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 / 38
CRAP
0.00% covered (danger)
0.00%
0 / 2413
ExaminationReportService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 38
163620.00
0.00% covered (danger)
0.00%
0 / 2413
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 3
 getDigitalValuationReports
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 54
 getBookletCountDigitalValuationReport
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 27
 getBookletCountWithStaffDigitalValuationReport
0.00% covered (danger)
0.00%
0 / 1
342.00
0.00% covered (danger)
0.00%
0 / 59
 getMarkNotSubmittedStaffListDigitalValuationReport
0.00% covered (danger)
0.00%
0 / 1
380.00
0.00% covered (danger)
0.00%
0 / 64
 getRegisteredStudentsDigitalValuationDetails
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 78
 getStudentQuestionWiseMarkReport
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 61
 getStudentQuestionWiseMarkDetails
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 63
 getStudentIdByRegisterNo
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 18
 getStudentSubjectDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 59
 getGoverningCouncilReport
0.00% covered (danger)
0.00%
0 / 1
306.00
0.00% covered (danger)
0.00%
0 / 102
 getAssignedStudentsCount
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 44
 getAllRegistredStudentSemesterDetails
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 78
 getMarkCardIssueRegisterReport
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 73
 getAssignedSubjectStudentsDetails
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 49
 getAllExamRegisteredStudentDetails
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 59
 getRegisteredStudentCountReport
0.00% covered (danger)
0.00%
0 / 1
506.00
0.00% covered (danger)
0.00%
0 / 91
 getEvaluationReport
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 64
 getEndSemesterReport
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 79
 getAllRegistredStudentOverAllDetails
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 112
 getExamCourseWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 60
 getCourseWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
506.00
0.00% covered (danger)
0.00%
0 / 64
 getExamRegisteredStudentReport
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 40
 getExamTallyReport
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 84
 getStudentExamFeeDetails
0.00% covered (danger)
0.00%
0 / 1
182.00
0.00% covered (danger)
0.00%
0 / 69
 getRegularExamSubjectWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 50
 getSubjectWiseResultAnalysisConsolidated
0.00% covered (danger)
0.00%
0 / 1
182.00
0.00% covered (danger)
0.00%
0 / 45
 getRegularExamCourseWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 52
 getSemWiseConsolidatedCourseDetails
0.00% covered (danger)
0.00%
0 / 1
210.00
0.00% covered (danger)
0.00%
0 / 48
 getConsolidatedSubjectMarkDetails
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 65
 getExamValuationProgressReport
0.00% covered (danger)
0.00%
0 / 1
3192.00
0.00% covered (danger)
0.00%
0 / 169
 getExamDateWiseReport
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 75
 getExamDetailedValuationReport
0.00% covered (danger)
0.00%
0 / 1
506.00
0.00% covered (danger)
0.00%
0 / 101
 getStaffRemunerationReport
0.00% covered (danger)
0.00%
0 / 1
240.00
0.00% covered (danger)
0.00%
0 / 79
 getBatchStudentsForInvigilatorsDiary
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 66
 filterStudentsByRegisterRange
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 18
 submitStudentRoomDetails
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 38
 getAllHallAssignedRegisteredStudentDetails
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 53
<?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\base\util\TwigRenderer;
use com\linways\core\ams\professional\util\PdfUtil;
use com\linways\ec\core\mapper\RegularExamReportServiceMapper;
use com\linways\ec\core\service\CommonExamService;
use com\linways\ec\core\request\SearchExamRegistrationRequest;
use com\linways\ec\core\service\ExamRegistrationService;
use com\linways\ec\core\service\RegularExamReportService;
use com\linways\core\ams\professional\service\StaffService;
use com\linways\core\ams\professional\service\CourseTypeService;
use com\linways\core\ams\professional\service\StudentService;
use com\linways\ec\core\service\ExamRegistrationSubjectService;
use com\linways\ec\core\service\StudentExamRegistrationService;
use com\linways\ec\core\service\ExamValuationService;
use com\linways\ec\core\service\FinalConsolidatedReportService;
use com\linways\core\ams\professional\service\AmsCustomFieldsService;
use com\linways\core\ams\professional\constant\AmsCustomFieldsEntities;
use com\linways\core\ams\professional\request\examcontroller\ConsolidatedMarkReportRequest;
use com\linways\core\ams\professional\request\api\GetAllFacultiesRequest;
use com\linways\core\ams\professional\request\api\GetAllDepartmentsRequest;
use com\linways\core\ams\professional\service\DepartmentService;
use com\linways\core\ams\professional\request\academic\SearchAcademicTermRequest;
use com\linways\core\ams\professional\service\academic\AcademicTermService;
use com\linways\core\ams\professional\util\CommonUtil;
use com\linways\ec\core\service\StudentMarkListService;
use com\linways\ec\core\constant\StatusConstants;
use com\linways\ec\core\logging\Events;
use com\linways\ec\core\logging\entities\Staff;
use com\linways\core\ams\professional\logging\AMSLogger;
class ExaminationReportService extends BaseService
{
    use MakeSingletonTrait;
    private function __construct() {
        $this->mapper = RegularExamReportServiceMapper::getInstance()->getMapper();
        $this->logger = AMSLogger::getLogger('exam-controller-log');
    }
   
  
    /**
     * Get Digital Valuation Reports
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getDigitalValuationReports($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->courseTypeId = $searchRequest->courseTypeId;
        $request->reportType = $searchRequest->reportType;
        $resultData = new \stdClass;
        // Different Digital Valuation Reports
        switch ($request->reportType) {
            case 'BOOKLET_COUNT':
                $resultData =  $this->getBookletCountDigitalValuationReport($request);
                $templateName = "digital_valuation_report_booklet_count";
                break;
            case 'BOOKLET_COUNT_WITH_STAFF':
                $resultData =  $this->getBookletCountWithStaffDigitalValuationReport($request);
                $templateName = "digital_valuation_report_booklet_count_with_staff";
                break;
            case 'MARK_NOT_SUBMITTED_STAFF_LIST':
                $resultData =  $this->getMarkNotSubmittedStaffListDigitalValuationReport($request);
                $templateName = "digital_valuation_report_mark_not_submitted_staff_list";
                break;
            default: 
                break;
        }
        $requestForExamRegistration = new SearchExamRegistrationRequest;
        $requestForExamRegistration->id = $request->examRegistrationId;
        $examRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration));
        $collegeData = CommonExamService::getInstance()->getCollegeDetails();
        if(empty($resultData)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No details found.");
        }
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/digitalValuationReports/$templateName.twig"), [ 'subjects'=>$resultData,'collegeData'=>$collegeData,'examRegistration'=>$examRegistration]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Digital 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);
        return  $programResult;
    }
     /**
     * get Booklet Count Digital Valuation Report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getBookletCountDigitalValuationReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->courseTypeId = $searchRequest->courseTypeId;
        $bookletCountDetails = [];
        $studentDetails = $this->getRegisteredStudentsDigitalValuationDetails($request);
        foreach($studentDetails as $student){
            $student->valuationDetails = json_decode($student->valuationDetails);
            $bookletCountDetails[$student->subjectCode]->subjectCode = $student->subjectCode;
            $bookletCountDetails[$student->subjectCode]->subjectName = $student->subjectName;
            $bookletCountDetails[$student->subjectCode]->bookletCount++;
            if(!empty($student->valuationDetails->assignedValuationStaffs)){
                $student->assignedValuationStaffs = (array)$student->valuationDetails->assignedValuationStaffs;
                foreach($student->assignedValuationStaffs as $valuation){
                    if(!empty($valuation->addiitonalExamniners)){
                        $bookletCountDetails[$student->subjectCode]->firstValuationAssignedPaper = $valuation->count == '1' ? (int)$bookletCountDetails[$student->subjectCode]->firstValuationAssignedPaper + 1 : (int)$bookletCountDetails[$student->subjectCode]->firstValuationAssignedPaper ;
                        $bookletCountDetails[$student->subjectCode]->secondValuationAssignedPaper = $valuation->count == '2' ? (int)$bookletCountDetails[$student->subjectCode]->secondValuationAssignedPaper + 1 : (int)$bookletCountDetails[$student->subjectCode]->secondValuationAssignedPaper ;
                        $bookletCountDetails[$student->subjectCode]->thirdValuationAssignedPaper = $valuation->count == '3' ? (int)$bookletCountDetails[$student->subjectCode]->thirdValuationAssignedPaper + 1 : (int)$bookletCountDetails[$student->subjectCode]->thirdValuationAssignedPaper ;
                    }
                }
                $bookletCountDetails[$student->subjectCode]->firstValuationReturnedPaper = $student->mark1Confirm ? (int)$bookletCountDetails[$student->subjectCode]->firstValuationReturnedPaper + 1 : (int)$bookletCountDetails[$student->subjectCode]->firstValuationReturnedPaper ;
                $bookletCountDetails[$student->subjectCode]->secondValuationReturnedPaper = $student->mark2Confirm  ? (int)$bookletCountDetails[$student->subjectCode]->secondValuationReturnedPaper + 1 : (int)$bookletCountDetails[$student->subjectCode]->secondValuationReturnedPaper ;
                $bookletCountDetails[$student->subjectCode]->thirdValuationReturnedPaper = $student->mark3Confirm  ? (int)$bookletCountDetails[$student->subjectCode]->thirdValuationReturnedPaper + 1 : (int)$bookletCountDetails[$student->subjectCode]->thirdValuationReturnedPaper ;
            }
        }
        return $bookletCountDetails;
    }
    /**
     * get Booklet Count with staff Digital Valuation Report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getBookletCountWithStaffDigitalValuationReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->courseTypeId = $searchRequest->courseTypeId;
        $bookletCountStaffDetails = [];
        $studentDetails = $this->getRegisteredStudentsDigitalValuationDetails($request);
        $getAllFacultiesRequest = new GetAllFacultiesRequest;
        $staffs = StaffService::getInstance()->getAllFacultiesForApi($getAllFacultiesRequest);
        $allStaffs = [];
        foreach($staffs as $staff){
            $allStaffs[$staff->id] = $staff;
        }
        foreach($studentDetails as $student){
            $student->valuationDetails = json_decode($student->valuationDetails);
            if(!empty($student->valuationDetails->assignedValuationStaffs)){
                $bookletCountStaffDetails[$student->subjectCode]->subjectCode = $student->subjectCode;
                $bookletCountStaffDetails[$student->subjectCode]->subjectName = $student->subjectName;
                $student->assignedValuationStaffs = (array)$student->valuationDetails->assignedValuationStaffs;
                foreach($student->assignedValuationStaffs as $valuation){
                    if(!empty($valuation->addiitonalExamniners)){
                        $staffId = '';
                        $staffId = reset($valuation->addiitonalExamniners);
                        if($valuation->count == '1'){
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'1']->staffName = $allStaffs[$staffId]->name;
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'1']->valuationCount = $valuation->count;
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'1']->bookletCount++;
                        }
                        elseif($valuation->count == '2'){
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'2']->staffName = $allStaffs[$staffId]->name;
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'2']->valuationCount = $valuation->count;
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'2']->bookletCount++;
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'2']->registerNo[] = $student->registerNo;
                        }
                        elseif($valuation->count == '3'){
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'3']->staffName = $allStaffs[$staffId]->name;
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'3']->valuationCount = $valuation->count;
                            $bookletCountStaffDetails[$student->subjectCode]->staffs[$staffId.'3']->bookletCount++;
                        }
                    }
                }
                if($student->mark1Confirm && $student->mark1SubmittedStaff){
                    if($bookletCountStaffDetails[$student->subjectCode]->staffs[$student->mark1SubmittedStaff.'1']){
                        $bookletCountStaffDetails[$student->subjectCode]->staffs[$student->mark1SubmittedStaff.'1']->bookletReturnedCount++;
                    }
                }
                if($student->mark2Confirm && $student->mark2SubmittedStaff){
                    if($bookletCountStaffDetails[$student->subjectCode]->staffs[$student->mark2SubmittedStaff.'2']){
                        $bookletCountStaffDetails[$student->subjectCode]->staffs[$student->mark2SubmittedStaff.'2']->bookletReturnedCount++;
                    }
                }
                if($student->mark3Confirm && $student->mark3SubmittedStaff){
                    if($bookletCountStaffDetails[$student->subjectCode]->staffs[$student->mark3SubmittedStaff.'3']){
                        $bookletCountStaffDetails[$student->subjectCode]->staffs[$student->mark3SubmittedStaff.'3']->bookletReturnedCount++;
                    }
                }
            }
        }
        return $bookletCountStaffDetails;
    }
    
    /**
     * get mark not submitted staff list for digital valuation
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getMarkNotSubmittedStaffListDigitalValuationReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->courseTypeId = $searchRequest->courseTypeId;
        $notSubmittedStaffDetails = [];
        $studentDetails = $this->getRegisteredStudentsDigitalValuationDetails($request);
        foreach($studentDetails as $student){
            $student->valuationDetails = json_decode($student->valuationDetails);
            if(!empty($student->valuationDetails->assignedValuationStaffs)){
                $notSubmittedStaffDetails[$student->subjectCode]->subjectCode = $student->subjectCode;
                $notSubmittedStaffDetails[$student->subjectCode]->subjectName = $student->subjectName;
                $notSubmittedStaffDetails[$student->subjectCode]->bookletCount++;
                $student->assignedValuationStaffs = (array)$student->valuationDetails->assignedValuationStaffs;
                foreach($student->assignedValuationStaffs as $valuation){
                    if(!empty($valuation->addiitonalExamniners)){
                        $staffId = reset($valuation->addiitonalExamniners);
                        if($valuation->count == '1'){
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['1']->valuationCount = $valuation->count;
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['1']->assignedStudentCount++; 
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['1']->assignedStaffs[$staffId]->studentcount++;
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['1']->assignedStaffs[$staffId]->id = $staffId;
                        }
                        elseif($valuation->count == '2'){
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['2']->valuationCount = $valuation->count;
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['2']->assignedStudentCount++; 
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['2']->assignedStaffs[$staffId]->studentcount++;
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['2']->assignedStaffs[$staffId]->id = $staffId;
                        }
                        elseif($valuation->count == '3'){
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['3']->valuationCount = $valuation->count;
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['3']->assignedStudentCount++; 
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['3']->assignedStaffs[$staffId]->studentcount++;
                            $notSubmittedStaffDetails[$student->subjectCode]->valuations['3']->assignedStaffs[$staffId]->id = $staffId;
                        }
                    }
                }
                if($student->mark1Confirm && $student->mark1SubmittedStaff){
                    $notSubmittedStaffDetails[$student->subjectCode]->valuations['1']->assignedStaffs[$student->mark1SubmittedStaff]->submittedStudentcount++;
                }
                if($student->mark2Confirm && $student->mark2SubmittedStaff){
                    $notSubmittedStaffDetails[$student->subjectCode]->valuations['2']->assignedStaffs[$student->mark2SubmittedStaff]->submittedStudentcount++;
                }
                if($student->mark3Confirm && $student->mark3SubmittedStaff){
                    $notSubmittedStaffDetails[$student->subjectCode]->valuations['3']->assignedStaffs[$student->mark3SubmittedStaff]->submittedStudentcount++;
                }
            }
        }
        foreach($notSubmittedStaffDetails as $subject){
            foreach($subject->valuations as $valuation){
                foreach($valuation->assignedStaffs as $staff){
                    if((int)$staff->submittedStudentcount < (int)$staff->studentcount){
                        $valuation->notSubmittedStaffIds[] = $staff->id;
                    }
                }
                if(!empty($valuation->notSubmittedStaffIds)){
                    $staffDetails = [];
                    $staffDetails = StaffService::getInstance()->getStaffByIds($valuation->notSubmittedStaffIds);
                    $valuation->notSubmittedStaffNameArray = array_column($staffDetails,'name');
                    $valuation->notSubmittedStaffNames = implode(',',$valuation->notSubmittedStaffNameArray);
                }
            }
        }
        return $notSubmittedStaffDetails;
    }
    /**
     * Get Registered Student Digital Valuation Details
     * @param $request
     * @return $students
     */
    public function getRegisteredStudentsDigitalValuationDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            $joinQuery = "";
            $whereQuery = "";
            $orderBy = "";
            $groupBy = " GROUP BY sa.studentID, aa.id";
            if(!empty($request->examRegistrationId)) {
                $whereQuery .= " AND eerb.ec_exam_registration_id = '$request->examRegistrationId'";
            }
            $query = "SELECT DISTINCT
                esar.id,
                sa.studentID as studentId,
                aa.id AS assessmentId,
                esar.falseNo AS falseNumber,
                IF (esar.valuation_details IS NULL, JSON_OBJECT(), esar.valuation_details) AS valuationDetails,
                eers.valuation_details as subjectValuationDetails,
                sa.studentName,
                spa.properties->>'$.registerNumber' AS registerNo,
                spa.properties->>'$.rollNumber' AS rollNo,
                sub.code AS subjectCode,
                sub.name AS subjectName,
                caps.id AS academicPaperSubjectId,
                IF (oec1Started.id IS NULL, 0, 1) AS mark1Started,
                IF (oec2Started.id IS NULL, 0, 1) AS mark2Started,
                oec1.is_confirmed as mark1Confirm,
                oec1.updated_by as mark1SubmittedStaff,
                oecRev.is_confirmed as mark1ReviewConfirm,
                oecRev.updated_by as mark1ReviewSubmittedStaff,
                oec2.is_confirmed as mark2Confirm,
                oec2.updated_by as mark2SubmittedStaff,
                oec3.is_confirmed as mark3Confirm,
                oec3.updated_by as mark3SubmittedStaff
            FROM
                ec_student_assessment_registration esar
            INNER JOIN studentaccount sa ON
                sa.studentID = esar.student_id
            INNER JOIN am_assessment aa ON
                aa.id = esar.am_assessment_id
            INNER JOIN oe_exams oe ON
                oe.assessment_id = aa.id AND oe.is_deleted = 0
            INNER JOIN ec_exam_registration_subject eers ON
                eers.am_assessment_id = aa.id
            INNER JOIN ec_exam_registration_batch eerb ON
                eerb.id = eers.ec_exam_registration_batch_id
            INNER JOIN ec_exam_registration eer ON
                eer.id = eerb.ec_exam_registration_id AND
                eer.trashed IS NULL
            INNER JOIN `groups` g ON 
                g.id = eerb.groups_id
            INNER JOIN program p ON 
                p.id = g.properties->>'$.programId'
            INNER JOIN student_program_account spa ON 
                spa.student_id  = esar.student_id  AND
                spa.current_program_id = p.id
            INNER JOIN cm_academic_paper_subjects caps ON
                caps.id = eers.cm_academic_paper_subjects_id
            INNER JOIN v4_ams_subject sub ON
                sub.id = caps.ams_subject_id
            LEFT JOIN oe_exam_marks_confirm oec1 ON oec1.oe_exams_id = oe.id AND oec1.oe_users_id = sa.studentID AND oec1.valuation_count = 1 AND (oec1.revaluation_id IS NULL OR oec1.revaluation_id = '') AND oec1.is_confirmed = '1' AND oec1.review_id IS NULL
            LEFT JOIN oe_exam_marks_confirm oecRev ON oecRev.oe_exams_id = oe.id AND oecRev.oe_users_id = sa.studentID AND oecRev.valuation_count = 1 AND (oecRev.revaluation_id IS NULL OR oecRev.revaluation_id = '') AND oecRev.is_confirmed = '1' AND oecRev.review_id IS NOT NULL
            LEFT JOIN oe_exam_marks_confirm oec2 ON oec2.oe_exams_id = oe.id AND oec2.oe_users_id = sa.studentID AND oec2.valuation_count = 2 AND (oec2.revaluation_id IS NULL OR oec2.revaluation_id = '') AND oec2.is_confirmed = '1'
            LEFT JOIN oe_exam_marks_confirm oec1Started ON oec1Started.oe_exams_id = oe.id AND oec1Started.oe_users_id = sa.studentID AND oec1Started.valuation_count = 1 AND (oec1Started.revaluation_id IS NULL OR oec1Started.revaluation_id = '') 
            LEFT JOIN oe_exam_marks_confirm oec2Started ON oec2Started.oe_exams_id = oe.id AND oec2Started.oe_users_id = sa.studentID AND oec2Started.valuation_count = 2 AND (oec2Started.revaluation_id IS NULL OR oec2.revaluation_id = '')
            LEFT JOIN oe_exam_marks_confirm oec3 ON oec3.oe_exams_id = oe.id AND oec3.oe_users_id = sa.studentID AND oec3.valuation_count = 3 AND (oec3.revaluation_id IS NULL OR oec3.revaluation_id = '') AND oec3.is_confirmed = '1'
            WHERE
                esar.trashed IS NULL AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED') AND eer.type = esar.ec_exam_registration_type AND esar.valuation_details IS NOT NULL
                AND (CAST(esar.properties ->> '$.syllabusSubType' AS CHAR) != 'MOOC' OR esar.properties ->> '$.syllabusSubType' IS NULL) ";
        try {
            $registeredStudent = $this->executeQueryForList($query.$whereQuery.$groupBy.$orderBy);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        return $registeredStudent;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Get Student Question wise mark report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getStudentQuestionWiseMarkReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->registerNo = $searchRequest->registerNo;
        $request->assessmentId = $searchRequest->assessmentId;
        $request->studentId = $searchRequest->studentId;
        $additionalInfo = new \stdClass;
        $resultData = new \stdClass;
        $templateName = "student-question-wise-mark-report-template-1";
        $questions = [];
        if(empty($request->registerNo) && !$request->studentId){
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Invalid Request");
        }
        $request->studentId = $request->studentId ? $request->studentId : $this->getStudentIdByRegisterNo($request->registerNo);
        if(empty($request->studentId) ||  empty($request->assessmentId)){
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Invalid Request");
        }
        $resultData =  $this->getStudentQuestionWiseMarkDetails($request);
        foreach($resultData as $question){
            if(!$question->mainQuestionId){
                $questions[$question->questionId] = $question;
                $questions[$question->questionId]->subQuestions =[];
            }
        }
        foreach($resultData as $question){
            if($question->mainQuestionId){
                $questions[$question->mainQuestionId]->subQuestions[$question->questionId] = $question;
            }
        }
        $questions = array_values($questions);
        array_walk($questions,function($question){
            $question->subQuestions = array_values($question->subQuestions);
        });
        $additionalInfo = $this->getStudentSubjectDetails($request);
        $additionalInfo->valCounts = [1,2,3];
        if(empty($resultData)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No details found.");
        }
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/studentQuestionWiseMarkReport/$templateName.twig"), [ 'questionAnswers'=>$questions,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Student Question Wise Mark 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;
    }
    /**
     * Get Registered Student Question Wise mark details
     * @param $request
     * @return $students
     */
    public function getStudentQuestionWiseMarkDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            
            $query = "SELECT DISTINCT
                            oeq.id AS questionId,
                            oeq.mark AS maxQuestionMark,
                            oeq.properties ->> '$.mainQuestionId' AS mainQuestionId,
                            oeua.oe_exam_answers_id AS answerId,
                            oeua.answer,
                            oeua.answers,
                            IF (
                                oeq.properties ->> '$.type' = 'MCQ',
                                oea.point,
                                oeum.mark
                                ) AS mark,
                            oeum.valuation_marks AS multipleValuationMarks,
                            oeq.properties ->> '$.type' AS questionType,
                            oeq.properties ->> '$.section' AS questionSection,
                            oeq.properties ->> '$.orderNo' AS questionOrderNo,
                            oes.properties ->> '$.orderNo' AS orderNo,
                            oes.name AS section_name
                        FROM
                            oe_exams oe
                        INNER JOIN
                            oe_exam_questions oeq ON
                            oeq.oe_exams_id = oe.id
                        LEFT JOIN
                            oe_exam_user_answers oeua ON
                                oeq.oe_exams_id = oeua.oe_exams_id
                                AND oeq.id = oeua.oe_exam_questions_id
                                AND oeua.user_type = 'STUDENT'
                                AND oeua.user_id = '$request->studentId
                        LEFT JOIN
                            oe_exam_answers oea ON
                                oea.oe_exams_id = oeua.oe_exams_id
                                AND oea.oe_exam_questions_id = oeua.oe_exam_questions_id
                                AND oea.id = oeua.oe_exam_answers_id 
                        LEFT JOIN
                            oe_exam_user_mark oeum ON
                                oeum.oe_exams_id = oeq.oe_exams_id
                                AND oeum.oe_exam_questions_id = oeq.id
                                AND oeum.user_type = 'STUDENT'
                                AND oeum.user_id = '$request->studentId
                        LEFT JOIN
                            oe_exam_sections oes ON
                            oes.oe_exams_id = oe.id
                                AND JSON_EXTRACT(oeq.properties,
                                '$.section') = oes.id
                        WHERE
                            oe.identifying_context->>'$.assessmentId' = '$request->assessmentId'
                        ORDER BY
                            CAST(oes.properties ->> '$.orderNo' AS UNSIGNED) ASC,
                            CAST(oeq.properties ->> '$.orderNo' AS UNSIGNED) ASC, 
                            oeq.question ASC";
     
            $studentQuestionWiseMark = $this->executeQueryForList($query);
        } 
        catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        foreach($studentQuestionWiseMark as $question){
            $question->multipleValuationMarks = (array)json_decode($question->multipleValuationMarks);
        } 
        return $studentQuestionWiseMark;
        
    }
     /**
     * Get StudentId by student register No
     * @param $regNo
     * @return $studentId
     */
    public function getStudentIdByRegisterNo($regNo){
        try{
            $query = "SELECT
                            spa.student_id as studentId
                        FROM
                            student_program_account spa
                       
                        WHERE
                            spa.properties->>'$.registerNumber' = '$regNo'";
        try {
            $studentId = $this->executeQueryForObject($query)->studentId;
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        return $studentId;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Get student subject Valuation Mark Details
     * @param $request
     * @return $students
     */
    public function getStudentSubjectDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            $query = "SELECT DISTINCT
                sa.studentID as studentId,
                aa.id AS assessmentId,
                sa.studentName,
                spa.properties->>'$.registerNumber' AS registerNo,
                spa.properties->>'$.rollNumber' AS rollNo,
                caps.properties->>'$.externalMaxMark' AS externalMaxMark,
                sub.code AS subjectCode,
                sub.name AS subjectName,
                caps.id AS academicPaperSubjectId,
                oec1.is_confirmed as mark1Confirm,
                oec1.exam_mark as mark1,
                oec2.is_confirmed as mark2Confirm,
                oec2.exam_mark as mark2,
                oec3.is_confirmed as mark3Confirm,
                oec3.exam_mark as mark3,
                oecRew.is_confirmed as markReviewConfirm,
                oecRew.exam_mark as markReview
            FROM
                ec_student_assessment_registration esar
            INNER JOIN studentaccount sa ON
                sa.studentID = esar.student_id
            INNER JOIN am_assessment aa ON
                aa.id = esar.am_assessment_id
            INNER JOIN oe_exams oe ON
                oe.assessment_id = aa.id AND oe.is_deleted = 0
            INNER JOIN ec_exam_registration_subject eers ON
                eers.am_assessment_id = aa.id
            INNER JOIN ec_exam_registration_batch eerb ON
                eerb.id = eers.ec_exam_registration_batch_id
            INNER JOIN ec_exam_registration eer ON
                eer.id = eerb.ec_exam_registration_id AND
                eer.trashed IS NULL
            INNER JOIN `groups` g ON 
                g.id = eerb.groups_id
            INNER JOIN program p ON 
                p.id = g.properties->>'$.programId'
            INNER JOIN student_program_account spa ON 
                spa.student_id  = esar.student_id  AND
                spa.current_program_id = p.id 
            INNER JOIN cm_academic_paper_subjects caps ON
                caps.id = eers.cm_academic_paper_subjects_id
            INNER JOIN v4_ams_subject sub ON
                sub.id = caps.ams_subject_id
            LEFT JOIN oe_exam_marks_confirm oec1 ON oec1.oe_exams_id = oe.id AND oec1.oe_users_id = sa.studentID AND oec1.valuation_count = 1 AND (oec1.revaluation_id IS NULL OR oec1.revaluation_id = '') AND oec1.is_confirmed = '1' AND oec1.review_id IS NULL
            LEFT JOIN oe_exam_marks_confirm oecRew ON oecRew.oe_exams_id = oe.id AND oecRew.oe_users_id = sa.studentID AND oecRew.valuation_count = 1 AND (oecRew.revaluation_id IS NULL OR oecRew.revaluation_id = '') AND oecRew.is_confirmed = '1' AND oecRew.review_id IS NOT NULL
            LEFT JOIN oe_exam_marks_confirm oec2 ON oec2.oe_exams_id = oe.id AND oec2.oe_users_id = sa.studentID AND oec2.valuation_count = 2 AND (oec2.revaluation_id IS NULL OR oec2.revaluation_id = '') AND oec2.is_confirmed = '1'
            LEFT JOIN oe_exam_marks_confirm oec3 ON oec3.oe_exams_id = oe.id AND oec3.oe_users_id = sa.studentID AND oec3.valuation_count = 3 AND (oec3.revaluation_id IS NULL OR oec3.revaluation_id = '') AND oec3.is_confirmed = '1'
            WHERE
                esar.trashed IS NULL AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED') AND esar.student_id = '$request->studentId' AND esar.am_assessment_id = '$request->assessmentId'";
        
            $studentSubjectDetails = $this->executeQueryForObject($query);
            return $studentSubjectDetails;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Get Governing Council Report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getGoverningCouncilReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->courseTypeId = $searchRequest->courseTypeId;
        $request->admissionYear = $searchRequest->admissionYear;
        $request->academicTermId = $searchRequest->academicTermId;
        $additionalInfo = new \stdClass;
        $resultData = new \stdClass;
        $genders = [
            "MALE"=>"MALE",
            "FEMALE"=>"FEMALE"
        ];
        $templateName = "governing-council-report-template-1";
        $batchGroups = FinalConsolidatedReportService::getInstance()->getBatchesByAcademicTerm($request);
        if(empty($batchGroups)){
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"No batches found");
        }
        foreach($batchGroups as $batchKey => $batch){
            $academicStartYear = "";
            $academicEndYear = "";
            // $academicTermRequest = new \stdClass;
            // $academicTermRequest->groupId = $batch->id;
            // $academicTermRequest->academicTermId = $request->academicTermId;
            // $allSemesterDetails = CommonExamService::getInstance()->getAllAcademicTermsDetailsByBatch($academicTermRequest);
            $studentMarkDetailsRequest = new \stdClass;
            $studentMarkDetailsRequest->groupId = $batch->id;
            $studentMarkDetailsRequest->academicTermId = $searchRequest->academicTermId;
            $studentMarkDetailsRequest->considerSupplementary = false;
            $students = $this->getAllRegistredStudentSemesterDetails($studentMarkDetailsRequest);
            $allSemesterDetails = max(array_map(function($o){return $o->semesters;},$students));
            if($allSemesterDetails ){
                $firstSemExamDetails = reset(array_filter(reset($allSemesterDetails)->semesterMarkHistory,function($value){
                    return $value->historyType == 'REGULAR';
                }));
                $lastSemExamDetails = reset(array_filter(end($allSemesterDetails)->semesterMarkHistory,function($value){
                    return $value->historyType == 'REGULAR';
                }));
                if(!$firstSemExamYear){
                    $firstSemExamYear = $firstSemExamDetails->examYear;
                }
                else{
                    $firstSemExamYear = (int)$firstSemExamYear > (int)$firstSemExamDetails->examYear ?  $firstSemExamDetails->examYear : $firstSemExamYear;
                }
                if(!$lastSemExamYear){
                    $lastSemExamYear = $lastSemExamDetails->examYear;
                }
                else{
                    $lastSemExamYear = (int)$lastSemExamYear < (int)$lastSemExamDetails->examYear ?  $lastSemExamDetails->examYear : $lastSemExamYear; 
                }
            }
            $batch->noOfSeats = 0;
            if($students){
                foreach ( $allSemesterDetails as $academicTerm ) {
                    foreach ($genders as $gender) {
                        $studentCountRequest = new \stdClass;
                        $studentCountRequest->groupId = $batch->id;
                        $studentCountRequest->academicTermId = $academicTerm->id;
                        $studentCountRequest->gender = $gender;
                        $batch->semesters[$academicTerm->id]->name = $academicTerm->name;
                        $batch->semesters[$academicTerm->id]->gender[$gender]->studentCount = $this->getAssignedStudentsCount($studentCountRequest);
                        // $studentCountRequest->isRegisteredStudent = true;
                        // $batch->semesters[$academicTerm->id]->gender[$gender]->noOfRegisteredStudents = $this->getAssignedStudentsCount($studentCountRequest);
                    }
                }
                foreach($students as $student){
                    foreach($student->semesters as $academicTerm){
                        $batch->semesters[$academicTerm->id]->gender[$student->gender]->totalRegStudents++;
                        $batch->semesters[$academicTerm->id]->totalRegStudents++;
                        if($academicTerm->semesterFailedStatus == 'PASSED'){
                            $batch->semesters[$academicTerm->id]->gender[$student->gender]->totalPassStudents++;
                            $batch->semesters[$academicTerm->id]->totalPassStudents++;
                        }
                        $batch->semesters[$academicTerm->id]->totalPercentage =  round(($batch->semesters[$academicTerm->id]->totalPassStudents / $batch->semesters[$academicTerm->id]->totalRegStudents) * 100, 2);
                    }
                }
            }
            ksort($batch->semesters);
            $batch->semesterCount = count($batch->semesters);
            if(!$batch->semesterCount){
                unset($batchGroups[$batchKey]);
            }
            
        }
        $additionalInfo->collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $additionalInfo->batchStartYear = $searchRequest->admissionYear;
        $additionalInfo->academicYears = $firstSemExamYear ? $firstSemExamYear : '';
        $additionalInfo->academicYears .= $lastSemExamYear? ' - '.$lastSemExamYear : '' ;
        $additionalInfo->courseType = CourseTypeService::getInstance()->getCourseTypesById ($searchRequest->courseTypeId)->typeName;
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/governingCouncilReport/$templateName.twig"), [ 'batches'=>$batchGroups,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Governing Council 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;
    }
     /**
     * get count of assigned students by batch
     * @param $searchRequest 
     * @return $assignedStudentsCount 
     * @author Krishnajith
     */
    public function getAssignedStudentsCount($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $whereQuery = "";
            if(!empty($searchRequest->groupId)) {
                $groupIdString = is_array($searchRequest->groupId) ? "'" . implode("','",$searchRequest->groupId) . "'" : "'".$searchRequest->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if(!empty($searchRequest->gender)) {
                $whereQuery .= " AND s.studentGender = '$searchRequest->gender'";
            }
            if(!empty($searchRequest->academicTermId)) {
                $whereQuery .= " AND act.id = '$searchRequest->academicTermId'";
            }
           
            $query = "SELECT COUNT(DISTINCT  spa.student_id) as studentCount
                        FROM studentaccount s 
                        INNER JOIN student_program_account spa
                            ON spa.student_id = s.studentID 
                        INNER JOIN student_program_batch_log spbl 
                            ON spbl.program_student_id = spa.id AND 
                            spbl.properties->>'$.academicStatus' IN ('ACTIVE','COMPLETED')
                        INNER JOIN `program` p 
                            ON p.id = spbl.program_id
                        INNER JOIN `groups` g 
                            ON g.id = spbl.batch_group_id
                        INNER JOIN groups_relations gr ON 
                            gr.parent_groups_id = g.id
                        INNER JOIN `groups` sg ON 
                            sg.id = gr.child_groups_id AND sg.type = 'SUBJECT'
                        INNER JOIN group_members sgm ON
                            sgm.groups_id = sg.id AND 
                            sgm.members->>'$.studentId' = spa.id AND
                            sgm.academic_status IN ('ACTIVE')
                        INNER JOIN cm_academic_paper_subjects aps ON 
                            aps.id = sg.paperSubjectId
                        INNER JOIN academic_term act ON
                            act.id = sg.academic_term_id AND act.id = spbl.term_id
                        WHERE 1=1 ";
            $assignedStudentsCount = $this->executeQueryForObject($query.$whereQuery);
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $assignedStudentsCount->studentCount;
    }
     /**
     * get All Registered Students Semester Details
     * @param $searchRequest 
     */
    public function getAllRegistredStudentSemesterDetails($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $orderBy = "ORDER BY act.properties ->> '$.orderNo' ASC";
            $whereQuery = "";
            
            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 )";
            }
            $query = "SELECT DISTINCT
                        sa.studentID AS id,
                        sa.studentID AS studentId,
                        sa.studentName AS name,
                        sa.studentGender AS gender,
                       
                        g.id AS groupId,
                        g.name AS groupName,
                        act.id AS academicTermId,
                        act.name AS academicTermName,
                        g.properties ->> '$.startYear' AS academicYear,
                        esmdsem.mark_history AS semesterMarkHistory,
                        esmdsem.failed_status AS semesterFailedStatus
                    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
                    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
                    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 program p ON
                        p.id = CAST(g.properties ->> '$.programId' AS CHAR)
                    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 
                    WHERE 1=1";
            $studentMarkDetails = $this->executeQueryForList($query.$whereQuery.$orderBy);
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        $studentSemesterDetails = [];
        foreach($studentMarkDetails as $student){
            $studentSemesterDetails[$student->id]->id = $student->id;
            $studentSemesterDetails[$student->id]->id = $student->id;
            $studentSemesterDetails[$student->id]->name = $student->name;
            $studentSemesterDetails[$student->id]->gender = $student->gender;
            $studentSemesterDetails[$student->id]->groupId = $student->groupId;
            $studentSemesterDetails[$student->id]->groupName = $student->groupName;
            $studentSemesterDetails[$student->id]->semesters[$student->academicTermId]->id = $student->academicTermId;
            $studentSemesterDetails[$student->id]->semesters[$student->academicTermId]->name = $student->academicTermName;
            $studentSemesterDetails[$student->id]->semesters[$student->academicTermId]->semesterMarkHistory = json_decode($student->semesterMarkHistory);
            if(!$searchRequest->considerSupplementary){
                $currentAcademicTerm = new \stdClass;
                $currentAcademicTerm = reset(array_filter($studentSemesterDetails[$student->id]->semesters[$student->academicTermId]->semesterMarkHistory ,function($value){
                    return $value->historyType == "REGULAR";
                }));
                $studentSemesterDetails[$student->id]->semesters[$student->academicTermId]->semesterFailedStatus = $currentAcademicTerm ? $currentAcademicTerm->failedStatus : '';
            }
            else{
                $studentSemesterDetails[$student->id]->semesters[$student->academicTermId]->semesterFailedStatus = $student->failedStatus;
            }
        };
        return $studentSemesterDetails;
    }
    /**
     * Get Mark Card issue register report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getMarkCardIssueRegisterReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->examType = $searchRequest->examType;
        $request->departmentId = $searchRequest->departmentId;
        $request->groupId = $searchRequest->groupId;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $additionalInfo = new \stdClass;
        $resultData = new \stdClass;
        $templateName = "consolidated-marks-card-issue-register-template";
        $batches = [];
        if($request->examType == 'REGULAR' ){
            $studentDetailsRequest = new \stdClass;
            $studentDetailsRequest->departmentId = $searchRequest->departmentId;
            $studentDetailsRequest->groupId = $searchRequest->groupId;
            $studentDetailsRequest->examRegistrationBatchId = $searchRequest->examRegistrationBatchId;
            $students = $this->getAssignedSubjectStudentsDetails($studentDetailsRequest);
            $additionalInfo->isSupplementary = false;
        }
        else if($request->examType == 'SUPPLEMENTARY' ){
            $studentDetailsRequest = new \stdClass;
            $studentDetailsRequest->examRegistrationId = $searchRequest->examRegistrationId;
            $studentDetailsRequest->examRegistrationBatchId = $searchRequest->examRegistrationBatchId;
            $students =  $this->getAllExamRegisteredStudentDetails($studentDetailsRequest);
            $additionalInfo->isSupplementary = true;
        }        
        if(empty($students)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No details found.");
        }
        foreach($students as $student){
            $student->studentImage  = StudentService::getInstance()->getStudentProfilePic($student->studentId)->docpath;
            $student->studentSignature  = StudentService::getInstance()->getStudentSignPic($student->studentId)->docpath;
            $batches[$student->groupId]->id = $student->groupId;
            $batches[$student->groupId]->name = $student->groupName;
            if($student->examRegistrationName){
                $batches[$student->groupId]->examRegistrationName = $student->examRegistrationName;
            }
            $batches[$student->groupId]->students[] = $student;
        }
        $additionalInfo->collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $semesters = CommonExamService::getInstance()->getAcademicTermDetailsUptoFinalTerm($request);
        foreach($semesters as $semester){
            $semesterNames = CommonExamService::getInstance()->getDifferentSemesterName($semester->name);
            $semester->semInRomanLetter = $semesterNames->romanLetter;
            $semester->semInFullName = $semesterNames->fullName;
            $semester->semInSemNumber = $semesterNames->semNumber;
            $semester->semPrefix = $semesterNames->prefix;
        }
        $additionalInfo->semesters = $semesters;
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/markCardIssueRegister/$templateName.twig"), [ 'batches'=>$batches,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Mark Card Issue Register</title><body>';
            $prtContent .= $responseHtml;
            $prtContent .= '</body></html>';
            $totalWidth = 297;
            $totalHeight = 210;
            $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;
    }
    /**
     * get Assigned Subject Students Details
     * @param $searchRequest 
     * @return $studentDetails 
     * @author Krishnajith
     */
    public function getAssignedSubjectStudentsDetails($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $orderBy = " ORDER BY spa.properties->>'$.registerNumber' ASC";
            $whereQuery = "";
            if(!empty($searchRequest->groupId)) {
                $groupIdString = is_array($searchRequest->groupId) ? "'" . implode("','",$searchRequest->groupId) . "'" : "'".$searchRequest->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if(!empty($searchRequest->programId)) {
                $programIdString = is_array($searchRequest->programId) ? "'" . implode("','",$searchRequest->programId) . "'" : "'".$searchRequest->programId."'";
                $whereQuery .= " AND p.id IN ( $programIdString )";
            }
            if(!empty($searchRequest->departmentId)) {
                $departmentIdString = is_array($searchRequest->departmentId) ? "'" . implode("','",$searchRequest->departmentId) . "'" : "'".$searchRequest->departmentId."'";
                $whereQuery .= " AND dpt.deptID IN ( $departmentIdString )";
            }
            $query = "SELECT DISTINCT
                            g.id AS groupId,
                            g.name AS groupName,
                            g.properties ->>'$.programId'  AS programId,
                            dpt.deptName AS departmentName,
                            dpt.deptID AS departmentId,
                            spa.student_id AS studentId,
                            spa.properties->>'$.rollNumber' AS studentRollNo,
                            IF (spa.properties->>'$.registerNumber',spa.properties->>'$.registerNumber',' ')AS studentRegisterNo,
                            s.studentName AS studentName
                        FROM 
                            studentaccount s 
                        INNER JOIN student_program_account spa
                            ON spa.student_id = s.studentID 
                        INNER JOIN student_program_batch_log spbl 
                            ON spbl.program_student_id = spa.id AND spbl.properties->>'$.academicStatus' IN ('ACTIVE','COMPLETED')
                        INNER JOIN `program` p 
                            ON p.id = spbl.program_id
                        INNER JOIN `groups` g 
                            ON g.id = spbl.batch_group_id
                        INNER JOIN department dpt ON
                            dpt.deptID = g.properties->>'$.departmentId'
                        INNER JOIN group_members gm ON
                            gm.groups_id = g.id AND 
                            gm.members->>'$.studentId' = spa.id
                        WHERE 1=1 ";
            $studentDetails = $this->executeQueryForList($query.$whereQuery.$orderBy);
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $studentDetails;
    }
     /**
     * get All Exam Registered Student Details 
     * @param $searchRequest 
     * @return $registeredStudentsDetails 
     * @author Krishnajith
     */
    public function getAllExamRegisteredStudentDetails($searchRequest){
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $whereQuery = null;
            $orderBy = " ORDER BY spa.properties->>'$.registerNumber' ASC ";
            $whereQuery = "";
            if(!empty($searchRequest->examRegistrationId)) {
                $examRegistrationIdString = is_array($searchRequest->examRegistrationId) ? "'" . implode("','",$searchRequest->examRegistrationId) . "'" : "'".$searchRequest->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            if(!empty($searchRequest->examRegistrationBatchId)) {
                $examRegistrationBatchIdString = is_array($searchRequest->examRegistrationBatchId) ? "'" . implode("','",$searchRequest->examRegistrationBatchId) . "'" : "'".$searchRequest->examRegistrationBatchId."'";
                $whereQuery .= " AND eerb.id IN ( $examRegistrationBatchIdString )";
            }
            $query = "SELECT
                        DISTINCT 
                        sa.studentID AS id,
                        sa.studentID AS studentId,
                        sa.studentName AS studentName,
                        spa.properties->>'$.rollNumber' AS rollNo,
                        spa.properties->>'$.registerNumber' AS studentRegisterNo,
                        g.id AS groupId,
                        g.name AS groupName,
                        eer.id AS examRegistrationId,
                        eer.name AS examRegistrationName,
                        dept.deptID,
                        dept.deptName,
                        dept.departmentDesc
                    FROM
                        `groups` g
                    INNER JOIN ec_exam_registration_batch eerb ON
                        eerb.groups_id = g.id
                    INNER JOIN ec_exam_registration eer ON
                        eer.id = eerb.ec_exam_registration_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 am_assessment aa ON
                        aa.id = eers.am_assessment_id
                    INNER JOIN program p ON
                        p.id = g.properties ->> '$.programId'
                    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 student_program_account spa ON 
                        spa.current_program_id = p.id AND 
                        spa.student_id = esar.student_id 
                    INNER JOIN studentaccount sa ON 
                        sa.studentID = spa.student_id
                    INNER JOIN department dept ON
                        dept.deptID = g.properties ->> '$.departmentId'                
                    WHERE 1=1 ";
            $registeredStudentsDetails = $this->executeQueryForList($query.$whereQuery.$orderBy);
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $registeredStudentsDetails;
    }
    /**
     * get Registered Student Count Report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getRegisteredStudentCountReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->examType = $searchRequest->examType;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->examDate = $searchRequest->examDate;
        $request->session = $searchRequest->session;
        $request->reportType = $searchRequest->reportType;
        $additionalInfo = new \stdClass;
        $resultData = new \stdClass;
        $templateName = "registered-student-count-report";
        $examSessions = [
            "FN" => "AM",
            "AN" => "PM"
        ];
        if($request->examRegistrationId){
            $subjects = ExamRegistrationSubjectService::getInstance()->getAllSubjectDetailsByRegistration($request->examRegistrationId);
        }
        if(empty($subjects)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No details found.");
        }
        foreach($subjects as $subjectKey => $subject){
            if($request->examDate){
                if ( date('Y-m-d', strtotime($request->examDate)) != date('Y-m-d', strtotime($subject->assessmentDate)) || empty($subject->assessmentDate) || $subject->assessmentDate == "0000-00-00"){
                    unset($subjects[$subjectKey]);
                    continue;
                }
            }
            if($request->session){
                $examTime = date('A', strtotime($subject->assessmentStartTime));
                if(($examSessions[$request->session] != $examTime) || empty($subject->assessmentStartTime) || $subject->assessmentStartTime == "00:00:00"){
                    unset($subjects[$subjectKey]);
                    continue;
                }
            }
            $studentCountRequest = new \stdClass;
            $studentCountRequest->examRegistrationId = $request->examRegistrationId;
            $studentCountRequest->assessmentId = explode(',',$subject->assessmentIds);
            $studentCountRequest->academicPaperSubjectId = $subject->academicPaperSubjectId;
            $subject->studentCount = StudentExamRegistrationService::getInstance()->getCountOfRegisteredStudents($studentCountRequest);
            $subject->assessmentDate = $subject->assessmentDate && $subject->assessmentDate != "0000-00-00" ? date("d-m-Y", strtotime($subject->assessmentDate)) : '';
            $subject->assessmentStartTime = $subject->assessmentDate && $subject->assessmentStartTime != "00:00:00" ? ($subject->assessmentStartTime ?  date("h:i A", strtotime($subject->assessmentStartTime)) : '') : '';
        }
        if($request->reportType == 'COURSE_WISE'){
            $distinctSubjects = [];
            foreach($subjects as $subject){
                if(isset($distinctSubjects[$subject->amsSubjectId])){
                    $distinctSubjects[$subject->amsSubjectId]->studentCount += $subject->studentCount;
                    $distinctSubjects[$subject->amsSubjectId]->groupNames[$subject->groupId] = $subject->groupName;
                } else {
                    $distinctSubjects[$subject->amsSubjectId] = $subject;
                    $distinctSubjects[$subject->amsSubjectId]->groupNames = [$subject->groupId => $subject->groupName];
                }
            }
            foreach($distinctSubjects as $subject){
                $subject->groupName = implode(", ", $subject->groupNames);
            }
            $subjects = array_values($distinctSubjects);
        }
        else{
            $subjects = array_values($subjects);
        }
        if(empty($subjects)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No details found.");
        }
        // $requestForExamRegistration = new SearchExamRegistrationRequest;
        // $requestForExamRegistration->id = $request->examRegistrationId;
        // $additionalInfo->examRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration));
        $additionalInfo->collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/registeredStudentCountReport/$templateName.twig"), [ 'subjects'=>$subjects,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Registered Student Count 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->subjects = $subjects;
        $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
        return  $programResult;
    }
     /**
     * get Evaluation Report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getEvaluationReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $templateName = "evaluation-report-template";
        $request = new \stdClass;
        $additionalInfo = new \stdClass;
        $additionalInfo->extValRequired = false;
        $request->courseTypeId = $searchRequest->courseTypeId;
        $request->examType = $searchRequest->examType;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->groupId = $searchRequest->groupId;
        $request->assessmentId = $searchRequest->assessmentId;
        $request->valuationCount = $searchRequest->valuationCount;
        $courseType = CourseTypeService::getInstance()->getCourseTypesById ($request->courseTypeId);
        $additionalInfo->courseTypeName = $courseType->typeName;
        
        if($courseType->extValRequired == '1'){
            $additionalInfo->extValRequired = true;
            $additionalInfo->valuationCounts = $request->valuationCount;
        }
        $subjectStudentsDetails = [];
        $students = ExamValuationService::getInstance()->getAllStudentExternalMarksByExamRegistrationSubject($request);
        if(empty($students)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No students found.");
        }
        foreach($students as $student){
            $subjectStudentsDetails[$student->subjectId]->id = $student->subjectId;
            $subjectStudentsDetails[$student->subjectId]->subjectCode = $student->subjectCode;
            $subjectStudentsDetails[$student->subjectId]->subjectName = $student->subjectName;
            $subjectStudentsDetails[$student->subjectId]->students[] = $student;
        }
        $batchRequest = new \stdClass;
        $batchRequest->groupsIds = $searchRequest->groupId;
        $batchDetails =  FinalConsolidatedReportService::getInstance()->getAllGroupDetailsByGroupIds($batchRequest);
        foreach($batchDetails as $batch){
            $batchNames[] =  $batch->groupName;
        }
        $additionalInfo->batchName = implode(" , ",$batchNames);
        
        $requestForExamRegistration = new SearchExamRegistrationRequest;
        $requestForExamRegistration->id = $request->examRegistrationId;
        $additionalInfo->examRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration));
        $additionalInfo->collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/evaluationReport/$templateName.twig"), [ 'subjects'=>$subjectStudentsDetails,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Evaluation 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;
    }
     /**
     * get End semester Report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getEndSemesterReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $templateName = "end-semester-report-template";
        $request = new \stdClass;
        $additionalInfo = new \stdClass;
        $request->courseTypeId = $searchRequest->courseTypeId;
        $request->examType = $searchRequest->examType;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->groupId = $searchRequest->groupId;
        $students = $this->getAllRegistredStudentOverAllDetails($request);
        $batchStudents = [];
        if(empty($students)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No students found.");
        }
        foreach( $students as  $student){
            $student->semesterMarkHistory = json_decode($student->semesterMarkHistory);
            $currentAcademicTerm = reset(array_filter($student->semesterMarkHistory ,function($value)use($request){
                return $value->examRegistrationId == $request->examRegistrationId;
            }));
            $batchStudents[$student->groupId]->id = $student->groupId;
            $batchStudents[$student->groupId]->deptName = $student->deptName;
            $batchStudents[$student->groupId]->academicTermName = $student->academicTermName;
            $semesterNames = CommonExamService::getInstance()->getDifferentSemesterName($batchStudents[$student->groupId]->academicTermName);
            $batchStudents[$student->groupId]->semInRomanLetter = $semesterNames->romanLetter;
            $batchStudents[$student->groupId]->name = $student->studentDetails->groupName;
            $batchStudents[$student->groupId]->subjects[$student->academicPaperSubjectId]->id = $student->academicPaperSubjectId;
            $batchStudents[$student->groupId]->subjects[$student->academicPaperSubjectId]->code = $student->subjectCode;
            $batchStudents[$student->groupId]->subjects[$student->academicPaperSubjectId]->name = $student->subjectName;
            $batchStudents[$student->groupId]->students[$student->id]->id = $student->id;
            $batchStudents[$student->groupId]->students[$student->id]->registerNo = $student->regNo;
            $batchStudents[$student->groupId]->students[$student->id]->name = $student->studentName;
            $batchStudents[$student->groupId]->students[$student->id]->sgpa = $currentAcademicTerm->sgpa;
            $batchStudents[$student->groupId]->students[$student->id]->failedStatus = $currentAcademicTerm->failedStatus ;
            $batchStudents[$student->groupId]->students[$student->id]->remarks = "";
            $batchStudents[$student->groupId]->students[$student->id]->subjects[$student->academicPaperSubjectId]->id = $student->academicPaperSubjectId;
            $batchStudents[$student->groupId]->students[$student->id]->subjects[$student->academicPaperSubjectId]->code = $student->subjectCode;
            $batchStudents[$student->groupId]->students[$student->id]->subjects[$student->academicPaperSubjectId]->name = $student->subjectName;
            $batchStudents[$student->groupId]->students[$student->id]->subjects[$student->academicPaperSubjectId]->attendanceStatus = $student->subAttendanceStatus;
            $batchStudents[$student->groupId]->students[$student->id]->subjects[$student->academicPaperSubjectId]->failedStatus = $student->subjectFailedStatus;
            $batchStudents[$student->groupId]->students[$student->id]->subjects[$student->academicPaperSubjectId]->grade = $student->subjectGrade;
        }
        foreach( $batchStudents as $batch){
            foreach( $batch->students as $student){
                $customFields = AmsCustomFieldsService::getInstance()->getAmsCustomFieldValue(AmsCustomFieldsEntities::STUDENT, $student->id, []);
                if( $customFields ){
                    $student->ktuCode = CommonExamService::getInstance()->getCustomFieldObjectList($customFields)->studentData->KTU_CODE;
                }
            }
        }
        $requestForExamRegistration = new SearchExamRegistrationRequest;
        $requestForExamRegistration->id = $request->examRegistrationId;
        $additionalInfo->examRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration));
           
        $additionalInfo->examRegistration->examYear = $additionalInfo->examRegistration->properties->examYear;
        $additionalInfo->examRegistration->examMonth = $additionalInfo->examRegistration->properties->examMonth;
        $additionalInfo->examRegistration->examMonthYear = date("F Y", strtotime($additionalInfo->examRegistration->examYear."-".$additionalInfo->examRegistration->examMonth));
        $additionalInfo->collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/endSemesterReport/$templateName.twig"), [ 'batchs'=>$batchStudents,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Evaluation Report</title><body>';
            $prtContent .= $responseHtml;
            $prtContent .= '</body></html>';
            $width = 7 * 38;
            $height = $width * 1.414;
            $options = array(
                'page-width'     => $width . "mm",
                'page-height'    => $height . "mm",
                'dpi'            => 96,
                'margin-top' => "10mm",
                'margin-left' => "10mm",
                'margin-right' => "10mm",
                'margin-bottom' => "10mm",
                // '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;
    }
     /**
     * get All Registered Students Details
     * @param $searchRequest 
     */
    public function getAllRegistredStudentOverAllDetails($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $orderBy = " ORDER BY spa.properties->>'$.registerNumber' ASC";
            $whereQuery = "";
            if(!empty($searchRequest->groupId)) {
                $groupIdString = is_array($searchRequest->groupId) ? "'" . implode("','",$searchRequest->groupId) . "'" : "'".$searchRequest->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            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 )";
            }
            $query = "SELECT DISTINCT
                        sa.studentID AS id,
                        sa.studentID AS studentId,
                        sa.studentName,
                        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 courseTypeName,
                        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 ->>'$.grade' AS semesterGrade,
                        esmdsem.mark_history AS semesterMarkHistory,
                        esmdsem.failed_status AS semesterFailedStatus,
                        esmdsem.mark_details AS semesterMarkDetails,
                        s.code AS subjectCode,
                        aps.properties ->> '$.syllabusName' AS syllabusName,
                        s.name AS subjectName,
                        eers.cm_academic_paper_subjects_id AS academicPaperSubjectId,
                        esmdsub.mark_details ->>'$.externalGrade' AS subjectExtrenalGrade,
                        esmdsub.grade AS subjectGrade,
                        esmdsub.mark_details ->>'$.attendanceStatus' AS subAttendanceStatus,
                        esmdsub.failed_status AS subjectFailedStatus,
                        esmdsubcon.failed_status AS subjectConsolidatedFailedStatus
                    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
                    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
                    INNER JOIN studentaccount sa ON 
                        sa.studentID = esar.student_id
                    INNER JOIN student_program_account spa
                        ON spa.student_id = sa.studentID
                    INNER JOIN groups_relations gr ON 
                        gr.parent_groups_id = g.id
                    INNER JOIN `groups` sg ON 
                        sg.id = gr.child_groups_id AND sg.type = 'SUBJECT'
                    INNER JOIN group_members sgm ON
                        sgm.groups_id = sg.id AND 
                        sgm.academic_status IN ('ACTIVE') AND
                        sgm.members->>'$.studentId' = spa.id
                    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 
                    WHERE 1=1";
            $studentMarkDetails = $this->executeQueryForList($query.$whereQuery.$orderBy);
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $studentMarkDetails;
    }
     /**
     * get Regular Exam Couse Wise Result Analysis
     * @param $searchRequest 
     * @return $response 
     */
     public function getExamCourseWiseResultAnalysis($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'];
            $courseWiseResultAnalysisRequest = new \stdClass;
            $courseWiseResultAnalysisRequest->academicTermId = $searchRequest->academicTermId;
            $courseWiseResultAnalysisRequest->examRegistrationId = $searchRequest->examRegistrationId;
            
            // 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; 
            }
            
            $heads = [];
            $heads['male'] = 'male';
            $heads['female'] = 'female';
            $heads['consolidated'] = 'consolidated';
            $resultAnalysis = $this->getCourseWiseResultAnalysis($courseWiseResultAnalysisRequest);
            if(empty($resultAnalysis)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No Entry In This Exam Registration");
            }
            else{
                $templateName = "ResultStatisticalAnalysis";
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'resultAnalysis'=>$resultAnalysis ,'heads'=>$heads, '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>Result Statistical 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 = RegularExamReportService::getInstance()->getAllRegistredStudentOverAllDetails($request);
            // $studentMarkDetails = $this->getMarkReportDummyData();
            if($studentMarkDetails){
                foreach($studentMarkDetails as $student){
                    $student->academicTerm = reset($student->academicTerms);
                    $currentAcademicTerm = reset(array_filter(reset($student->academicTerms)->markHistory,function($value)use($request){
                        return $value->examRegistrationId == $request->examRegistrationId;
                    }));
                    $batchId = $student->studentDetails->batchId;
                    $resultAnalysis[$batchId]->batchId = $student->studentDetails->batchId;
                    $resultAnalysis[$batchId]->batchName = $student->studentDetails->batchName;
                    $resultAnalysis[$batchId]->data['consolidated']->enrolled++;
                    $resultAnalysis[$batchId]->data['consolidated']->passed += $currentAcademicTerm->failedStatus == "FAILED" ? 0 : 1;
                    $resultAnalysis[$batchId]->data['consolidated']->failed += $currentAcademicTerm->failedStatus == "FAILED" ? 1 : 0;
                    $student->isAbsentInSubject = 1;
                    foreach ( $student->academicTerm->subjects as $subject ) {
                        if ($subject->examAttendanceStatus == 'PRESENT') {
                            $student->isAbsentInSubject = 0;
                            break;
                        }
                    }
                    if (!$student->isAbsentInSubject) {
                        $resultAnalysis[$batchId]->data['consolidated']->appeared++;
                    }
                    else{
                        $resultAnalysis[$batchId]->data['consolidated']->absent++;
                    }
                    
                    $gender = $student->studentDetails->gender;
                    $studentGender = "";
                    if( $gender == "MALE"){
                        $studentGender = "male";
                    }
                    else if( $gender == "FEMALE"){
                        $studentGender = "female";
                    }
                    if( $studentGender ){
                        $resultAnalysis[$batchId]->data[$studentGender]->enrolled++;
                        $resultAnalysis[$batchId]->data[$studentGender]->passed += $currentAcademicTerm->failedStatus == "FAILED" ? 0 : 1;
                        $resultAnalysis[$batchId]->data[$studentGender]->failed += $currentAcademicTerm->failedStatus == "FAILED" ? 1 : 0;
                        if (!$student->isAbsentInSubject) {
                            $resultAnalysis[$batchId]->data[$studentGender]->appeared++;
                        }
                        else{
                            $resultAnalysis[$batchId]->data[$studentGender]->absent++;
                        }
                    }
                }
                foreach($resultAnalysis as $singleResultAnalysis){
                    $singleResultAnalysis->data['consolidated']->passPercentage = $singleResultAnalysis->data['consolidated']->passed && $singleResultAnalysis->data['consolidated']->appeared ? round ( ( 100 * $singleResultAnalysis->data['consolidated']->passed / $singleResultAnalysis->data['consolidated']->appeared ), 2) : 0;    
                    
                    $singleResultAnalysis->data['male']->passPercentage = $singleResultAnalysis->data['male']->passed && $singleResultAnalysis->data['male']->appeared ? round ( ( 100 * $singleResultAnalysis->data['male']->passed / $singleResultAnalysis->data['male']->appeared ), 2) : 0;                    
                    
                    $singleResultAnalysis->data['female']->passPercentage = $singleResultAnalysis->data['female']->passed && $singleResultAnalysis->data['female']->appeared ? round ( ( 100 * $singleResultAnalysis->data['female']->passed / $singleResultAnalysis->data['female']->appeared ), 2) : 0;                    
                }
            }
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $resultAnalysis;
    }
    /**
     * get Registered Student Report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getExamRegisteredStudentReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->examType = $searchRequest->examType;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->subjectId = $searchRequest->subjectId;
        $students = NominalRollService::getInstance()->getAllExamRegisteredStudentDetailsForNominalRoll($request);
        if(empty($students)){
            throw new ExamControllerException(ExamControllerException::NO_STUDENT_IN_THE_BATCH_SUBJECT,"No details found.");
        }
        $templateName = "registered-student-report-template-1";
        $additionalInfo->examRegistrationName = reset($students)->examRegistrationName;
        $additionalInfo->subjectName = reset(reset($students)->subjects)->name;
        $additionalInfo->subjectCode = reset(reset($students)->subjects)->code;
        $additionalInfo->collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/registeredStudentReport/$templateName.twig"), [ 'students'=>$students,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Registered Student 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->subjects = $subjects;
        $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
        return  $programResult;
    }
    
  
      /**
     * get Registered Student Report
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getExamTallyReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request = $searchRequest;
        $feeReceiptConstantValue = "";
        $searchExamRuleRequest = new SearchRuleRequest;
        $searchExamRuleRequest->name = 'EXAM_REGISTRATION_CREATION_RULE';
        $ruleObj = reset(RuleService::getInstance()->searchRule($searchExamRuleRequest));
        if($ruleObj){
            $feeReceiptConstantValue = $ruleObj->rule->feeReceiptConstantValue ?? "";
        }
        $examType = 'EC_EXAM_TALLY_REPORT';
        $tallyReportTemplate = StudentMarkListService::getInstance()->getUniversityMarkListTemplate($examType);
        $students = $this->getStudentExamFeeDetails($request);
        if(empty($students)){
            throw new ExamControllerException(ExamControllerException::NO_STUDENT_IN_THE_BATCH_SUBJECT,"No details found.");
        }
        foreach($students as $student){
            if($feeReceiptConstantValue){
                $student->feeReceiptNo = $feeReceiptConstantValue."" .date("Y"). "EX " .str_pad($student->id, 5, '0', STR_PAD_LEFT);
            }
            $student->examAcademicYear = ($student->batchStartYear + (floor(($student->semInSemNumber - 1) / 2))) ." - ".($student->batchStartYear +  (floor(($student->semInSemNumber - 1) / 2)) + 1);
            $student->timestamp = strtotime($student->transactionDate);
            $student->transactionDate = date("d-m-Y", $student->timestamp);
        }
        $templateName = "exam-tally-report-template-default";
        if($tallyReportTemplate == 'Template_1'){
            $templateName = "exam-tally-report-template-1";
        }
        $additionalInfo->fromDate = strtotime($request->fromDate);
        $additionalInfo->fromDate = date("d-m-Y", $additionalInfo->fromDate);
        $additionalInfo->toDate = strtotime($request->toDate);
        $additionalInfo->toDate = date("d-m-Y", $additionalInfo->toDate);
        $additionalInfo->currentDateTime = date('d-m-Y h:i:sa');
        if($searchRequest->departmentId){
            $getAllDepartmentRequest = new GetAllDepartmentsRequest();
            $getAllDepartmentRequest->ids = $searchRequest->departmentId;
            $departments = DepartmentService::getInstance()->getAllDepartmentForApi($getAllDepartmentRequest);
            $departmentNames = array_column($departments, 'name');
            $additionalInfo->departmentName = implode(',',$departmentNames);        
        }
        else{
            $additionalInfo->departmentName = "ALL";
        }
        if($searchRequest->academicTermId){
            $getAcademicTermRequest = new SearchAcademicTermRequest();
        
            $academicTerms = AcademicTermService::getInstance()->searchAcademicTerm($getAcademicTermRequest);
            foreach($academicTerms as $academicTerm){
                if(in_array($academicTerm->id,$searchRequest->academicTermId)){
                    $academicTermNames[] = $academicTerm->name;
                }
            }
            $additionalInfo->semesterName = implode(',',$academicTermNames);                        
        }
        else{
            $additionalInfo->semesterName = "ALL";
        }
        $additionalInfo->subjectName = reset(reset($students)->subjects)->name;
        $additionalInfo->subjectCode = reset(reset($students)->subjects)->code;
        $additionalInfo->collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/tallyReport/$templateName.twig"), [ 'students'=>$students,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Exam Tally Report</title><body>';
            $prtContent .= $responseHtml;
            $prtContent .= '</body></html>';
            $totalWidth = 297 ;
            $totalHeight = 210;
            $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;
    }
     /**
     * Get Registered Student Digital Valuation Details
     * @param $request
     * @return $students
     */
    public function getStudentExamFeeDetails($request){
        try{
            $searchRequest = $this->realEscapeObject($request);
            $joinQuery = "";
            $whereQuery = "";
            $orderBy = "";
            $groupBy = "";
            if(!empty($searchRequest->fromDate) && !empty($searchRequest->toDate)) {
                $whereQuery .= " AND DATE(eop.transactionDate) >= '$searchRequest->fromDate' AND DATE(eop.transactionDate) <= '$searchRequest->toDate'";
            }
            if(!empty($searchRequest->groupId)) {
                $groupIdString = is_array($searchRequest->groupId) ? "'" . implode("','",$searchRequest->groupId) . "'" : "'".$searchRequest->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if(!empty($searchRequest->examRegistrationId)) {
                $examRegistrationIdString = is_array($searchRequest->examRegistrationId) ? "'" . implode("','",$searchRequest->examRegistrationId) . "'" : "'".$searchRequest->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            if(!empty($searchRequest->departmentId)) {
                $departmentIdString = is_array($searchRequest->departmentId) ? "'" . implode("','",$searchRequest->departmentId) . "'" : "'".$searchRequest->departmentId."'";
                $whereQuery .= " AND d.deptID IN ( $departmentIdString )";
            }
            if(!empty($searchRequest->academicTermId)) {
                $academicTermIdString = is_array($searchRequest->academicTermId) ? "'" . implode("','",$searchRequest->academicTermId) . "'" : "'".$searchRequest->academicTermId."'";
                $whereQuery .= " AND act.id IN ( $academicTermIdString )";
            }
            $query = "SELECT DISTINCT
                eserd.id as examRegStudentId,
                sa.studentID as studentId,
                sa.studentName,
                sa.admissionNo as admissionNo,
                spa.properties->>'$.registerNumber' AS registerNo,
                spa.properties->>'$.rollNumber' AS rollNo,
                eer.name as examRegistrationName,
                act.name as semesterName,
                eop.txnID as txnID,
                eop.payment_gateway_txn_id as paymentGatewayID,
                g.name as groupName,
                g.properties->>'$.startYear' AS batchStartYear,
                CAST(act.properties->>'$.orderNo' AS UNSIGNED) as semInSemNumber,
                eop.amount as totalFee,
                eop.transactionDate as transactionDate,
                esar.id as studentSubjectid,
                esar.properties as studentSubjectProperties
            FROM ec_student_assessment_registration esar
            INNER JOIN studentaccount sa ON sa.studentID = esar.student_id
            INNER JOIN ec_exam_registration_subject eers ON eers.am_assessment_id = esar.am_assessment_id
            INNER JOIN ec_exam_registration_batch eerb ON eerb.id = eers.ec_exam_registration_batch_id
            INNER JOIN ec_exam_registration eer ON eer.id = eerb.ec_exam_registration_id AND eer.trashed IS NULL
            INNER JOIN ec_student_exam_registration_details eserd ON eserd.student_id = sa.studentID AND eserd.ec_exam_registration_id = eer.id
            INNER JOIN `groups` g ON g.id = eerb.groups_id
            INNER JOIN program p ON p.id = g.properties->>'$.programId'
            INNER JOIN academic_term act ON act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR) 
            INNER JOIN student_program_account spa ON spa.student_id  = esar.student_id  AND spa.current_program_id = p.id
            INNER JOIN program_department_relation pdr ON pdr.program_id = spa.current_program_id
            INNER JOIN department d ON d.deptID = pdr.department_id
            INNER JOIN ec_online_payment eop ON eop.studentID = esar.student_id AND eop.properties->>'$.examRegistrationId' = eer.id AND eop.status = 'SUCCESS'
            WHERE
                esar.trashed IS NULL AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED') AND eer.type = esar.ec_exam_registration_type";
        try {
            $registeredStudent = $this->executeQueryForList($query.$whereQuery.$groupBy.$orderBy,$this->mapper[RegularExamReportServiceMapper::GET_STUDENT_EXAM_FEE_DETAILS]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        return $registeredStudent;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
          /**
     * 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;
            
            $subjectWiseResultAnalysisRequest = new \stdClass;
            $subjectWiseResultAnalysisRequest->academicTermId = $searchRequest->academicTermId;
            $subjectWiseResultAnalysisRequest->groupId = $searchRequest->examRegBatchIds;
            $subjectWiseResultAnalysisRequest->absenteesAsFailedStatus = $absenteesAsFailedStatus;
  
            $resultAnalysis = $this->getSubjectWiseResultAnalysisConsolidated($subjectWiseResultAnalysisRequest);
            if(empty($resultAnalysis)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"Result analysis not available");
            }
            else{
                $templateName = "SubjectWiseResultAnalysisConsolidatedTemplate";
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/resultAnalysisSemWiseConsolidated/$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 getSubjectWiseResultAnalysisConsolidated($request){
        $request = $this->realEscapeObject($request);
        try{
            $resultAnalysis = [];
            $studentMarkDetails = $this->getConsolidatedSubjectMarkDetails($request);
            if($studentMarkDetails){
                foreach($studentMarkDetails as $key => $subject){
                    $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->failedStatus == "FAILED" ? 0 : 1;
                    if ($subject->attendanceStatus == 'ABSENT') {
                        $resultAnalysis[$syllabusCode]->absent ++;
                    }
                    if($request->absenteesAsFailedStatus){
                        $resultAnalysis[$syllabusCode]->failed += $subject->failedStatus == "FAILED" ? 1 : 0;
                        if ($subject->attendanceStatus != 'ABSENT') {
                            $resultAnalysis[$syllabusCode]->appeared++;
                        }
                    }
                    else{
                        if ($subject->attendanceStatus != 'ABSENT') { 
                            $resultAnalysis[$syllabusCode]->failed += $subject->failedStatus == "FAILED" ? 1 : 0;
                            $resultAnalysis[$syllabusCode]->appeared++;
                        } 
                    }
                }
                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'];
        
            $absenteesAsFailedStatus = $searchRequest->absenteesAsFailedStatus == 'true' ? true : false;
            $courseWiseResultAnalysisRequest = new \stdClass;
            $courseWiseResultAnalysisRequest->academicTermId = $searchRequest->academicTermId;
            $courseWiseResultAnalysisRequest->courseTypeId = $searchRequest->courseTypeId;
            $courseWiseResultAnalysisRequest->startYear = $searchRequest->startYear;
            $courseWiseResultAnalysisRequest->absenteesAsFailedStatus = $absenteesAsFailedStatus;
            $resultAnalysis = $this->getSemWiseConsolidatedCourseDetails($courseWiseResultAnalysisRequest);
                if(empty($resultAnalysis)){
                throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"Result analysis not available");
                }
                else{
                    $templateName = "CourseWiseResultAnalysisConsolidatedTemplate";
                    $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/resultAnalysisSemWiseConsolidated/$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 getSemWiseConsolidatedCourseDetails($request)
    {
        $request = $this->realEscapeObject($request);
        try{
            $resultAnalysis = [];
            $studentMarkList = $this->getConsolidatedSubjectMarkDetails($request);
            $studentMarkDetails = [];
            foreach($studentMarkList as $key => $student){
                if(empty($studentMarkDetails[$student->studentId])){
                    $studentMarkDetails[$student->studentId] = $student;
                    $studentMarkDetails[$student->studentId]->isAbsentInSubject = 1;
                }
                if ($student->attendanceStatus  == 'PRESENT'){
                    $studentMarkDetails[$student->studentId]->isAbsentInSubject = 0;
                }
                
            }
            if($studentMarkDetails){
                foreach($studentMarkDetails as $key => $student){
                    if($student){
                        $batchId = $student->groupsId;
                        $resultAnalysis[$batchId]->batchId = $student->groupsId;
                        $resultAnalysis[$batchId]->batchName = $student->groupName;
                        $resultAnalysis[$batchId]->enrolled++;
                        $resultAnalysis[$batchId]->passed += $student->semesterFailedStatus == "FAILED" ? 0 : 1;
                        $resultAnalysis[$batchId]->failed += $student->semesterFailedStatus == "FAILED" ? 1 : 0;
                        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 consolidated subject mark details
        * @param $request 
        * @return $subjectsMarkDetails 
    */
    public function getConsolidatedSubjectMarkDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            $whereQuery = "";
            if(!empty($request->groupId)) {
                $groupIdString = is_array($request->groupId) ? implode("','",$request->groupId) : $request->groupId;
                $whereQuery .= " AND g.id IN ('$groupIdString') ";
            }
            if(!empty($request->academicTermId)) {
                $whereQuery .= " AND atm.id = '$request->academicTermId";
            }
            if(!empty($request->startYear)) {
                $whereQuery .= " AND g.properties ->> '$.startYear' = '$request->startYear";
            } 
            if(!empty($request->courseTypeId)) {
                $whereQuery .= " AND p.course_type_id = '$request->courseTypeId";
            }
            $query = "SELECT
                ecsmd.student_id AS studentId,
                ecsmd.groups_id AS groupsId,
                atm.id AS termId,
                ecsmd.cm_academic_paper_subjects_id AS paperSubjetId,
                ecsmd.mark_details AS markDetails,
                ecsmd.no_of_chances_taken AS noOfChancesTaken,
                ecsmd.total_mark AS totalMarkObtained,
                ecsmd.class,
                ecsmd.grade,
                ecsmd.failed_status AS failedStatus,
                ecsmd.attendance_status AS attendanceStatus,
                esmd.failed_status AS semesterFailedStatus,
                g.name AS groupName,
                s.code AS code,
                s.name AS name,
                caps.properties ->> '$.syllabusName' AS syllabusName,
                cap.properties ->> '$.order' AS priority,
                IF(caps.properties ->> '$.classType' = 'THEORY',1,0) AS isTheory
            FROM
                ec_consolidated_subject_mark_details ecsmd
            INNER JOIN student_program_account spa
                ON spa.student_id =  ecsmd.student_id
            INNER JOIN `groups` g ON
                g.id = ecsmd.groups_id 
            INNER JOIN program p ON
                p.id = CAST(g.properties ->> '$.programId' AS CHAR)
            INNER JOIN cm_academic_paper_subjects caps ON
                caps.id = ecsmd.cm_academic_paper_subjects_id
            INNER JOIN cm_academic_paper cap ON
                cap.id = caps.cm_academic_paper_id
            INNER JOIN cm_syllabus_academic_term_settings csats ON
                csats.id = cap.cm_syllabus_academic_term_settings_id
            INNER JOIN academic_term atm ON
                atm.id = csats.academic_term_id
            INNER JOIN v4_ams_subject s ON
                s.id = caps.ams_subject_id
            INNER JOIN ec_semester_mark_details esmd ON 
                esmd.groups_id = ecsmd.groups_id AND esmd.student_id = spa.student_id AND esmd.academic_term_id = atm.id
            WHERE
                1 = 1 AND ecsmd.is_active = 1 
            $whereQuery ORDER BY  esmd.student_id, s.id ASC ";
            $subjectsMarkDetails = $this->executeQueryForList($query);
            return $subjectsMarkDetails;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Get Exam Valuation Progress Report 
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getExamValuationProgressReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->subjectCode = $searchRequest->subjectCodes;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->staffIds = $searchRequest->staffIds;
        $request->startDates = $searchRequest->startDates;
        $request->reportType = $searchRequest->reportType;
        $additionalInfo = new \stdClass;
        $searchRequestExam = new SearchExamRegistrationRequest();
        $searchRequestExam->id = $searchRequest->examRegistrationId;
        $currentExamRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($searchRequestExam));
        $additionalInfo->examRegistrationName = $currentExamRegistration->name;
        $additionalInfo->reportType = $request->reportType;
        $studentDetails = $this->getRegisteredStudentsDigitalValuationDetails($request);
        $reportData = [];
        $assignedStaffIds = [];
        if($request->reportType == 'STAFF_WISE' && !empty($request->staffIds)){
            foreach( $studentDetails as  $student){ 
                $student->subjectValuationDetails = json_decode($student->subjectValuationDetails);
                $student->valuationDetails = json_decode($student->valuationDetails);
                foreach($student->subjectValuationDetails->valuationStaffs as $valuationStaff){
                    if(!empty($valuationStaff->addiitonalExamniners)){
                        foreach($valuationStaff->addiitonalExamniners as $staff){
                            if(in_array($staff,$request->staffIds)){
                                foreach($student->valuationDetails->assignedValuationStaffs as $assignedValuationStaff){
                                    if($assignedValuationStaff->count == $valuationStaff->count && in_array($staff,$assignedValuationStaff->addiitonalExamniners)){
                                        $assignedStaffIds[$staff] = $staff;
                                        $reportData[$staff]->id = $staff;
                                        $reportData[$staff]->name = "Staff Name Temp";
                                        $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->name = $student->subjectCode .'-'. $student->subjectName; 
                                        $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->valuationCount = $valuationStaff->count; 
                                        if(empty($reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->assignedStudentCount)){
                                            $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->assignedStudentCount = 0;
                                            $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->startedStudentCount = 0;
                                            $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->confirmedStudentCount = 0;
                                        }
                                        $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->assignedStudentCount = $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->assignedStudentCount + 1 ; 
                                        if( $valuationStaff->count == '1'){
                                            $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->startedStudentCount = $student->mark1Started ? $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->startedStudentCount + 1 : $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->startedStudentCount;
                                            $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->confirmedStudentCount = $student->mark1Confirm ? $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->confirmedStudentCount + 1 : $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->confirmedStudentCount;
                                            $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->type = 'Valuer';
                                        }
                                        else if( $valuationStaff->count == '2'){
                                            $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->startedStudentCount = $student->mark2Started ? $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->startedStudentCount + 1 : $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->startedStudentCount;
                                            $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->confirmedStudentCount = $student->mark2Confirm ? $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->confirmedStudentCount + 1 : $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->confirmedStudentCount;
                                            $reportData[$staff]->subjectStaff[$student->subjectCode.$valuationStaff->count]->type = 'Reviewer';
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        else if($request->reportType == 'SUBJECT_WISE' && !empty($request->subjectCode)){
            foreach( $studentDetails as  $student){ 
                if(in_array($student->subjectCode,$request->subjectCode)){
                    $student->subjectValuationDetails = json_decode($student->subjectValuationDetails);
                    $student->valuationDetails = json_decode($student->valuationDetails);
                    foreach($student->subjectValuationDetails->valuationStaffs as $valuationStaff){
                        if(!empty($valuationStaff->addiitonalExamniners)){
                            foreach($valuationStaff->addiitonalExamniners as $staff){
                                foreach($student->valuationDetails->assignedValuationStaffs as $assignedValuationStaff){
                                    if($assignedValuationStaff->count == $valuationStaff->count && in_array($staff,$assignedValuationStaff->addiitonalExamniners)){
                                        $assignedStaffIds[$staff] = $staff;
                                        $reportData[$student->subjectCode]->id = $student->subjectCode;
                                        $reportData[$student->subjectCode]->name = $student->subjectCode .'-'. $student->subjectName;
                                        $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->id = $staff; 
                                        $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->name = "Staff Name temp"; 
                                        $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->valuationCount = $valuationStaff->count; 
                                        if(empty($reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount)){
                                            $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount = 0;
                                            $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount = 0;
                                            $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount = 0;
                                        }
                                        $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount = $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount + 1 ; 
                                        if( $valuationStaff->count == '1'){
                                            $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount = $student->mark1Started ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount;
                                            $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount = $student->mark1Confirm ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount;
                                            $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->type = 'Valuer';
                                        }
                                        else if( $valuationStaff->count == '2'){
                                            $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount = $student->mark2Started ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount;
                                            $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount = $student->mark2Confirm ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount;
                                            $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->type = 'Reviewer';
                                        }
                                    }
                                }
                            } 
                        }
                    }
                }
            }
        }
        else if($request->reportType == 'START_DATE_WISE' && !empty($request->startDates)){
            foreach( $studentDetails as  $student){ 
                $student->subjectValuationDetails = json_decode($student->subjectValuationDetails);
                $student->valuationDetails = json_decode($student->valuationDetails);
                $startDateArray = array_unique(array_column($student->subjectValuationDetails->valuationDates, 'startDate'));
                // foreach($student->subjectValuationDetails->valuationDates as $valuationDate){
                if(!empty($startDateArray)){
                    foreach($startDateArray as $startDate){
                        if(in_array($startDate,$request->startDates)){
                            foreach($student->subjectValuationDetails->valuationStaffs as $valuationStaff){
                                if(!empty($valuationStaff->addiitonalExamniners)){
                                    foreach($valuationStaff->addiitonalExamniners as $staff){
                                        foreach($student->valuationDetails->assignedValuationStaffs as $assignedValuationStaff){
                                            if($assignedValuationStaff->count == $valuationStaff->count && in_array($staff,$assignedValuationStaff->addiitonalExamniners)){
                                                $assignedStaffIds[$staff] = $staff;
                                                $reportData[$student->subjectCode]->id = $student->subjectCode;
                                                $reportData[$student->subjectCode]->name = $student->subjectCode .'-'. $student->subjectName;
                                                $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->id = $staff;
                                                $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->name = "Staff Name temp"; 
                                                $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->valuationCount = $valuationStaff->count; 
                                                if(empty($reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount)){
                                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount = 0;
                                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount = 0;
                                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount = 0;
                                                }
                                                $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount = $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount + 1 ; 
                                                if( $valuationStaff->count == '1'){
                                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount = $student->mark1Started ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount;
                                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount = $student->mark1Confirm ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount;
                                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->type = 'Valuer';
                                                }
                                                else if( $valuationStaff->count == '2'){
                                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount = $student->mark2Started ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount;
                                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount = $student->mark2Confirm ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount;
                                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->type = 'Reviewer';
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                // }
            }
        }
        $assignedStaffIds = array_values($assignedStaffIds);
        $staffNames = !empty($assignedStaffIds) ? StaffService::getInstance()->getStaffByIds($assignedStaffIds) : [];
        foreach($staffNames as $staff){
            $staffNamesWithKey[$staff->id] = $staff;
        }
        $templateName = "valuation-progress-report_template_1";
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/valuationProgressReport/$templateName.twig"), [ 'staffs'=>$staffNamesWithKey,'reportData'=>$reportData,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Mark Card Issue Register</title><body>';
            $prtContent .= $responseHtml;
            $prtContent .= '</body></html>';
            $options = array(
                'page-width'     => "210mm",
                'page-height'    => "297mm",
                'dpi'            => 96,
                'margin-top' => "10mm",
                'margin-left' => "10mm",
                'margin-right' => "10mm",
                'margin-bottom' => "10mm",
                // '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;
    }
     /**
     * get Exam Date wise report
     * @param $searchRequest 
     * @return $response 
     */
     public function getExamDateWiseReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $additionalDetails = new \stdClass;
            $additionalDetails->collegeData = CommonExamService::getInstance()->getCollegeDetails();
            $batchRequest = new \stdClass;
            $batchRequest->groupsIds = $searchRequest->groupId;
            $batchDetails =  FinalConsolidatedReportService::getInstance()->getAllGroupDetailsByGroupIds($batchRequest);
            foreach($batchDetails as $batch){
                $batchNames[] =  $batch->groupName;
            }
            $additionalDetails->batchName = implode(" , ",$batchNames);
            $getAcademicTermRequest = new SearchAcademicTermRequest();
            $getAcademicTermRequest->id = $searchRequest->academicTermId;
            $academicTerms = AcademicTermService::getInstance()->searchAcademicTerm($getAcademicTermRequest);
            $additionalDetails->semesterName = reset($academicTerms)->name; 
            $requestForExamRegistration = new SearchExamRegistrationRequest;
            $requestForExamRegistration->id = $searchRequest->examRegistrationId;
            $examRegistration = ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration);
            if(!empty($examRegistration)){
                $additionalDetails->examRegistrationName = reset($examRegistration)->name;
            }
            $getSubjectDetailsReq = new \stdClass;
            $getSubjectDetailsReq->examRegistrationId = $searchRequest->examRegistrationId;
            $getSubjectDetailsReq->academicTermId = $searchRequest->academicTermId;
            $getSubjectDetailsReq->groupId = $searchRequest->groupId;
            $getSubjectDetailsReq->examToDate = $searchRequest->examToDate;
            $getSubjectDetailsReq->examFromDate = $searchRequest->examFromDate;
            $assignedSubjects = ExamRegistrationSubjectService::getInstance()->getAllSubjectAssessmentDetailsByExamRegistrationId($getSubjectDetailsReq);
            foreach($assignedSubjects as $subject){
                $subject->assessmentProperties = json_decode($subject->assessmentProperties);
                if($subject->assessmentProperties->assessmentDate){
                    $uniqueSubjects[$subject->subjectCode]->id = $subject->subjectId;
                    $uniqueSubjects[$subject->subjectCode]->subjectCode = $subject->subjectCode;
                    $uniqueSubjects[$subject->subjectCode]->subjectName = $subject->subjectName;
                    $uniqueSubjects[$subject->subjectCode]->syllabusName = $subject->syllabusName;
                    $uniqueSubjects[$subject->subjectCode]->isTheory = $subject->isTheory;
                    $uniqueSubjects[$subject->subjectCode]->assessmentDate =  date("d-m-Y" ,strtotime($subject->assessmentProperties->assessmentDate));
                    $uniqueSubjects[$subject->subjectCode]->startTime = $subject->assessmentProperties->startTime ? date("h:i A" ,strtotime($subject->assessmentProperties->startTime)) : '';
                    $uniqueSubjects[$subject->subjectCode]->endTime = $subject->assessmentProperties->endTime ? date("h:i A" ,strtotime($subject->assessmentProperties->endTime)) : '';
                }
            }
            if(empty($uniqueSubjects)){
                throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No Subject Assigned");
            }
            else{
                $templateName = "examDateWiseReportTemplate";
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/examDateWiseReport/$templateName.twig"), [ 'subjects'=>$uniqueSubjects ,'additionalDetails'=>$additionalDetails]);
                $prtContent = NULL;
                    $prtContent .= '<html><head>';
                    $prtContent .= "";
                    $prtContent .= '</head><title>Exam Date Wise Report</title><body>';
                    $prtContent .= $responseHtml;
                    $prtContent .= '</body></html>';
                    $totalWidth = 210;
                    $totalHeight = 297;
                    $options = array(
                        'page-width'     => "210mm",
                        'page-height'    => "297mm",
                        'dpi'            => 96,
                        'margin-top' => "10mm",
                        'margin-left' => "10mm",
                        'margin-right' => "10mm",
                        'margin-bottom' => "10mm",
                        // '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;
    }
     /**
     * Get Exam Detailed Valuation Report 
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getExamDetailedValuationReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $request = new \stdClass;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $additionalInfo = new \stdClass;
        $searchRequestExam = new SearchExamRegistrationRequest();
        $searchRequestExam->id = $searchRequest->examRegistrationId;
        $currentExamRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($searchRequestExam));
        $additionalInfo->examRegistrationName = $currentExamRegistration->name;
        $studentDetails = $this->getRegisteredStudentsDigitalValuationDetails($request);
        $reportData = [];
        $assignedStaffIds = [];
        foreach( $studentDetails as  $student){ 
            $student->subjectValuationDetails = json_decode($student->subjectValuationDetails);
            $student->valuationDetails = json_decode($student->valuationDetails);
            foreach($student->subjectValuationDetails->valuationStaffs as $valuationStaff){
                if(!empty($valuationStaff->addiitonalExamniners)){
                    foreach($valuationStaff->addiitonalExamniners as $staff){
                        foreach($student->valuationDetails->assignedValuationStaffs as $assignedValuationStaff){
                            if($assignedValuationStaff->count == $valuationStaff->count && in_array($staff,$assignedValuationStaff->addiitonalExamniners)){
                                $assignedStaffIds[$staff] = $staff;
                                $reportData[$student->subjectCode]->id = $student->subjectCode;
                                $reportData[$student->subjectCode]->name = $student->subjectName;
                                $reportData[$student->subjectCode]->code = $student->subjectCode;
                                if(empty($reportData[$student->subjectCode]->assignedStudentCount)){
                                    $reportData[$student->subjectCode]->assignedStudentCount = 0;
                                }
                                foreach($student->subjectValuationDetails->valuationDates as $valuationDate){
                                    if($valuationDate->count == $valuationStaff->count){
                                        $startDate = strtotime($valuationDate->startDate);
                                        $endDate = strtotime($valuationDate->endDate);
                                        $noOfDays = abs((int) floor(($endDate - $startDate) / (60 * 60 * 24)));
                                        $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->valuationStartDate = $valuationDate->startDate; 
                                        $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->valuationEndDate = $valuationDate->endDate; 
                                        $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->noOfDays = $noOfDays; 
                                    }
                                }
                                $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->id = $staff; 
                                $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->name = "Staff Name temp"; 
                                $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->valuationCount = $valuationStaff->count; 
                                $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->falseNumbers[$student->falseNumber] = $student->falseNumber; 
                                if(empty($reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount)){
                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount = 0;
                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount = 0;
                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount = 0;
                                }
                                $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount = $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->assignedStudentCount + 1 ; 
                                if( $valuationStaff->count == '1'){
                                    $reportData[$student->subjectCode]->assignedStudentCount = $reportData[$student->subjectCode]->assignedStudentCount + 1 ; 
                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount = $student->mark1Started ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount;
                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount = $student->mark1Confirm ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount;
                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->type = 'Valuer';
                                }
                                else if( $valuationStaff->count == '2'){
                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount = $student->mark2Started ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->startedStudentCount;
                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount = $student->mark2Confirm ? $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount + 1 : $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->confirmedStudentCount;
                                    $reportData[$student->subjectCode]->subjectStaff[$staff.$valuationStaff->count]->type = 'Reviewer';
                                }
                            }
                        }
                    } 
                }
            }
        }
        foreach($reportData as $subject){
            uasort($subject->subjectStaff, function($a, $b) {
                return ($a->valuationCount > $b->valuationCount);
            });
            foreach($subject->subjectStaff as $subjectStaff){
                $subjectStaff->falseNumbers = array_filter( $subjectStaff->falseNumbers, function($item) {
                    return $item !== null;
                });
                $subjectStaff->falseNumberRange = min($subjectStaff->falseNumbers) .'-'. max($subjectStaff->falseNumbers);
            }
        }
        $assignedStaffIds = array_values($assignedStaffIds);
        $staffNames = !empty($assignedStaffIds) ? StaffService::getInstance()->getStaffByIds($assignedStaffIds) : [];
        foreach($staffNames as $staff){
            $staffNamesWithKey[$staff->id] = $staff;
        }
        $templateName = "detailed-valuation-report_template_1";
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/detailedValuationReport/$templateName.twig"), [ 'staffs'=>$staffNamesWithKey,'reportData'=>$reportData,'additionalInfo'=>$additionalInfo]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Mark Card Issue Register</title><body>';
            $prtContent .= $responseHtml;
            $prtContent .= '</body></html>';
            $options = array(
                'page-width'     => "297mm",
                'page-height'    => "210mm",
                'dpi'            => 96,
                'margin-top' => "10mm",
                'margin-left' => "10mm",
                'margin-right' => "10mm",
                'margin-bottom' => "10mm",
                // '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;
    }
    /**
     * get Staff Remuneration Report
     * @param $searchRequest 
     * @return $response 
     */
     public function getStaffRemunerationReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $additionalDetails = new \stdClass;
            $additionalDetails->collegeData = CommonExamService::getInstance()->getCollegeDetails();
            $bookletCountStaffDetails = [];
            $studentDetails = $this->getRegisteredStudentsDigitalValuationDetails($searchRequest);
            $staffDeatils = [];
            foreach($studentDetails as $student){
                $student->valuationDetails = json_decode($student->valuationDetails);
                if(!empty($student->valuationDetails->assignedValuationStaffs)){
                    if($student->mark1Confirm && $student->mark1SubmittedStaff){
                        $staffDeatils[$student->mark1SubmittedStaff]->staffId = $staffDeatils[$student->mark1SubmittedStaff]->staffId ?? $student->mark1SubmittedStaff;
                        $staffDeatils[$student->mark1SubmittedStaff]->valuatedCount++;
                    }
                    if($student->mark2Confirm && $student->mark2SubmittedStaff){
                        $staffDeatils[$student->mark2SubmittedStaff]->staffId = $staffDeatils[$student->mark2SubmittedStaff]->staffId ?? $student->mark2SubmittedStaff;
                        $staffDeatils[$student->mark2SubmittedStaff]->valuatedCount++;
                    }
                    if($student->mark3Confirm && $student->mark3SubmittedStaff){
                        $staffDeatils[$student->mark3SubmittedStaff]->staffId = $staffDeatils[$student->mark3SubmittedStaff]->staffId ?? $student->mark3SubmittedStaff;
                        $staffDeatils[$student->mark3SubmittedStaff]->valuatedCount++;
                    }
                    if($student->mark1ReviewConfirm && $student->mark1ReviewSubmittedStaff){
                        $staffDeatils[$student->mark1ReviewSubmittedStaff]->staffId = $staffDeatils[$student->mark1ReviewSubmittedStaff]->staffId ?? $student->mark1ReviewSubmittedStaff;
                        $staffDeatils[$student->mark1ReviewSubmittedStaff]->valuatedCount++;
                    }
                }
            }
            $staffIds = array_column($staffDeatils,'staffId');
            $staffBankDetailsReq = new \stdClass;
            $staffBankDetailsReq->staffIds = $staffIds;
            $staffBankDetails = CommonExamService::getInstance()->getStaffBankAccountDetails($staffBankDetailsReq);
            $allStaffs = [];
            foreach($staffBankDetails as $staff){
                $allStaffs[$staff->id] = $staff;
            }
            foreach($staffDeatils as $staff){
                $staffDeatils[$staff->staffId]->ifscCode = $allStaffs[$staff->staffId]->ifscCode;
                $staffDeatils[$staff->staffId]->bankAccountNumber = $allStaffs[$staff->staffId]->bankAccountNumber;
                $staffDeatils[$staff->staffId]->bankName = $allStaffs[$staff->staffId]->bankName;
                $staffDeatils[$staff->staffId]->name = $allStaffs[$staff->staffId]->name;
                $staffDeatils[$staff->staffId]->deptName = $allStaffs[$staff->staffId]->deptName;           
            }
            uasort($staffDeatils, function ($a, $b) {
                return $a->name > $b->name;
            });
            if(empty($staffDeatils)){
                throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No Staff Found");
            }
            else{
                $templateName = "staffRemunerationReportTemplate";
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examinationReports/staffRemunerationReport/$templateName.twig"), [ 'staffDetails'=>$staffDeatils ,'additionalDetails'=>$additionalDetails]);
                $prtContent = NULL;
                    $prtContent .= '<html><head>';
                    $prtContent .= "";
                    $prtContent .= '</head><title>Exam Date Wise Report</title><body>';
                    $prtContent .= $responseHtml;
                    $prtContent .= '</body></html>';
                    $totalWidth = 210;
                    $totalHeight = 297;
                    $options = array(
                        'page-width'     => "210mm",
                        'page-height'    => "297mm",
                        'dpi'            => 96,
                        'margin-top' => "10mm",
                        'margin-left' => "10mm",
                        'margin-right' => "10mm",
                        'margin-bottom' => "10mm",
                        // '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;
    }
 /**
     * get student details by batch
     * @param $request
     * auther sibin c
     */
    public function getBatchStudentsForInvigilatorsDiary($request)
    {
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $orderByQuery = "";
        if(!empty($request->groupId)) {
            $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
            $whereQuery .= " AND g.id IN ( $groupIdString )";
        }
        if(!empty($request->programId)) {
            $programIdString = is_array($request->programId) ? "'" . implode("','",$request->programId) . "'" : "'".$request->programId."'";
            $whereQuery .= " AND p.id IN ( $programIdString )";
        }
        if(!empty($request->academicTermId)) {
            $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
            $whereQuery .= " AND act.id IN ( $academicTermIdString )";
        }
        $orderByQuery = " ORDER BY spa.properties->>'$.registerNumber' ASC";
        $query = "SELECT DISTINCT
                    spa.student_id AS studentId,
                    spa.properties->>'$.rollNumber' AS studentRollNo,
                    spa.properties->>'$.registerNumber' AS registerNo,
                    std.studentName AS studentName,
                    sl.secondlangaugeID as secondLanguageId,
                    sl.secondLangaugeName as secondLanguageName
                FROM 
                    studentaccount s 
                INNER JOIN student_program_account spa
                    ON spa.student_id = s.studentID 
                INNER JOIN student_program_batch_log spbl 
                    ON spbl.program_student_id = spa.id AND spbl.properties->>'$.academicStatus' IN ('ACTIVE','COMPLETED')
                INNER JOIN `program` p 
                    ON p.id = spbl.program_id
                INNER JOIN `groups` g 
                    ON g.id = spbl.batch_group_id
                INNER JOIN groups_relations gr ON 
                    gr.parent_groups_id = g.id
                INNER JOIN `groups` sg ON 
                    sg.id = gr.child_groups_id AND sg.type = 'SUBJECT'
                INNER JOIN group_members sgm ON
                    sgm.groups_id = sg.id AND 
                    sgm.members->>'$.studentId' = spa.id AND sgm.academic_status IN ('ACTIVE')
                INNER JOIN cm_academic_paper_subjects aps ON 
                    aps.id = sg.paperSubjectId
                INNER JOIN cm_academic_paper ap ON 
                    aps.cm_academic_paper_id = ap.id
                INNER JOIN cm_syllabus_academic_term_settings csats ON 
                    csats.id = ap.cm_syllabus_academic_term_settings_id 
                INNER JOIN academic_term act ON
                    act.id = sg.academic_term_id AND act.id = spbl.term_id
                INNER JOIN v4_ams_subject sub ON 
                    sub.id = aps.ams_subject_id
                INNER JOIN studentaccount std ON 
                    std.studentID = spa.student_id
                LEFT JOIN secondLangauge sl ON 
                    sl.secondlangaugeID = std.secondlangaugeID
                WHERE 1=1 AND sg.academic_term_id = csats.academic_term_id";
        try {
            $students = $this->executeQueryForList($query.$whereQuery.$orderByQuery);
            // $students = array_values(CommonUtil::smartSort($students, 'registerNo', $order = 'asc'));
        } catch (\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        if ($request->regNoFrom && $request->regNoTo){
            $students = $this->filterStudentsByRegisterRange($students, $request->regNoFrom, $request->regNoTo);
        }
        return $students;
    } 
    function filterStudentsByRegisterRange($studentList, $startRegNo, $endRegNo) {
        $startIndex = -1;
        $endIndex = -1;
        // Find the start and end indices
        foreach ($studentList as $index => $student) {
            if ($student->registerNo === $startRegNo) {
                $startIndex = $index;
            }
            if ($student->registerNo === $endRegNo) {
                $endIndex = $index;
            }
            // Stop the loop once both indices are found
            if ($startIndex !== -1 && $endIndex !== -1) {
                break;
            }
        }
        // If valid indices are found, slice the array
        if ($startIndex !== -1 && $endIndex !== -1 && $startIndex <= $endIndex) {
            return array_slice($studentList, $startIndex, $endIndex - $startIndex + 1);
        }
        // Return an empty array if the indices are not found or invalid
        return [];
    }
    /**
     * @author Sibin
     * submit student room details
     */
    public function submitStudentRoomDetails($request)
    {
        $properties = $request->properties ? addslashes(json_encode($request->properties, JSON_INVALID_UTF8_IGNORE | JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_ERROR_INVALID_PROPERTY_NAME)) : "";
        $request = $this->realEscapeObject($request);
        $identifier = $request->identifier;
        $userId = $request->userId; // Assuming userId is available in $request object
        $entryType = $request->entryType;
        $userType = $request->userType;
        $identifierType = $request->identifierType;
        $studentList = $request->studentList;
        $createdBy = $request->createdBy;
        $insertStr = [];
        foreach($studentList as $student){
            $userId = $student->studentId;
            $insertStr[] = "('$identifier', $userId, '$properties', '$entryType', '$userType', '$identifierType', '$createdBy', NOW())";
        }
        if(!empty($insertStr)){
            $insertStr = implode($insertStr,",");
            $sql = "INSERT INTO subjectWiseSubmissions (identifier, userId, properties, entryType, userType, identifierType, created_by, created_date) VALUES  $insertStr";
            try {
               return $this->executeQuery($sql);
               AMSLogger::log_info($this->logger,Events::EC_SAVE_EXAM_REG_STUDENT_ROOM_NO, [
                "staff" => new Staff(["id" => $request->userId]),
                "request" => $insertStr,
                "status" => StatusConstants::SUCCESS
            ]);
            } catch (\Exception $e) {
                AMSLogger::log_error($this->logger,Events::EC_SAVE_EXAM_REG_STUDENT_ROOM_NO, [
                    "staff" => new Staff(["id" => $request->userId]),
                    "request" => $insertStr,
                    "errorCode" => $e->getCode(),
                    "errorMessage" => $e->getMessage(),
                    "status" => StatusConstants::FAILED
                ]);
                throw new ExamControllerException($e->getMessage(), $e->getCode());
            }
        }
        return false;
    }
    /**
     * get All Hall Assigned Registered Student Details
     * @param $request
     * auther Krishnajith
     */
    public function getAllHallAssignedRegisteredStudentDetails($request){
        $request = $this->realEscapeObject($request);
        if(is_array($request->assessmentId)){
            foreach($request->assessmentId as $key => $value){
                $request->assessmentId[$key] = stripslashes($value);
            }
        }
        $whereQuery = "";
        $orderByQuery = "";
        if(!empty($request->examRegistrationId)) {
            $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
            $whereQuery .= " AND eerb.ec_exam_registration_id IN ( $examRegistrationIdString )";
        }
        if(!empty($request->assessmentId)) {
            $assessmentIdString = is_array($request->assessmentId) ? "'" . implode("','",$request->assessmentId) . "'" : "'".$request->assessmentId."'";
            $whereQuery .= " AND esar.am_assessment_id IN ( $assessmentIdString )";
        }
        if(!empty($request->academicTermId)) {
            $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
            $whereQuery .= " AND eerb.properties ->> '$.academicTermId' IN ( $academicTermIdString )";
        }
        if(!empty($request->hallId)) {
            $hallIdString = is_array($request->hallId) ? "'" . implode("','",$request->hallId) . "'" : "'".$request->hallId."'";
            $whereQuery .= " AND eh.id IN ( $hallIdString )";
        }
        $orderByQuery = " ORDER BY esar.falseNo ASC";
         $query = "SELECT DISTINCT
                    esar.falseNo AS falseNumber,
                    eer.name as examRegistrationName
                FROM 
                    ec_student_assessment_registration esar
                INNER JOIN ec_exam_registration_subject eers ON
                    eers.am_assessment_id = esar.am_assessment_id 
                INNER JOIN ec_exam_registration_batch eerb ON
                    eerb.id = eers.ec_exam_registration_batch_id 
                INNER JOIN ec_exam_registration eer ON
                    eer.id = eerb.ec_exam_registration_id AND
                    eer.trashed IS NULL
                LEFT JOIN ec_hall_arrangement_group_assigned_student ehagas  ON 
                    ehagas.am_assessment_id = esar.am_assessment_id AND 
                    ehagas.student_id = esar.student_id 
                LEFT JOIN ec_hall_arrangement_group_assigned_hall ehagh ON 
                    ehagh.id = ehagas.ec_hall_arrangement_group_assigned_hall_id AND ehagh.is_locked = 1
                LEFT JOIN ec_exam_hall eh ON
                    eh.id = ehagh.ec_exam_hall_id
                WHERE 1=1 AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED') AND
                    eer.type = esar.ec_exam_registration_type AND esar.falseNo IS NOT NULL ";
        try {
            $students = $this->executeQueryForList($query.$whereQuery.$orderByQuery);
        } catch (\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        return $students;
    } 
}