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 / 86
CRAP
0.00% covered (danger)
0.00%
0 / 7095
StudentExamRegistrationService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 86
2568006.00
0.00% covered (danger)
0.00%
0 / 7094
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 3
 saveStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 29
 validateSaveStudentRegistrationRequest
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 7
 insertStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 16
 updateStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 21
 deleteStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 19
 restoreStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 19
 searchStudentExams
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 52
 searchStudentRegularExamSubjectDetails
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 57
 searchExamAssessments
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 34
 searchAssessmentExamStudents
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 65
 searchUnassignedAssessmentExamStudents
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 42
 updateValuationDetails
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 19
 searchPacketStudents
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 72
 updateStudentRegistrationValidationDetails
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 getExamRegistrationsForStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
40200.00
0.00% covered (danger)
0.00%
0 / 553
 getStudentExamRegistrationSubjectFeeDetails
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 21
 getStudentRegularExamRegistrationSubjectFeeDetails
0.00% covered (danger)
0.00%
0 / 1
16002.00
0.00% covered (danger)
0.00%
0 / 387
 getStudentExamRegistrationFeeDetails
0.00% covered (danger)
0.00%
0 / 1
992.00
0.00% covered (danger)
0.00%
0 / 246
 saveStudentExamRegistrationDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 insertStudentExamRegistratioDetails
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 19
 getStudentExamRegistrationTotalFeeDetails
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 57
 getCurrentPaymentStatus
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 26
 getCurrentPaymentStatusForStudent
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 36
 getStudentSupplementaryExamRegistrationSubjectFeeDetails
0.00% covered (danger)
0.00%
0 / 1
31506.00
0.00% covered (danger)
0.00%
0 / 562
 searchAllStudentDetailsByExamRegistration
0.00% covered (danger)
0.00%
0 / 1
306.00
0.00% covered (danger)
0.00%
0 / 56
 getAllStudentDetailsByExamRegistration
0.00% covered (danger)
0.00%
0 / 1
420.00
0.00% covered (danger)
0.00%
0 / 172
 deleteStudentRegistrationDetails
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 getExamMarkEntryForExamRegistration
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 43
 getAllRevaluationsForStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
2070.00
0.00% covered (danger)
0.00%
0 / 131
 getStudentRevaluationDetails
0.00% covered (danger)
0.00%
0 / 1
552.00
0.00% covered (danger)
0.00%
0 / 192
 getAllRevaluationSubjectsForStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
3306.00
0.00% covered (danger)
0.00%
0 / 254
 searchAllStudentDetailsByExamRevaluation
0.00% covered (danger)
0.00%
0 / 1
2070.00
0.00% covered (danger)
0.00%
0 / 126
 getCountOfRegisteredStudents
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 53
 getRegisteredStudentsValuationDetails
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 102
 getRevaluationRegisteredStudentsValuationDetails
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 97
 deleteNotAppliedStudents
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 getStudentExamNotification
0.00% covered (danger)
0.00%
0 / 1
870.00
0.00% covered (danger)
0.00%
0 / 136
 getStudentCollegeChallanTemplate
0.00% covered (danger)
0.00%
0 / 1
992.00
0.00% covered (danger)
0.00%
0 / 153
 checkChallanNoAlreadyExist
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 15
 getStudentChallanDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 18
 getStudentExamTimeTable
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 32
 saveWithHeldStatus
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 11
 getAllRevaluationSubjectsForManageStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
992.00
0.00% covered (danger)
0.00%
0 / 145
 getExamMarkEntryForExamRevaluation
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 47
 updateBalceAmountDetailsInExamRegistration
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 34
 getRevaluationStudentRegisteredReport
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 50
 getStudentRegularExamRegistrationSubjectFeeDetailsForBulkStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
1260.00
0.00% covered (danger)
0.00%
0 / 136
 countOfStudentsAssignedBatch
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 40
 countOfRegisteredStudentsInBatch
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 44
 saveStudentRegistrationOnlinePaymentStatus
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 27
 validateSaveOnlinePaymentStatus
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 5
 insertStudentOnlinePaymentStatus
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 updateStudentOnlinePaymentStatus
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 20
 searchStudentOnlinePayement
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 39
 deleteStudentOnlinePaymentStatus
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 14
 getStudentExamFeeReceipt
0.00% covered (danger)
0.00%
0 / 1
420.00
0.00% covered (danger)
0.00%
0 / 96
 getParentRevaluationRegistredStudentDetails
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 110
 searchPacketStudentsRevaluation
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 83
 getStudentCollegeChallanTemplateRevaluation
0.00% covered (danger)
0.00%
0 / 1
210.00
0.00% covered (danger)
0.00%
0 / 115
 getStudentRevaluationExamFeeReceipt
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 60
 searchAllStudentDetailsBySpecialExamRegistration
0.00% covered (danger)
0.00%
0 / 1
272.00
0.00% covered (danger)
0.00%
0 / 54
 getAllStudentDetailsBySpecialExamRegistration
0.00% covered (danger)
0.00%
0 / 1
306.00
0.00% covered (danger)
0.00%
0 / 108
 getStudentSpecialExamRegistrationSubjectFeeDetails
0.00% covered (danger)
0.00%
0 / 1
4692.00
0.00% covered (danger)
0.00%
0 / 241
 getStudentSpecialExamRegistrationFeeDetails
0.00% covered (danger)
0.00%
0 / 1
506.00
0.00% covered (danger)
0.00%
0 / 140
 saveStudentExamSeatNumber
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 11
 getStudentAssignedHallsForExam
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 24
 getMinorHonoursExamRegistrationsForStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
5700.00
0.00% covered (danger)
0.00%
0 / 209
 searchStudentCurrentHornoursMinorExamRegistrationFeeDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 6
 getStudentRegularMinorHonourExamRegistrationSubjectFeeDetails
0.00% covered (danger)
0.00%
0 / 1
7140.00
0.00% covered (danger)
0.00%
0 / 286
 saveMoocExamRegistrationCertificateStatus
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 11
 getStudentRegisteredExamRegistrationWithResultDetails
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 85
 getBlockedUnblockedSubjectDetails
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 28
 checkAndUpdateAllStudentPaymentStatus
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 87
 getOnlineAppliedStudentDetails
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 88
 getStudentExamRegistrationDetails
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 73
 getStudentExamApplicationForm
0.00% covered (danger)
0.00%
0 / 1
380.00
0.00% covered (danger)
0.00%
0 / 104
 setStudentAdditonalProfileDetails
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 14
 removeStudentRegistrationStatusFromFailedToUnpaid
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 17
 removeStudentRegistrationStatusFromFailedToUnpaidRevaluation
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 23
 setPageSize
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 5
 getAllStudentIdsByExamRegistration
0.00% covered (danger)
0.00%
0 / 1
650.00
0.00% covered (danger)
0.00%
0 / 106
 getExamRegistrationForHallTicket
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 29
 getStudentRoomDetails
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 18
 getRegisteredStudentExamRegistrationDetails
0.00% covered (danger)
0.00%
0 / 1
552.00
0.00% covered (danger)
0.00%
0 / 152
 getRegisteredStudentRevaluationDetails
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 86
<?php
namespace com\linways\ec\core\service;
use com\linways\base\util\SecurityUtils;
use com\linways\ec\core\dto\StudentRegistration;
use com\linways\base\util\MakeSingletonTrait;
use com\linways\ec\core\constant\StatusConstants;
use com\linways\ec\core\constant\ExamPaymentMethodConstants;
use com\linways\ec\core\exception\ExamControllerException;
use com\linways\ec\core\request\SearchStudentRegistrationRequest;
use com\linways\ec\core\mapper\StudentExamRegistrationServiceMapper;
use com\linways\core\ams\professional\service\CommonService;
use com\linways\ec\core\service\CommonExamService;
use com\linways\ec\core\service\ExamRegistrationService;
use com\linways\ec\core\constant\SettingsConstants;
use com\linways\ec\core\constant\StudentExamRegistrationPaymentStatus;
use com\linways\ec\core\constant\StudentExamRegistrationOnlinePaymentStatus;
use com\linways\ec\core\constant\StudentExamRegistrationStatus;
use com\linways\ec\core\request\SearchStudentExamRegistrationRequest;
use com\linways\ec\core\service\ExamRegistrationFeeCommonService;
use com\linways\ec\core\dto\StudentExamRegistrationDetails;
use com\linways\ec\core\constant\ExamRegistrationTypeConstants;
use com\linways\core\ams\professional\logging\AMSLogger;
use com\linways\ec\core\logging\Events;
use com\linways\ec\core\logging\entities\Staff;
use com\linways\academics\core\request\attendance\AttendanceTermWiseReport;
use com\linways\academics\core\service\attendance\AttendanceService;
use com\linways\ec\core\request\SearchExamRegistrationRequest;
use com\linways\ec\core\request\SearchRuleRequest;
use com\linways\ec\core\service\RuleService;
use com\linways\base\util\TwigRenderer;
use com\linways\ec\core\service\HallTicketsService;
use com\linways\core\ams\professional\util\PdfUtil;
use com\linways\core\ams\professional\util\CommonUtil;
use com\linways\core\ams\professional\service\StudentService;
use com\linways\core\ams\professional\service\examcontroller\CommonExamService AS ProfessionalCommonExamService;
use com\linways\ec\core\constant\SyllabusTypeConstants;
use com\linways\ec\core\service\ExamStudentAdditionalDetailsService;
use com\linways\ec\core\service\CertificateUploadService;
use com\linways\core\ams\professional\dto\SettingsConstents;
use com\linways\core\ams\professional\service\examcontroller\examvaluationrule\ExamValuationRuleService;
use com\linways\ec\core\service\MarksCardService;
use com\linways\ec\core\service\GradeSchemeService;
use com\linways\academics\core\service\ExperimentCompletionService;
use com\linways\academics\core\request\experimentStatus\GetStudentLabStatusRequest;
use com\linways\core\ams\professional\service\StudentPaymentService;
use com\linways\core\ams\professional\request\StudentOnlinePaymentRequest;
use com\linways\core\ams\professional\dto\PaymentGateway;
use TCPDFBarcode;
use com\linways\academics\core\service\StudentService AS AmStudentService;
use function strings\lowerCase;
use com\linways\ec\core\service\BlockStudentMappingService;
use com\linways\core\ams\professional\service\ReservationStudentsService;
use com\linways\core\ams\professional\service\StaffService;
class StudentExamRegistrationService extends BaseService
{
    use MakeSingletonTrait;
    private function __construct() {
        $this->mapper = StudentExamRegistrationServiceMapper::getInstance()->getMapper();
        $this->logger = AMSLogger::getLogger('exam-controller-log');
    }
    /**
     * Save student registration
     * @param StudentRegistration $studentRegistration
     * @return String $id
     */
    public function saveStudentRegistration (StudentRegistration $studentRegistration){
        $currentStaffId = $GLOBALS['userId'] ? $GLOBALS['userId'] : $studentRegistration->studentId;
        $studentRegistration = $this->realEscapeObject($studentRegistration);
        $studentRegistration->createdBy = $studentRegistration->createdBy ? $studentRegistration->createdBy : $GLOBALS['userId'];
        $studentRegistration->updatedBy =$studentRegistration->updatedBy ? $studentRegistration->updatedBy : $GLOBALS['userId'];
        try{
            $this->validateSaveStudentRegistrationRequest($studentRegistration);
            if(!empty($studentRegistration->id)){
                $studentRegistration->id = $this->updateStudentRegistration($studentRegistration);
            }
            else{
                $studentRegistration->id = $this->insertStudentRegistration($studentRegistration);
            }
            AMSLogger::log_info($this->logger,Events::EC_SAVE_STUDENT_ASSESSMENT_REGISTRATION,[
            "staff" => new Staff(["id" => $currentStaffId]),
                "request" => $studentRegistration,
                "status" => StatusConstants::SUCCESS
            ]);
        }catch(\Exception $e) {
            AMSLogger::log_error($this->logger,Events::EC_SAVE_STUDENT_ASSESSMENT_REGISTRATION,[
                "staff" => new Staff(["id" => $currentStaffId]),
                "request" => $studentRegistration,
                "errorCode" => $e->getCode(),
                "errorMessage" => $e->getMessage(),
                "status" => StatusConstants::FAILED
            ]);
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        return $studentRegistration->id;
    }
    
    /**
     * Validate StudentRegistration Request Before Saving
     * @param StudentRegistration $studentRegistration
     * @return NULL
     */
    private function validateSaveStudentRegistrationRequest(StudentRegistration $studentRegistration){
        if(empty($studentRegistration->studentId))
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_STUDENT_REGISTRATION,"Student is empty! Please select student for registration"); 
        if(empty($studentRegistration->assessmentId))
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_STUDENT_REGISTRATION,"Exam is invalid.");
        if((empty($studentRegistration->createdBy)  && empty($studentRegistration->id)) || (empty($studentRegistration->updatedBy) && !empty($studentRegistration->id)))
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_STUDENT_REGISTRATION,"Unauthorized entry.");
    }
    
    /**
     * Insert studentRegistration
     * @param StudentRegistration $studentRegistration
     * @return String $id
     */
    private function insertStudentRegistration(StudentRegistration $studentRegistration){
        $properties = !empty($studentRegistration->properties) ? "'".json_encode($studentRegistration->properties)."'" : "'{}'";
        $valuationDetails = !empty($studentRegistration->valuationDetails) ? "'" . json_encode($studentRegistration->valuationDetails) . "'" : "'{}'";
        $identifyingContext = !empty($studentRegistration->identifyingContext) ? "'" . json_encode($studentRegistration->identifyingContext) . "'" : "'{}'";
        $id = SecurityUtils::getRandomString();
        $query = "INSERT INTO ec_student_assessment_registration
            (id,am_assessment_id,student_id,ec_exam_registration_type,properties,identifying_context,valuation_details,created_by,updated_by)
        VALUES
            ('$id','$studentRegistration->assessmentId','$studentRegistration->studentId','$studentRegistration->examRegistrationType',$properties,$identifyingContext,$valuationDetails,'$studentRegistration->createdBy','$studentRegistration->updatedBy') 
            ON DUPLICATE KEY UPDATE `properties` = JSON_MERGE_PATCH(`properties`,$properties), `identifying_context` = JSON_MERGE_PATCH(`identifying_context`,$identifyingContext), updated_by = VALUES(created_by)";
        
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $id;
    }
    /**
     * Update Student registration
     * @param StudentRegistration $studentRegistration
     * @return NULL
     */
    private function updateStudentRegistration(StudentRegistration $studentRegistration){
        $properties = !empty($studentRegistration->properties) ? "'".json_encode($studentRegistration->properties)."'" : "JSON_OBJECT()";
        $valuationDetails = !empty($studentRegistration->valuationDetails) ? "'" . json_encode($studentRegistration->valuationDetails) . "'" : "JSON_OBJECT()";
        $identifyingContext = !empty($studentRegistration->identifyingContext) ? "'" . json_encode($studentRegistration->identifyingContext) . "'" : "JSON_OBJECT()";
        $updateColumn = !empty($studentRegistration->valuationDetails) ? "valuation_details = JSON_MERGE_PATCH(`valuation_details`,$valuationDetails)," : "";
        $query = "UPDATE ec_student_assessment_registration 
        SET 
            am_assessment_id = '$studentRegistration->assessmentId',
            student_id = '$studentRegistration->studentId',
            ec_exam_registration_type = '$studentRegistration->examRegistrationType',
            properties = JSON_MERGE_PATCH(`properties`,$properties),
            identifying_context = JSON_MERGE_PATCH(`identifying_context`,$identifyingContext),
            $updateColumn
            updated_by = '$studentRegistration->updatedBy'
        WHERE 
            id = '$studentRegistration->id'";
        try {
            $this->executeQuery($query);return $studentRegistration->id;
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
    }
    
    /**
     * Delete Student registration (Soft Delete)
     * @param String $id
     * @return NULL
     */
    public function deleteStudentRegistration($id)
    {
        $id = $this->realEscapeString($id);
        $updatedBy = $GLOBALS['userId'];
        if(empty($id)) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_STUDENT_REGISTRATION,"Student registration not found. Please try again!");
        }
        $query = "UPDATE 
            ec_student_assessment_registration 
        SET 
            trashed = UTC_TIMESTAMP(),
            updated_by = '$updatedBy
        WHERE 
            id = '$id'";
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_DELETING_STUDENT_REGISTRATION,"Error deleting student registration! Please try again");
        }
    }
    /**
     * Restore Student registration
     * @param String $id
     * @return NULL
     */
    public function restoreStudentRegistration($id)
    {
        $id = $this->realEscapeString($id);
        $updatedBy = $GLOBALS['userId'];
        if(empty($id)) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_STUDENT_REGISTRATION,"Student registration not found. Please try again!");
        }
        $query = "UPDATE 
            ec_student_assessment_registration 
        SET 
            trashed=NULL,
            updated_by='$updatedBy
        WHERE 
            id='$id'";
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_RESTORING_STUDENT_REGISTRATION,"Error restoring student registration! Please try again");
        }
    }
    
    /**
     * Search Student registration Details
     * @param SearchStudentRegistrationRequest $request
     * @return StudentRegistration
     */
    public function searchStudentExams(SearchStudentRegistrationRequest $request)
    {
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        if(!empty($request->id)) {
            $whereQuery .= " AND sar.id = '$request->id'";
        }
        if(!empty($request->studentId)) {
            $whereQuery .= " AND sar.student_id = '$request->studentId'";
        }
        if(!empty($request->examRegistrationId)) {
            $whereQuery .= " AND eerb.ec_exam_registration_id = '$request->examRegistrationId'";
        }
        if($request->trashed === StatusConstants::ACTIVE) {
            $whereQuery .= " AND sar.trashed IS NULL";
        }
        if($request->trashed === StatusConstants::TRASHED) {
            $whereQuery .= " AND sar.trashed IS NOT NULL";
        }
        if(!empty($request->name)) {
            $whereQuery .= " AND sar.name LIKE '%$request->name%'";
        }
        if($request->startIndex !== "" && $request->endIndex !== "")
        {
            $limitQuery .= " LIMIT $request->startIndex,$request->endIndex";
        }
        $query = "SELECT
            sar.id,
            sar.am_assessment_id,
            sar.student_id,
            sar.properties,
            sar.trashed,
            sar.created_by,
            sar.created_date,
            sar.updated_by,
            sar.updated_date,
            aa.identifying_context
        FROM
            ec_student_assessment_registration sar
        INNER JOIN am_assessment aa ON
            aa.id = sar.am_assessment_id
        INNER JOIN ec_exam_registration_batch eerb ON
            eerb.id = sar.properties->>'$.examRegistrationBatchId'
        WHERE
            1 = 1";
        try {
            $studentRegistrations = $this->executeQueryForList($query.$whereQuery.$limitQuery,$this->mapper[StudentExamRegistrationServiceMapper::SEARCH_STUDENT_REGISTRATION_SUBJECTS]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch studentRegistration details! Please try again");
        }
        return $studentRegistrations;
    }
    
    /**
     * Search Student registration Details
     * @param $request
     * @return $subjects
     */
    public function searchStudentRegularExamSubjectDetails($request)
    {
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        if(!empty($request->id)) {
            $whereQuery .= " AND ecscmd.id = '$request->id'";
        }
        if(!empty($request->studentId)) {
            $whereQuery .= " AND ecscmd.student_id = '$request->studentId'";
        }
        if(!empty($request->groupId)) {
            $whereQuery .= " AND ecscmd.groups_id = '$request->groupId'";
        }
        if(!empty($request->paperSubjectId)) {
            $paperSubjectIdString = is_array($request->paperSubjectId) ? "'" . implode("','",$request->paperSubjectId) . "'" : '$request->paperSubjectId';
            $whereQuery .= " ecscmd.paper_subject_id IN($paperSubjectIdString)";
        }
        if($request->startIndex !== "" && $request->endIndex !== "")
        {
            $limitQuery .= " LIMIT $request->startIndex,$request->endIndex";
        }
        $query = "SELECT
        ecscmd.id,
        ecscmd.student_id,
        ecscmd.mark_details,
        ecscmd.mark_history,
        ecscmd.no_of_chances_taken,
        ecscmd.total_marks,
        ecscmd.percentage,
        ecscmd.grade,
        ecscmd.grade_point,
        ecscmd.credit_grade_point,
        ecscmd.class,
        ecscmd.status,
        ecscmd.is_dirty,
        ecscmd.created_by,
        ecscmd.created_date,
        ecscmd.updated_by,
        ecscmd.updated_date,
        ecscmd.paper_subject_id,
        ecscmd.groups_id
    FROM
        ec_subject_consolidated_mark_details ecscmd
    WHERE
        1 = 1
        ";
        try {
            $subjectDetails = $this->executeQueryForList($query.$whereQuery.$limitQuery,$this->mapper[StudentExamRegistrationServiceMapper::SEARCH_STUDENT_SUBJECTS_MARK_DETAILS]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch studentRegistration details! Please try again");
        }
        $subjects = [];
        foreach ($subjectDetails as $subject) {
            $subjects[$subject->paperSubjectId] = $subject;
        }
        return $subjects;
    }
    
    /**
     * get Assessment exams
     * @param $request
     * @return $assessments
     */
    public function searchExamAssessments($request)
    {
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        if(!empty($request->examRegId)) {
            $whereQuery .= " AND eerb.ec_exam_registration_id = '$request->examRegId'";
        }
        if(!empty($request->groupId)) {
            $whereQuery .= " AND eerb.groups_id = '$request->groupId'";
        }
        // if($request->startIndex !== "" && $request->endIndex !== "")
        // {
        //     $limitQuery .= " LIMIT $request->startIndex,$request->endIndex";
        // }
        $query = "SELECT DISTINCT
            eers.am_assessment_id AS id,
            aa.name,
            aa.description,
            eerb.groups_id AS batchId
        FROM
            ec_exam_registration_subject eers
        INNER JOIN am_assessment aa ON
            aa.id = eers.am_assessment_id
        INNER JOIN ec_exam_registration_batch eerb ON
            eerb.id = eers.ec_exam_registration_batch_id
        WHERE
            1 = 1
        ";
        try {
            $assessments = $this->executeQueryForList($query.$whereQuery.$limitQuery);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        foreach ($assessments as $assessment) {
            $assessment->text = $assessment->name;
        }
        return $assessments;
    }
    
    /**
     * Search Assessment students
     * @param $request
     * @return $students
     */
    public function searchAssessmentExamStudents($request)
    {
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        $mapperRequest = StudentExamRegistrationServiceMapper::SEARCH_ASSESSMENT_STUDENTS;
        if(!empty($request->assessmentId)) {
            $whereQuery .= " AND aa.id = '$request->assessmentId'";
        }
        if(!empty($request->groupId)) {
            $whereQuery .= " AND aa.identifying_context->>'$.groupId' = '$request->groupId'";
        }
        if(!empty($request->examRegistrationId)) {
            $whereQuery .= " AND aa.identifying_context->>'$.examRegistrationId' = '$request->examRegistrationId'";
        }
        if(!empty($request->paperSubjectId)) {
            $whereQuery .= " AND eers.cm_academic_paper_subjects_id = '$request->paperSubjectId'";
        }
        if(!empty($request->packetNo)) {
            $whereQuery .= " AND esar.valuation_details->>'$.packetNo' = '$request->packetNo'";
            $mapperRequest = StudentExamRegistrationServiceMapper::STUDENTS_WITH_PACKET_DETAILS;
        }
        elseif ($request->packetNotAssignedStudents) {
            $whereQuery .= " AND esar.valuation_details->>'$.packetNo' IS NULL";
            $mapperRequest = StudentExamRegistrationServiceMapper::STUDENTS_WITH_PACKET_DETAILS;
        }
        // if($request->startIndex !== "" && $request->endIndex !== "")
        // {
        //     $limitQuery .= " LIMIT $request->startIndex,$request->endIndex";
        // }
        $query = "SELECT
            esar.id,
            sa.studentName,
            sa.regNo,
            sa.studentID,
            esar.am_assessment_id,
            esar.properties,
            esar.valuation_details,
            esar.properties->>'$.hallticketStatus' AS hallticketStatus,
            esar.properties->>'$.registrationStatus' AS registrationStatus,
            esar.properties->>'$.hallticketBlockedReasons' AS hallticketBlockedReasons,
            esar.properties->>'$.registrationBlockedReasons' AS registrationBlockedReasons,
            esar.trashed,
            FALSE AS edit,
            caps.id AS paperSubjectId,
            s.code AS subjectCode,
            s.name AS subjectName
        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 ec_exam_registration_subject eers ON
            eers.am_assessment_id = aa.id
            AND eers.am_assessment_id = esar.am_assessment_id
        INNER JOIN cm_academic_paper_subjects caps ON
            caps.id = eers.cm_academic_paper_subjects_id
        INNER JOIN v4_ams_subject s ON
            s.id = caps.ams_subject_id
        WHERE
            esar.trashed IS NULL
        ";
        try {
            $students = $this->executeQueryForList($query.$whereQuery.$limitQuery, $this->mapper[StudentExamRegistrationServiceMapper::SEARCH_ASSESSMENT_STUDENTS]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        return $students;
    }
    /**
     * Search Assessment students
     * @param $request
     * @return $students
     */
    public function searchUnassignedAssessmentExamStudents($request)
    {
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        if(!empty($request->groupId)) {
            $whereQuery .= " AND gm.groups_id = '$request->groupId'";
        }
        // if($request->startIndex !== "" && $request->endIndex !== "")
        // {
        //     $limitQuery .= " LIMIT $request->startIndex,$request->endIndex";
        // }
        $query = "SELECT
            esar.id,
            s.studentName,
            s.regNo,
            s.studentID,
            esar.am_assessment_id,
            IF(esar.properties IS NULL ,
                JSON_SET(JSON_OBJECT('registrationStatus', '', 'hallticketStatus', ''), '$.hallticketBlockedReasons', '[]', '$.registrationBlockedReasons', '[]'), esar.properties) AS properties,
            esar.trashed,
            esar.created_by,
            esar.created_date,
            esar.updated_by,
            esar.updated_date,
            FALSE AS edit
        FROM
            group_members gm
        INNER JOIN student_program_account spa ON 
            spa.id  = gm.members->>'$.studentId'
        INNER JOIN studentaccount s ON
            s.studentID = spa.student_id
        LEFT JOIN ec_student_assessment_registration esar ON
            esar.student_id = s.studentID
        LEFT JOIN ec_exam_registration_subject eers ON
            eers.am_assessment_id = esar.am_assessment_id
        WHERE
            esar.id IS NULL 
            AND esar.trashed IS NULL
        ";
        try {
            $students = $this->executeQueryForList($query.$whereQuery.$limitQuery, $this->mapper[StudentExamRegistrationServiceMapper::SEARCH_ASSESSMENT_STUDENTS]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        return $students;
    }
      /**
     * Update student valuation details
     * @param $studentRegistration
     * @return NULL
     */
    public function updateValuationDetails($studentRegistration) {
        if(!empty($studentRegistration->valuationDetails)){
            $studentRegistration->valuationDetails->listStaffs = [];
        }
        $studentRegistration = $this->realEscapeObject($studentRegistration);
        $valuationDetails = !empty($studentRegistration->valuationDetails) ? "'" . json_encode($studentRegistration->valuationDetails) . "'" : "JSON_OBJECT()";
        
        $query = "UPDATE
            ec_student_assessment_registration
        SET
            valuation_details = '$valuationDetails'
        WHERE
            student_id = '$studentRegistration->studentId'
            AND am_assessment_id = '$studentRegistration->assessmentId'";
        try {
            $this->executeQuery($query);
            return;
        } catch (\Exception $e) {
            throw new ECCoreException($e->getCode(), $e->getMessage());
        }
    }
     /**
     * Search packet students
     * @param $request
     * @return $students
     */
    public function searchPacketStudents($request)
    {
        // $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        $mapperRequest = StudentExamRegistrationServiceMapper::SEARCH_ASSESSMENT_STUDENTS;
        $request->assessmentId = stripslashes($request->assessmentId);
        if(!empty($request->assessmentId)) {
            $whereQuery .= " AND aa.id IN ('$request->assessmentId')";
        }
        if(!empty($request->groupId)) {
            $whereQuery .= " AND aa.identifying_context->>'$.groupId' = '$request->groupId'";
        }
        if(!empty($request->examRegistrationId)) {
            $whereQuery .= " AND aa.identifying_context->>'$.examRegistrationId' = '$request->examRegistrationId'";
        }
        if(!empty($request->paperSubjectId)) {
            $whereQuery .= " AND eers.cm_academic_paper_subjects_id = '$request->paperSubjectId'";
        }
        if(!empty($request->hallId)) {
            $whereQuery .= " AND ehagah.ec_exam_hall_id = '$request->hallId'";
        }
        if(!empty($request->packetNo)) {
            $whereQuery .= " AND esar.valuation_details->>'$.packetNo' = '$request->packetNo'";
            $mapperRequest = StudentExamRegistrationServiceMapper::STUDENTS_WITH_PACKET_DETAILS;
        }
        elseif ($request->packetUnAssignedStudents) {
            $whereQuery .= " AND (esar.valuation_details->>'$.packetNo' IS NULL OR esar.valuation_details->>'$.packetNo'='')";
            $mapperRequest = StudentExamRegistrationServiceMapper::STUDENTS_WITH_PACKET_DETAILS;
        }
        $query = "SELECT
            esar.id,
            sa.studentName,
            sa.regNo,
            sa.studentID,
            esar.am_assessment_id,
            esar.properties,
            IF (esar.valuation_details IS NULL, JSON_OBJECT(), esar.valuation_details) AS valuation_details,
            IF (esar.valuation_order_details IS NULL, JSON_OBJECT(), esar.valuation_order_details) AS valuation_order_details,
            IF (esar.valuation_order_details IS NULL, 0, 1) AS isDisabledEdit,
            esar.trashed,
            FALSE AS edit,
            caps.id AS paperSubjectId,
            s.code AS subjectCode,
            s.name AS subjectName
        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 ec_exam_registration_subject eers ON
            eers.am_assessment_id = aa.id
            AND eers.am_assessment_id = esar.am_assessment_id
        INNER JOIN cm_academic_paper_subjects caps ON
            caps.id = eers.cm_academic_paper_subjects_id
        INNER JOIN v4_ams_subject s ON
            s.id = caps.ams_subject_id
        INNER JOIN ec_hall_arrangement_group_assigned_student ehas ON
            esar.student_id = ehas.student_id AND
            aa.id = ehas.am_assessment_id
        INNER JOIN ec_hall_arrangement_group_assigned_hall ehagah ON
            ehagah.id = ehas.ec_hall_arrangement_group_assigned_hall_id
        WHERE
            esar.trashed IS NULL AND esar.properties ->> '$.registrationStatus' = 'REGISTERED' ";
        try {
            $students = $this->executeQueryForList($query.$whereQuery.$limitQuery, $this->mapper[$mapperRequest]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        array_walk($students, function($student) {
            $student->error = "";
            $student->isAlreadyAssigned = true;});
        return $students;
    }
    /**
     * Update Student valuation Details
     * @param $studentRegistration
     * @return NULL
     */
    public function updateStudentRegistrationValidationDetails($studentRegistration)
    {
        if(!empty($studentRegistration->valuationDetails)){
            $studentRegistration->valuationDetails->listStaffs = [];
        }
        $valuationDetails = !empty($studentRegistration->valuationDetails) ? "'" . json_encode($studentRegistration->valuationDetails) . "'" : "JSON_OBJECT()";
            
        $query = "UPDATE ec_student_assessment_registration 
        SET 
            valuation_details = $valuationDetails,
            updated_by = '$studentRegistration->updatedBy'
        WHERE 
            id = '$studentRegistration->id'";
        try {
            $this->executeQuery($query);
            return $studentRegistration->id;
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
    }
       /**
     * Search stduent Exam Registration
     * @param SearchStudentExamRegistrationRequest $request
     * @return examRegistration
     */
    public function getExamRegistrationsForStudentRegistration(SearchStudentExamRegistrationRequest $request){
        $request->mappingType = "EXAM_REGISTRATION";
        $haveImprovement = false;
        $latestExamDetails = new \stdClass;
        $request->isNotConsiderSpecialExam = true;
        $request->notConsiderEmptyValidation = true;
        // this case to check block when regular hall ticket blocking then not able to register the corresponding supply
        // $blockRegularBlockedSubject is enable (SJU) then check any block condition is in corresponding regular ,if any reason founds then student cannot register that subject
        $supplySettingsDetails = CommonService::getInstance()->getSettings(SettingsConstents::SUPPLY_IMPROVE, SettingsConstents::SUPPLY_SETTINGS);
        $minAttendanceForExamReg = json_decode(CommonService::getInstance()->getSettings(SettingsConstents::EXAM_CONTROLLER, SettingsConstents::SEMESTER_EXAM_SETTINGS))->minAttendanceForExamReg;
        $supplySettings = json_decode($supplySettingsDetails);
        $blockRegularBlockedSubject = $supplySettings->blockSubjectIfRegularExamBlocked;
        $searchExamRuleRequest = new SearchRuleRequest;
        $searchExamRuleRequest->name = 'EXAM_REGISTRATION_CREATION_RULE';
        $ruleObj = reset(RuleService::getInstance()->searchRule($searchExamRuleRequest));
        $isShowApplicationForm = false;
        $isShowSubjectSlotInStudentSideExamRegistration = false;
        if($ruleObj){
            $isEnableMinorHonorExamRegistration = $ruleObj->rule->isEnableMinorHonorExamRegistration == '1' ? true : false;
            $isEnableFeeReceiptForAppliedStudents = $ruleObj->rule->isEnableFeeReceiptForAppliedStudents == '1' ? true : false;
            $isShowApplicationForm = $ruleObj->rule->isShowApplicationForm == '1' ? true : false;
            $isShowSubjectSlotInStudentSideExamRegistration = $ruleObj->rule->isShowSubjectSlotInStudentSideExamRegistration == '1' ? true : false;
        }
        $studentDetails = AmStudentService::getInstance()->getStudentBasicDetails($request->studentId);
        if ($supplySettings->supplyRedirectionToV3RegisterNoStarting && $request->examType == ExamRegistrationTypeConstants::SUPPLEMENTARY ) {
            if (in_array(substr($studentDetails->properties->registerNumber, 0, 2), $supplySettings->supplyRedirectionToV3RegisterNoStarting )) {
                $studentExamRegistrationDetails = new \stdClass;
                $studentExamRegistrationDetails->supplyRedirectionToV3 = 1;
                $studentExamRegistrationDetails->examRegistrations = [];
                $studentExamRegistrationDetails->v3CollegeUrl = $supplySettings->v3CollegeUrl;
                $studentExamRegistrationDetails->studentEmail = $studentDetails->email;
                $studentExamRegistrationDetails->specialExamRegistrations = [];
                return $studentExamRegistrationDetails;
            }
        }
        $request->isEnableMinorHonorExamRegistration = $isEnableMinorHonorExamRegistration;
        $searchRuleRequest = new SearchRuleRequest;
        $searchRuleRequest->name = "HALL_TICKET_STUDENT_SIDE";
        $hallTicketRule = reset(RuleService::getInstance()->searchRule($searchRuleRequest));
        $enableHallticketStudentSide = $hallTicketRule->rule->enableHallTicket ? true : false;
        $showExamRegReceiptSettingsJSON = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, SettingsConstants::ENABLE_EXAM_REGISTRATION_RECEIPT);
        $showExamRegReceipt = json_decode($showExamRegReceiptSettingsJSON)->enableReceiptRegular;
        $showAppliedSubjectsInExamReg = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, SettingsConstants::SHOW_APPLIED_SUBJECTS_IN_EXAM_REGISTRATION);
        $examRegistrations = $this->getStudentExamRegistrationFeeDetails($request);
        $specialExamRegistrations = $this->getStudentSpecialExamRegistrationFeeDetails($request);
        $regularExamSettings = CommonService::getInstance()->getSettings(SettingsConstents::REGULAR_EXAM, SettingsConstents::STUDENT_REGULAR_EXAM_REGISTRATION);
        $regularExamSettings = json_decode($regularExamSettings);
        if($regularExamSettings->requireAbcIdForRegistration && !$studentDetails->abcId){
            $studentDetails->blockAllRegistrationsWithNote = true;
            $studentDetails->blockAllRegistrationsMsg = "Please update your ABC Account ID to register for exams.";
        }
        if($request->examType == ExamRegistrationTypeConstants::SUPPLEMENTARY){
            $examRegistrationCopy = $examRegistrations;
            $isNearByPassedExamAsImprovement = false;
            $isImprovementOnlyForRegularPassed = false;
            $improvementArray = ["SUPPLY_IMPROVEMENT","IMPROVEMENT"];
            foreach ($examRegistrationCopy as $examRegistration) {
                if(in_array($examRegistration->examRegistrationProperties->examRegistrationType, $improvementArray)){
                    $haveImprovement = true;
                }
                $isCombineSupplyOrImprovement = $examRegistration->examRegistrationProperties->combinedExamRegistration == '1' ? true : false;
                $groupId = $examRegistration->groupId;
                $searchRequest = new \stdClass;
                $searchRequest->groupId = $groupId;
                $searchRequest->academicTermId = $examRegistration->academicTermId;
                $searchRequest->type =ExamRegistrationTypeConstants::SUPPLEMENTARY;
                $searchRequest->odrerBy = "ASSENDING_EXAM_MONTH_AND_YEAR";
                $allSupplementaryExamRegistrations = ExamRegistrationService::getInstance()->searchExamRegistrationByOtherDetails($searchRequest);
                $regularOrSupply = ["REGULAR","SUPPLEMENTARY"];
                $regularOrSupplyForPassed = $isImprovementOnlyForRegularPassed ? ["REGULAR"] : ["REGULAR","SUPPLEMENTARY"];
                $examRegistration->supplyImproveTreatedAs = "NOTHING";
                $latestExamYearAndMonth = max(array_map(function($history){ return $history->examYear."-".date("m", mktime(0, 0, 0, (int)$history->examMonth, 10));},$examRegistration->semesterMarkHistory));
                foreach($examRegistration->semesterMarkHistory as $history){
                    $examMonth = date("m", mktime(0, 0, 0, (int)$history->examMonth, 10));
                    if($history->examYear.'-'.$examMonth ==  $latestExamYearAndMonth){
                        $latestExamDetails = $history;
                        break; 
                    }
                }
                if($latestExamDetails->failedStatus == "PASSED" && in_array($latestExamDetails->historyType, $regularOrSupplyForPassed) && $haveImprovement){
                    $countExamRegistrations = 0;
                    foreach( $allSupplementaryExamRegistrations as $supplyExam){
                        if($supplyExam->properties->examYear."-".date("m", mktime(0, 0, 0, (int)$supplyExam->properties->examMonth, 10)) > $latestExamYearAndMonth){
                            $countExamRegistrations ++;
                            if($supplyExam->id == $examRegistration->id){
                                foreach($examRegistration->subjects as $subject){
                                    if($isNearByPassedExamAsImprovement){ 
                                        if(in_array($subject->subjectMarkDetails->latestExamType, $regularOrSupplyForPassed) && $countExamRegistrations == 1 ){
                                            $passedMonthAndYear = $subject->subjectMarkDetails->latestExamYear."-".date("m", mktime(0, 0, 0, (int)$subject->subjectMarkDetails->latestExamMonth, 10));
                                            if($passedMonthAndYear ==  $latestExamYearAndMonth){
                                                $subject->supplyOrImprovement = ExamRegistrationTypeConstants::IMPROVEMENT;
                                                $examRegistration->supplyImproveTreatedAs = ExamRegistrationTypeConstants::IMPROVEMENT;
                                            }
                                            else{
                                                $subject->supplyOrImprovement = "NOTHING";
                                            }
                                        }
                                        else{
                                            $subject->supplyOrImprovement = "NOTHING";
                                        }
                                    }
                                    else{
                                        $subject->supplyOrImprovement = ExamRegistrationTypeConstants::IMPROVEMENT;
                                        $examRegistration->supplyImproveTreatedAs = ExamRegistrationTypeConstants::IMPROVEMENT;
                                    }
                                }
                                break;
                            } 
                        }
                    }
                }
                elseif($latestExamDetails->failedStatus == "FAILED" && in_array($latestExamDetails->historyType, $regularOrSupply)){
                    $countExamRegistrations = 0;
                    if($isCombineSupplyOrImprovement && $haveImprovement){
                        foreach( $allSupplementaryExamRegistrations as $supplyExam){
                            if($supplyExam->properties->examYear."-".date("m", mktime(0, 0, 0, (int)$supplyExam->properties->examMonth, 10)) > $latestExamYearAndMonth){
                                $countExamRegistrations ++;
                                if($supplyExam->id == $examRegistration->id){
                                    $examRegistration->supplyImproveTreatedAs = ExamRegistrationTypeConstants::SUPPLEMENTARY;
                                    foreach($examRegistration->subjects as $subject){
                                        if($subject->subjectFailedStatus == "FAILED"){
                                            $subject->supplyOrImprovement = ExamRegistrationTypeConstants::SUPPLEMENTARY;
                                        }
                                        else{
                                            if($isNearByPassedExamAsImprovement){
                                                if(in_array($subject->subjectMarkDetails->latestExamType, $regularOrSupplyForPassed) && $countExamRegistrations == 1 ){
                                                    $passedMonthAndYear = $subject->subjectMarkDetails->latestExamYear."-".date("m", mktime(0, 0, 0, (int)$subject->subjectMarkDetails->latestExamMonth, 10));
                                                    if($passedMonthAndYear ==  $latestExamYearAndMonth){
                                                        $subject->supplyOrImprovement = ExamRegistrationTypeConstants::IMPROVEMENT;
                                                        $examRegistration->supplyImproveTreatedAs = "SUPPIMENTARY/IMPROVEMENT";
                                                    }
                                                    else{
                                                        $subject->supplyOrImprovement = "NOTHING";
                                                    }
                                                }
                                                else{
                                                    $subject->supplyOrImprovement = "NOTHING";
                                                }
                                                
                                             }
                                            else{
                                                $subject->supplyOrImprovement = ExamRegistrationTypeConstants::IMPROVEMENT;
                                                $examRegistration->supplyImproveTreatedAs = "SUPPIMENTARY/IMPROVEMENT";
                                            }
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    else{
                        foreach( $allSupplementaryExamRegistrations as $supplyExam){
                            if($supplyExam->properties->examYear."-".date("m", mktime(0, 0, 0, (int)$supplyExam->properties->examMonth, 10)) > $latestExamYearAndMonth){
                                if($supplyExam->id != $examRegistration->id){
                                    $examRegistration->supplyImproveTreatedAs = ExamRegistrationTypeConstants::SUPPLEMENTARY;
                                    if(($key = array_search('FAILED', array_column($examRegistration->subject,'subjectFailedStatus'))) !== FALSE) {
                                        unset($examRegistration->subject[$key]);
                                    }
                                    foreach($examRegistration->subjects as $subject){
                                        $subject->supplyOrImprovement = ExamRegistrationTypeConstants::SUPPLEMENTARY;
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
            }
            foreach ($examRegistrationCopy as $examRegistration) {
                if($examRegistration->supplyImproveTreatedAs == "NOTHING"){
                    $examRegistration->isBlocked = true;
                    $examRegistration->blockReasons = ["Can't Register"]; 
                }
                $examRegistration->subjects = (array_filter($examRegistration->subjects,function($value){
                    return $value->supplyOrImprovement != "NOTHING";
                }));
            }
        }
        $assignedHalls = $this->getStudentAssignedHallsForExam($request);
        foreach ($examRegistrations as $examRegistration) {
            $maxEndDate = "";
            $academicPaperSubjectBlocking = [];
            if($request->examType == ExamRegistrationTypeConstants::SUPPLEMENTARY){
                if($blockRegularBlockedSubject){
                    $regularBlockReasons = [];
                    // fetch regular blocked reasons
                    $regularExamBlockedReasonRequest = new \stdClass;
                    $regularExamBlockedReasonRequest->academicPaperSubjectId = [];
                    $regularExamBlockedReasonRequest->examRegistrationId = "";
                    $regularExamBlockedReasonRequest->studentId = $request->studentId;
                    // this case to fetch only  subject wise ( block reason) & Hall ticket blocking (blocking type)
                    // because blocking will be done only after student registration for regular exam, so blocking method will be hall ticket blocking, block reason type is subject wise
                    $regularExamBlockedReasonRequest->blockingType = 'HALL_TICKET_BLOCKING';
                    $regularExamBlockedReasonRequest->blockReasonType = 'SUBJECT_WISE';
                    // fetch the corresponding regular exam id 
                    $getRegularExamIdReg = new \stdClass;
                    $getRegularExamIdReg->examRegistrationId =  $examRegistration->examRegistrationId;
                    $getRegularExamIdReg->groupId =  $examRegistration->groupId;
                    $regularExamBlockedReasonRequest->examRegistrationId = ExamRegistrationService::getInstance()->getRegularExamRegistrationIdBySupplyExamRegistrationId($getRegularExamIdReg);
                    $regularExamBlockedReasonRequest->academicPaperSubjectId = array_column($examRegistration->subjects,'academicPaperSubjectId');
                    if(!empty($regularExamBlockedReasonRequest->academicPaperSubjectId) && !empty( $regularExamBlockedReasonRequest->examRegistrationId)){
                        $regularBlockReasons = BlockStudentMappingService::getInstance()->getStudentBlockReasonsDetails($regularExamBlockedReasonRequest);
                        foreach($regularBlockReasons as $regularBlockReason){
                            $academicPaperSubjectBlocking[$regularBlockReason->academicPaperSubjectId]->blockReasons[$regularBlockReason->blockReasonId] = $regularBlockReason;
                        }
                    }
                }
            }
            $blockedUnblockedSubjects = [];
            $requestForBlkUnblkSubjects = new \stdClass;
            $requestForBlkUnblkSubjects->studentId = $request->studentId;
            $requestForBlkUnblkSubjects->examRegistrationId = $examRegistration->id;
            $blockedUnblockedSubjects = $this->getBlockedUnblockedSubjectDetails($requestForBlkUnblkSubjects);
            $examRegistration->isEnableFeeReceiptForAppliedStudents = $isEnableFeeReceiptForAppliedStudents;
            $examRegistration->isApplied = false;
            $examRegistration->isBlocked = false;
            $examRegistration->isRegistered = false;
            $examRegistration->canRegister = true;
            $examRegistration->blockReasons = [];
            $examRegistration->paymentStatus = "Not Paid";
            $examRegistration->status = "Not Registered";
            $examRegistration->blockedSubjectCount = 0;
            if(count($examRegistration->batchFeeFine) > 1){
                $examRegistration->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($examRegistration);
            }
            else{
                $examRegistration->currentBatchCommonFeeFine = reset($examRegistration->batchFeeFine);
            }
            $examRegistration->commonFines = []; 
            $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
            $examRegistrationCommonFines = reset(array_filter($examRegistration->currentBatchCommonFeeFine->batchCommonFines,function($value)use($examRegistration){
                return $value->examRegistrationType == $examRegistration->examRegistrationType;
            }));
            $studentCommonFineIdsArray = array_keys((array)$examRegistrationCommonFines->fineType);
            $examRegistrationCommonFines->fineType = (array)$examRegistrationCommonFines->fineType;
            $today = date("Y-m-d H:i");
            // $maxEndDate = $examRegistration->examRegistrationProperties->registrationWithoutFineEndDate ? $examRegistration->examRegistrationProperties->registrationWithoutFineEndDate : '';
            foreach($allCommonFines as $commonFine){
                if ( in_array ( $commonFine->id, $studentCommonFineIdsArray ) ) {
                    $maxEndDate = $maxEndDate ?? $examRegistrationCommonFines->fineType[$commonFine->id]->endDate;
                    $minStartDate = $minStartDate ?? $examRegistrationCommonFines->fineType[$commonFine->id]->startDate;
                    if(strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($maxEndDate)){
                        $maxEndDate = $examRegistrationCommonFines->fineType[$commonFine->id]->endDate;
                    }
                    if(strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($minStartDate)){
                        $minStartDate = $examRegistrationCommonFines->fineType[$commonFine->id]->startDate;
                    }
                    if($examRegistration->examRegistrationPaymentProperties->challanAppliedDate){
                        if(strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($examRegistration->examRegistrationPaymentProperties->challanAppliedDate) && strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($examRegistration->examRegistrationPaymentProperties->challanAppliedDate) ){
                            $challanVerificationDate = $examRegistrationCommonFines->fineType[$commonFine->id]->verificationDate;
                            
                        }
                    }
                }
            }
            $examRegistration->isChallanExperied = true;
            if($challanVerificationDate && strtotime($challanVerificationDate) >= strtotime($today)){
                $examRegistration->isChallanExperied = false;
            }
            $examRegistration->registrationStartDate = $minStartDate;
            $examRegistration->registrationEndDate = $maxEndDate;
            $subjectPaymentMethod = "";
            foreach($examRegistration->subjects as $subject){
                $subject->isBlocked = false;
                $subject->hallName = $assignedHalls[$subject->assessmentId]->name;
                $subject->blockStudentTableId = $blockedUnblockedSubjects[$subject->academicPaperSubjectId] ? $blockedUnblockedSubjects[$subject->academicPaperSubjectId]->blockStudentTableId : null;
                $subject->unBlockStudentTableId = $blockedUnblockedSubjects[$subject->academicPaperSubjectId] ? $blockedUnblockedSubjects[$subject->academicPaperSubjectId]->unBlockStudentTableId : null;
                if($subject->blockStudentTableId  && !$subject->unBlockStudentTableId){
                    $subject->isBlocked = true;
                    $subject->blockReasons = ['Malpractice'];
                    $examRegistration->blockedSubjectCount ++;
                }
                // this case to check block when regular hall ticket blocking then not able to register the corresponding supply
                if(!empty($academicPaperSubjectBlocking[$subject->academicPaperSubjectId])) {
                    $blockReasons = [];
                    $blockReasons = $academicPaperSubjectBlocking[$subject->academicPaperSubjectId]->blockReasons;
                    $blockReasonNames = array_column( $blockReasons,'blockReasonName');
                    $subject->isBlocked = true;
                    $subject->blockReasons =  $blockReasonNames;
                    $examRegistration->blockedSubjectCount ++;
                }
                if($examRegistration->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SUBJECT_WISE'){
                    $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
                    $attendanceTermWiseReportRequest->studentId = $examRegistration->studentId;
                    $attendanceTermWiseReportRequest->termId = $examRegistration->academicTermId;
                    $attendanceTermWiseReportRequest->paperSubjectId = $subject->academicPaperSubjectId;
                    $subject->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
                    if($subject->properties->minimumAttendancePercentage > $subject->attendanceDetails->attendancePercentage){
                        if ( $subject->studentAssessmentRegistrationProperties->registrationStatus != StudentExamRegistrationStatus::APPLIED  && $subject->studentAssessmentRegistrationProperties->registrationStatus != StudentExamRegistrationStatus::REGISTERED ){
                            $subject->isBlocked = true;
                            $subject->blockReasons = ['Attendance Shortage'];
                            $examRegistration->blockedSubjectCount ++;
                        }
                    }
                }
                $subject->isApplied = false;
                if($subject->studentAssessmentRegistrationId && $subject->studentAssessmentRegistrationProperties){
                    $subject->paymentStatus = $subject->studentAssessmentRegistrationProperties->feeStatus;
                    $subject->status = $subject->studentAssessmentRegistrationProperties->registrationStatus;
                    if(($subject->paymentStatus == StudentExamRegistrationPaymentStatus::PAID || $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING || $subject->paymentStatus == StudentExamRegistrationPaymentStatus::FAILED  ) && ($subject->status == StudentExamRegistrationStatus::REGISTERED || $subject->status == StudentExamRegistrationStatus::APPLIED)){
                        $subject->isRegistered = $subject->status == StudentExamRegistrationStatus::REGISTERED ? true : false;
                        if(!$examRegistration->isRegistered){
                            $examRegistration->paymentStatus = $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PAID ? "Paid" : "Pending";
                            $examRegistration->status = $subject->status == StudentExamRegistrationStatus::REGISTERED ? "Registered" : "Applied";
                            $subjectPaymentMethod = $subject->studentAssessmentRegistrationProperties->paymentOption ? $subject->studentAssessmentRegistrationProperties->paymentOption : $subjectPaymentMethod;
                            $examRegistration->isRegistered = $subject->status == StudentExamRegistrationStatus::REGISTERED ? true : false;
                            $examRegistration->isApplied = !$examRegistration->isApplied && $subject->status == StudentExamRegistrationStatus::APPLIED ? true : $examRegistration->isApplied;
                            $examRegistration->isReApply = $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING ? true : false;
                            $examRegistration->isCheckPaymentStatus = !$examRegistration->isCheckPaymentStatus && $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING ? true : $examRegistration->isCheckPaymentStatus;
                            if ($subject->paymentStatus == StudentExamRegistrationPaymentStatus::FAILED && $subject->status == StudentExamRegistrationStatus::APPLIED && $examRegistration->examRegistrationPaymentProperties->paymentOption ==  ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD) {
                                $examRegistration->isAppliedButPaymentFailed = true;
                            }
                            if($examRegistration->examRegistrationType == 'REGULAR'){
                                $examRegistration->canRegister = $examRegistration->canRegister && $examRegistration->isRegistered ? false : true;
                            }
                        }
                        else{ 
                            if($examRegistration->examRegistrationType == 'SUPPLEMENTARY'){
                                $examRegistration->isApplied = !$examRegistration->isApplied && $subject->status == StudentExamRegistrationStatus::APPLIED ? true : $examRegistration->isApplied;
                                $examRegistration->isCheckPaymentStatus = !$examRegistration->isCheckPaymentStatus && $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING ? true : $examRegistration->isCheckPaymentStatus;
                            }
                            else{
                                $examRegistration->isReApply = false;
                                $examRegistration->isCheckPaymentStatus = false;
                            }                   
                            if($examRegistration->examRegistrationType == 'REGULAR'){
                                $examRegistration->canRegister = false;
                            }
                        }
                        $subject->isApplied = true;
                    }
                    else{
                        $subject->isApplied = false;
                    }
                    
                }
                else{
                    $subject->isApplied = false;
                }
            }
            if($subjectPaymentMethod ==  ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD && ( $examRegistration->isApplied) && !$examRegistration->isAppliedButPaymentFailed ){
                $searchRequestForPayment = new \stdClass;
                $searchRequestForPayment->studentId = $examRegistration->studentId;
                $searchRequestForPayment->examRegistrationId = $examRegistration->examRegistrationId;
                $studentPaymentStatusDetails = $this->searchStudentOnlinePayement($searchRequestForPayment);
                if(empty($studentPaymentStatusDetails)){
                    $examRegistration->isAppliedButPaymentFailed = true;
                }
                else{
                    $studentRecentPaymentPendingStatus = reset(array_filter($studentPaymentStatusDetails,function($value){
                        return $value->status == "PENDING";
                    }));
                    if(empty($studentRecentPaymentPendingStatus)){
                        $examRegistration->isAppliedButPaymentFailed = true;
                    }
                }
            }
            if ( $examRegistration->isAppliedButPaymentFailed ){
                $examRegistration->canRegister = true;
            }
            
            if (strtotime($minStartDate) > strtotime(date("Y-m-d H:i"))) {
                $examRegistration->isBlocked = true;
                $examRegistration->canRegister = false;
                $examRegistration->isNotStarted = true;
                $examRegistration->blockReasons = ["Registration not started"];
            }
            elseif (strtotime($maxEndDate)  < strtotime(date("Y-m-d H:i"))) {
                $examRegistration->isClosed = true;
                $examRegistration->isBlocked = true;
                $examRegistration->canRegister = false;
                $examRegistration->blockReasons = ["Registration closed"];
            }
            else if($examRegistration->examRegistrationPaymentProperties->paymentOption ==  ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD &&  ($examRegistration->examRegistrationType == 'REGULAR' || $examRegistration->examRegistrationType == 'SUPPLEMENTARY' ) && ( $examRegistration->isApplied || $examRegistration->isRegistered ) && !$examRegistration->isChallanExperied){
                $examRegistration->canRegister = false;
            }
            else if($examRegistration->examRegistrationPaymentProperties->paymentOption !=  ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD &&  ($examRegistration->examRegistrationType == 'REGULAR' || $examRegistration->examRegistrationType == 'SUPPLEMENTARY' ) && ( $examRegistration->isApplied || $examRegistration->isRegistered ) && !$examRegistration->isAppliedButPaymentFailed ){
                $examRegistration->canRegister = false;
            }
            $examRegistration->paymentOption =   $examRegistration->examRegistrationPaymentProperties->paymentOption;
            if($examRegistration->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SEMESTER_WISE'){
                if($minAttendanceForExamReg->enableDayWiseAttendanceChecking){
                    $semWiseRequest = new \stdClass;
                    $semWiseRequest->studentId = $request->studentId;
                    $semWiseRequest->termId = $examRegistration->academicTermId;
                    $semWiseRequest->examRegistrationId = $examRegistration->examRegistrationId;
                    $semWiseRequest->studentGender = $examRegistration->studentGender;
                    $semWiseRequest->workFlowId = $examRegistration->examRegistrationProperties->workFlowId;
                    $semWiseCriteria = ProfessionalCommonExamService::getInstance()->checkStudentSemesterWiseAttendanceCriteriaForExamRegistration($semWiseRequest);
                    if ( $semWiseCriteria->workflowId && $semWiseCriteria->eligibleForCondonation && !$semWiseCriteria->eligibleToApplyByDayWiseAttendance && !$examRegistration->isApplied && !$examRegistration->isRegistered){
                        $examRegistration->redirectToWorkFlowModule = 1;
                    }
                    if ( !$semWiseCriteria->eligibleToApplyByDayWiseAttendance && !$semWiseCriteria->isCondonationApproved){
                        $examRegistration->canRegister = false;
                        $examRegistration->blockReasons = ['Attendance Shortage'];
                    }
                }
                else{
                    $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
                    $attendanceTermWiseReportRequest->studentId = $examRegistration->studentId;
                    $attendanceTermWiseReportRequest->termId = $examRegistration->academicTermId;
                    $examRegistration->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
                    if($examRegistration->examRegistrationProperties->minimumAttendancePercentage > $examRegistration->attendanceDetails->attendancePercentage){
                        $examRegistration->canRegister = false;
                        $examRegistration->blockReasons = ['Attendance Shortage'];
                    }
                }
            }
            if($examRegistration->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SUBJECT_WISE'){
                if(count($examRegistration->subjects) == $examRegistration->blockedSubjectCount){
                    $condonationStatus = $examRegistration->examRegistrationProperties->workFlowId ? ProfessionalCommonExamService::getInstance()->getStatusOfWorkflowRequest($request->studentId, $examRegistration->academicTermId,$examRegistration->examRegistrationProperties->workFlowId) : '';
                    if($condonationStatus != 'APPROVED'){
                        $examRegistration->canRegister = false;
                        $examRegistration->blockReasons = ['Attendance Shortage'];
                    }
                }
            }
            if($examRegistration->examRegistrationProperties->enableHallTicketExamStudent && $enableHallticketStudentSide){
                $examRegistration->isShowHallTicket = $examRegistration->isRegistered ? true : false;
            }
            // sort the subject by academics order
            usort($examRegistration->subjects, function ($a, $b) {
                return $a->subjectPriority > $b->subjectPriority;
            });
            // this case handle for when student failed in transaction show the details in student side 
            $examRegistration->isPreviouslyFailedInPayment = false;
            if(($examRegistration->isApplied == false) && ($examRegistration->isRegistered == false) && ($examRegistration->canRegister == true)){
                $studentPaymentStatusDetails = [];
                $searchRequestForPayment = new \stdClass;
                $searchRequestForPayment->studentId = $examRegistration->studentId;
                $searchRequestForPayment->examRegistrationId = $examRegistration->examRegistrationId;
                $studentPaymentStatusDetails = $this->searchStudentOnlinePayement($searchRequestForPayment);
                $examRegistration->isPreviouslyFailedInPayment = empty($studentPaymentStatusDetails) ? false : true;
            }
            if ( $examRegistration->isAppliedButPaymentFailed ){
                $examRegistration->isPreviouslyFailedInPayment = true;
            }
            //BLOCK EXAM REG BY SHOWING AN ALERT NOTE ON TOP
            if($studentDetails->blockAllRegistrationsWithNote){
                // $examRegistration->canRegister = false;
                //common alert with this message will be showed on top 
                $examRegistration->alertMsgOnRegistrationView = $studentDetails->blockAllRegistrationsMsg;
                //show error msg toaster on register button click
                $examRegistration->blockRegistrationWithToaster = true;
                $examRegistration->blockRegistrationToasterMsg = $studentDetails->blockAllRegistrationsMsg;
            }
        }
        foreach ($specialExamRegistrations as $examRegistration) {
            $maxEndDate = "";
            $examRegistration->isSpecialExam = true;
            $examRegistration->isApplied = false;
            $examRegistration->isBlocked = false;
            $examRegistration->isRegistered = false;
            $examRegistration->canRegister = true;
            $examRegistration->blockReasons = [];
            $examRegistration->paymentStatus = "Not Paid";
            $examRegistration->status = "Not Registered";
            $examRegistration->blockedSubjectCount = 0;
            if(count($examRegistration->batchFeeFine) > 1){
                $examRegistration->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($examRegistration);
            }
            else{
                $examRegistration->currentBatchCommonFeeFine = reset($examRegistration->batchFeeFine);
            }
            $examRegistration->commonFines = []; 
            $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
            $examRegistrationCommonFines = reset(array_filter($examRegistration->currentBatchCommonFeeFine->batchCommonFines,function($value)use($examRegistration){
                return $value->examRegistrationType == $examRegistration->examRegistrationType;
            }));
            $studentCommonFineIdsArray = array_keys((array)$examRegistrationCommonFines->fineType);
            $examRegistrationCommonFines->fineType = (array)$examRegistrationCommonFines->fineType;
            $today = date("Y-m-d H:i");
            // $maxEndDate = $examRegistration->examRegistrationProperties->registrationWithoutFineEndDate ? $examRegistration->examRegistrationProperties->registrationWithoutFineEndDate : '';
            foreach($allCommonFines as $commonFine){
                if ( in_array ( $commonFine->id, $studentCommonFineIdsArray ) ) {
                    $maxEndDate = $maxEndDate ?? $examRegistrationCommonFines->fineType[$commonFine->id]->endDate;
                    $minStartDate = $minStartDate ?? $examRegistrationCommonFines->fineType[$commonFine->id]->startDate;
                    if(strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($maxEndDate)){
                        $maxEndDate = $examRegistrationCommonFines->fineType[$commonFine->id]->endDate;
                    }
                    if(strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($minStartDate)){
                        $minStartDate = $examRegistrationCommonFines->fineType[$commonFine->id]->startDate;
                    }
                    if($examRegistration->examRegistrationPaymentProperties->challanAppliedDate){
                        if(strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($examRegistration->examRegistrationPaymentProperties->challanAppliedDate) && strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($examRegistration->examRegistrationPaymentProperties->challanAppliedDate) ){
                            $challanVerificationDate = $examRegistrationCommonFines->fineType[$commonFine->id]->verificationDate;
                            
                        }
                    }
                }
            }
            $examRegistration->isChallanExperied = true;
            if($challanVerificationDate && strtotime($challanVerificationDate) >= strtotime($today)){
                $examRegistration->isChallanExperied = false;
            }
            $examRegistration->registrationStartDate = $minStartDate;
            $examRegistration->registrationEndDate = $maxEndDate;
            foreach($examRegistration->subjects as $subject){
                $subject->isBlocked = false;
                
                $subject->isApplied = false;
                $subject->hallName = $assignedHalls[$subject->assessmentId]->name;
                if($subject->studentAssessmentRegistrationId && $subject->studentAssessmentRegistrationProperties){
                    $subject->paymentStatus = $subject->studentAssessmentRegistrationProperties->feeStatus;
                    $subject->status = $subject->studentAssessmentRegistrationProperties->registrationStatus;
                    if(($subject->paymentStatus == StudentExamRegistrationPaymentStatus::PAID || $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING)&& ($subject->status == StudentExamRegistrationStatus::REGISTERED || $subject->status == StudentExamRegistrationStatus::APPLIED)){
                        $subject->isRegistered = $subject->status == StudentExamRegistrationStatus::REGISTERED ? true : false;
                        if(!$examRegistration->isRegistered){
                            $examRegistration->paymentStatus = $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PAID ? "Paid" : "Pending";
                            $examRegistration->status = $subject->status == StudentExamRegistrationStatus::REGISTERED ? "Registered" : "Applied";
                            $examRegistration->isRegistered = $subject->status == StudentExamRegistrationStatus::REGISTERED ? true : false;
                            $examRegistration->isApplied = !$examRegistration->isApplied && $subject->status == StudentExamRegistrationStatus::APPLIED ? true : $examRegistration->isApplied;
                            $examRegistration->isReApply = $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING ? true : false;
                            $examRegistration->isCheckPaymentStatus = !$examRegistration->isCheckPaymentStatus && $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING ? true : $examRegistration->isCheckPaymentStatus;
                            if($examRegistration->examRegistrationType == 'REGULAR'){
                                $examRegistration->canRegister = $examRegistration->canRegister && $examRegistration->isRegistered ? false : true;
                            }
                        }
                        else{ 
                            if($examRegistration->examRegistrationType == 'SUPPLEMENTARY'){
                                $examRegistration->isApplied = !$examRegistration->isApplied && $subject->status == StudentExamRegistrationStatus::APPLIED ? true : $examRegistration->isApplied;
                                $examRegistration->isCheckPaymentStatus = !$examRegistration->isCheckPaymentStatus && $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING ? true : $examRegistration->isCheckPaymentStatus;
                            }
                            else{
                                $examRegistration->isReApply = false;
                                $examRegistration->isCheckPaymentStatus = false;
                            }                   
                            if($examRegistration->examRegistrationType == 'REGULAR'){
                                $examRegistration->canRegister = false;
                            }
                        }
                        $subject->isApplied = true;
                    }
                    else{
                        $subject->isApplied = false;
                    }
                    
                }
                else{
                    $subject->isApplied = false;
                }
            }
            if (strtotime($minStartDate) > strtotime(date("Y-m-d H:i"))) {
                $examRegistration->isBlocked = true;
                $examRegistration->canRegister = false;
                $examRegistration->isNotStarted = true;
                $examRegistration->blockReasons = ["Registration not started"];
            }
            elseif (strtotime($maxEndDate)  < strtotime(date("Y-m-d H:i"))) {
                $examRegistration->isClosed = true;
                $examRegistration->isBlocked = true;
                $examRegistration->canRegister = false;
                $examRegistration->blockReasons = ["Registration closed"];
            }
            else if($examRegistration->examRegistrationPaymentProperties->paymentOption ==  ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD &&  $examRegistration->examRegistrationType == 'REGULAR' && ( $examRegistration->isApplied || $examRegistration->isRegistered ) && !$examRegistration->isChallanExperied){
                $examRegistration->canRegister = false;
            }
            $examRegistration->paymentOption =   $examRegistration->examRegistrationPaymentProperties->paymentOption;
            if($examRegistration->examRegistrationProperties->enableHallTicketExamStudent && $enableHallticketStudentSide){
                $examRegistration->isShowHallTicket = $examRegistration->isRegistered ? true : false;
            }
            // this case handle for when student failed in transaction show the details in student side 
            $examRegistration->isPreviouslyFailedInPayment = false;
            if(($examRegistration->isApplied == false) && ($examRegistration->isRegistered == false) && ($examRegistration->canRegister == true)){
                $studentPaymentStatusDetails = [];
                $searchRequestForPayment = new \stdClass;
                $searchRequestForPayment->studentId = $examRegistration->studentId;
                $searchRequestForPayment->examRegistrationId = $examRegistration->examRegistrationId;
                $studentPaymentStatusDetails = $this->searchStudentOnlinePayement($searchRequestForPayment);
                $examRegistration->isPreviouslyFailedInPayment = empty($studentPaymentStatusDetails) ? false : true;
            }
        }
        $studentExamRegistrationDetails = new \stdClass;
        $studentExamRegistrationDetails->enableHallticketStudentSide = $enableHallticketStudentSide;
        $studentExamRegistrationDetails->showExamRegReceipt = $showExamRegReceipt;
        $studentExamRegistrationDetails->showAppliedSubjectsInExamReg = $showAppliedSubjectsInExamReg;
        $studentExamRegistrationDetails->examRegistrations = $examRegistrations;
        $studentExamRegistrationDetails->specialExamRegistrations = $specialExamRegistrations;
        $studentExamRegistrationDetails->isShowApplicationForm = $isShowApplicationForm;
        $studentExamRegistrationDetails->isShowSubjectSlotInStudentSideExamRegistration = $isShowSubjectSlotInStudentSideExamRegistration;
        return $studentExamRegistrationDetails;
    }
    
     /**
     * Search stduent Regular Exam Registration
     * @param $request
     * @return studentDetails
     */
    public function getStudentExamRegistrationSubjectFeeDetails($request){
        if($request->examRegistrationType == ExamRegistrationTypeConstants::SUPPLEMENTARY){
            if($request->academicPaperSubjectId || $request->featchAllFees){
                $request->featchAllFees = true;
            }
            if($request->isSpecialExam == '1'){
                $studentDetails = $this->getStudentSpecialExamRegistrationSubjectFeeDetails($request);
            }
            else{
                $studentDetails = $this->getStudentSupplementaryExamRegistrationSubjectFeeDetails($request);
            }
        }
        else{
            if($request->isMinorHonourExamRegistration){
                $studentDetails = $this->getStudentRegularMinorHonourExamRegistrationSubjectFeeDetails($request);
            }
            else{
                $studentDetails = $this->getStudentRegularExamRegistrationSubjectFeeDetails($request);
            }
        }
        return($studentDetails);
    }
     /**
     * Search stduent Regular Exam Registration
     * @param $request
     * @return examRegistration
     */
    public function getStudentRegularExamRegistrationSubjectFeeDetails($request){
        $searchRequest = new \stdClass;
        $searchRequest->studentId = $request->studentId;
        $studentCommonFeesIdsArray = [];
        $studentCommonFineIdsArray = [];
        $searchRequest->academicPaperSubjectId = $request->academicPaperSubjectId;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->registrationStatus =  $request->registrationStatus;
        $searchRequest->notConsiderEmptyValidation =  $request->notConsiderEmptyValidation;
        $searchRequest->considerEmptyReturn =  $request->considerEmptyReturn;
        $searchRequest->considerRegisteredAndApplied =  $request->considerRegisteredAndApplied;
        $studentDetails = reset($this->getStudentExamRegistrationFeeDetails($searchRequest));
        if($request->considerRegisteredAndApplied){
            $registeredSearchRequest = new \stdClass;
            $registeredSearchRequest->studentId = $request->studentId;
            $registeredSearchRequest->examRegistrationId = $request->examRegistrationId;
            $registeredSearchRequest->registrationStatus =  "REGISTERED_AND_APPLIED";
            $registeredSearchRequest->notConsiderEmptyValidation = true;
            $registerdStudentDetails = reset($this->getStudentExamRegistrationFeeDetails($registeredSearchRequest));
        }
        if ($request->isStudentSideRequest && !$request->hideAlreadyExistCheck){
            $studentRegisterStatus = reset(array_filter($studentDetails->subjects,function($value){
                if($value->studentAssessmentRegistrationProperties->registrationStatus == "APPLIED" || $value->studentAssessmentRegistrationProperties->registrationStatus == "REGISTERED")
                return $value;
            }));
            if($studentRegisterStatus){
                if ( $studentRegisterStatus->studentAssessmentRegistrationProperties->registrationStatus == "APPLIED" && $studentRegisterStatus->studentAssessmentRegistrationProperties->feeStatus == "FAILED" && $studentRegisterStatus->studentAssessmentRegistrationProperties->paymentOption == "ONLINE_PAYMENT_METHOD"){
                    // do nothing
                }
                else{
                    $searchRequestForPayment = new \stdClass;
                    $searchRequestForPayment->studentId = $request->studentId;
                    $searchRequestForPayment->examRegistrationId = $request->examRegistrationId;
                    $studentPaymentStatusDetails = $this->searchStudentOnlinePayement($searchRequestForPayment);
                    if ($studentPaymentStatusDetails){
                        $studentRecentPaymentPendingStatus = reset(array_filter($studentPaymentStatusDetails,function($value){
                            return $value->status == "PENDING";
                        }));
                        if(empty($studentRecentPaymentPendingStatus)){
                            $eligibleForReapply = true;
                        }
                    }
                    else{
                        $eligibleForReapply = true;
                    }
                    if( $eligibleForReapply && $studentRegisterStatus->studentAssessmentRegistrationProperties->registrationStatus == "APPLIED" &&$studentRegisterStatus->studentAssessmentRegistrationProperties->paymentOption == "ONLINE_PAYMENT_METHOD"){
                        // do nothing
                    }
                    else{
                        throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,"Payment already initiated.");
                    }
                }
            }
        }
        if($studentDetails->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SEMESTER_WISE'){
            $minAttendanceForExamReg = json_decode(CommonService::getInstance()->getSettings(SettingsConstents::EXAM_CONTROLLER, SettingsConstents::SEMESTER_EXAM_SETTINGS))->minAttendanceForExamReg;
            if($minAttendanceForExamReg->enableDayWiseAttendanceChecking){
                $semWiseRequest = new \stdClass;
                $semWiseRequest->studentId = $request->studentId;
                $semWiseRequest->termId = $studentDetails->academicTermId;
                $semWiseRequest->examRegistrationId = $studentDetails->examRegistrationId;
                $semWiseRequest->studentGender = $studentDetails->studentGender;
                $semWiseRequest->workFlowId = $studentDetails->examRegistrationProperties->workFlowId;
                $semWiseCriteria = ProfessionalCommonExamService::getInstance()->checkStudentSemesterWiseAttendanceCriteriaForExamRegistration($semWiseRequest);
                if( $request->notConsiderValidation ){
                    $studentDetails->isShortageAttendance  = $semWiseCriteria->eligibleToApplyByDayWiseAttendance;
                }
                else if ( $request->isStudentSideRequest ){
                    if ( $semWiseCriteria->workflowId && $semWiseCriteria->eligibleForCondonation && !$semWiseCriteria->eligibleToApplyByDayWiseAttendance){
                        $semWiseCriteria->redirectToWorkFlowModule = 1;
                    return $semWiseCriteria;
                    }
                    else if ($semWiseCriteria->eligibleToApplyByDayWiseAttendance == false){
                        throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,"Can't register, attendance shortage. Should have minimum " . $semWiseCriteria->minimumAttendancePercentage . "% attendance.");
                    }
                }
            }
        }
        if($studentDetails->blockReasons && !$request->notConsiderValidation) {
            $blockReasonMsg = "Registration Blocked ";
            foreach($studentDetails->blockReasons as $reason){
                $blockReasonMsg .= "<br> * Due to ".$reason->name .". ";
                $blockReasonMsg .= $reason->contactPersonName ? "Please contact ".$reason->contactPersonName :"";
                $blockReasonMsg .= $reason->contactPersonDecription ? " ".$reason->contactPersonDecription :"";
            }
            throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,$blockReasonMsg);
        }
        foreach($studentDetails->examRegistrationProperties->paymentMethods as $paymentMethod){
            if($paymentMethod == ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD;
                $currentPaymentMethod->name = "College Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::BANK_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::BANK_CHALLAN_METHOD;
                $currentPaymentMethod->name = "Bank Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD;
                $currentPaymentMethod->name = "Online Payment Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
        }
        
        $showGenderWiseAttendance = false;
        if( empty($request->notConsiderValidation) ){
            $showGenderWiseAttendance = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, "EXAM_REGISTRATION_GENDER_WISE_ATTENDANCE_CHECK");
            if($showGenderWiseAttendance){
                if(empty($studentDetails->examRegistrationProperties->genderWiseMinimumAttendance)){
                    throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Gender wise attendance rule not added. Please contact exam controller.");
                }
                if(empty($studentDetails->studentGender) || (strtoupper($studentDetails->studentGender) != 'MALE' && strtoupper($studentDetails->studentGender) != 'FEMALE'  && strtoupper($studentDetails->studentGender) != 'OTHER') ){
                    throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Gender details not added. Please contact exam controller.");
                }
                $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance = (array) $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance;
            }
        }
        else{
            $showGenderWiseAttendance = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, "EXAM_REGISTRATION_GENDER_WISE_ATTENDANCE_CHECK");
            if($showGenderWiseAttendance){
                if(!empty($studentDetails->examRegistrationProperties->genderWiseMinimumAttendance && !empty($studentDetails->studentGender))){
                    $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance = (array) $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance;
                }
                else{
                    $showGenderWiseAttendance = false;
                }
            }
        }
        $studentDetails->totalFeeAmount = 0;
         // ------------Studdent common Fees & Fines --------------- 
        if(count($studentDetails->batchFeeFine) > 1){
            $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
        }
        else{
            $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
        }
        // ------------Remove Attendance Shortage Subjects Student Side--------------- 
        $studentDetails->eligibleSubjectForCondonation = [];
        $studentDetails->feSubjects = [];
        if($studentDetails->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SUBJECT_WISE'){
            $studentDetails->registeredSubjects = [];
            $condonationApprovedSubjectList = [];
            $feSubjectSettings = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, "ENABLE_FE_SUBJECTS_EXAM_REGISTRATION");
            $feSubjectSettings = json_decode($feSubjectSettings);
            $studentDetails->considerFeSubject = $feSubjectSettings->considerFeSubject;
            $studentDetails->considerFeSubjectForInternalCriteria = $feSubjectSettings->considerFeSubjectForInternalCriteria;
            
            if ($request->isStudentSideRequest){
                $enableSubjectWiseCondonation = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, "ENABLE_SUBJECT_WISE_CONDONATION");
                $studentDetails->considerSubjectWiseCondonation = $enableSubjectWiseCondonation;
            }
            if($studentDetails->considerSubjectWiseCondonation){
                if( $studentDetails->examRegistrationProperties->workFlowId ){
                    $condonationStatus = ProfessionalCommonExamService::getInstance()->getStatusOfWorkflowRequest($studentDetails->studentId, $studentDetails->academicTermId,$studentDetails->examRegistrationProperties->workFlowId);
                    if( $condonationStatus  == "APPROVED" ){
                        $condationSubjectRequest = new \stdClass();
                        $condationSubjectRequest->studentId = $studentDetails->studentId; 
                        $condationSubjectRequest->termId = $studentDetails->academicTermId; 
                        $condationSubjectRequest->gender = $studentDetails->studentGender; 
                        $condationSubjectRequest->isExamRegistrationApplyRequest = 1; 
                        $condationSubjectRequest->workFlowId = $studentDetails->examRegistrationProperties->workFlowId; 
                        $condationSubjectRequest = (array) $condationSubjectRequest;
                        $condonationApprovedSubjectList = ProfessionalCommonExamService::getInstance()->checkStudentIsEligibleForCondonation($condationSubjectRequest);
                    }
                    else{
                        $condationSubjectRequest = new \stdClass();
                        $condationSubjectRequest->studentId = $studentDetails->studentId; 
                        $condationSubjectRequest->termId = $studentDetails->academicTermId; 
                        $condationSubjectRequest->gender = $studentDetails->studentGender; 
                        $condationSubjectRequest->isExamRegistrationApplyRequest = 1; 
                        $condationSubjectRequest->workFlowId = $studentDetails->examRegistrationProperties->workFlowId; 
                        $condationSubjectRequest = (array) $condationSubjectRequest;
                        $condonationEligibleSubjectList = ProfessionalCommonExamService::getInstance()->checkStudentIsEligibleForCondonation($condationSubjectRequest);
                    }
                }
            }
            foreach($studentDetails->subjects as $key=> $subject){ 
                $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
                $attendanceTermWiseReportRequest->studentId = $studentDetails->studentId;
                $attendanceTermWiseReportRequest->termId = $studentDetails->academicTermId;
                $attendanceTermWiseReportRequest->paperSubjectId = $subject->academicPaperSubjectId;
                $attendanceTermWiseReportRequest->attendanceClosingDate = $studentDetails->batchProperties->attendanceClosingDate;
                $subject->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
                if($showGenderWiseAttendance){
                    if ( $subject->properties->minimumAttendancePercentage != 1 ){
                        $subject->properties->minimumAttendancePercentage = $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance[strtoupper($studentDetails->studentGender)];
                    }
                    else if ( $subject->properties->minimumAttendancePercentage == 1 ){
                        $subject->properties->minimumAttendancePercentage = 0;
                    }
                }
                $subject->isShortageAttendance  = ($subject->properties->minimumAttendancePercentage > $subject->attendanceDetails->attendancePercentage) ? true : false;
              
                if( $studentDetails->considerSubjectWiseCondonation && $condonationStatus  == "APPROVED" ){
                    if ( in_array($subject->academicPaperSubjectId, $condonationApprovedSubjectList) ){
                        $subject->isShortageAttendance = false;
                    }
                }
                else if ( $studentDetails->considerSubjectWiseCondonation  ){
                    if ( in_array($subject->academicPaperSubjectId, $condonationEligibleSubjectList) ){
                        $studentDetails->eligibleSubjectForCondonation[] = json_decode(json_encode($studentDetails->subjects[$key]));
                    }
                }
                if( $studentDetails->considerFeSubjectForInternalCriteria && $studentDetails->considerFeSubject ){
                    if ( $subject->classType == 'PRACTICAL' && $subject->isShortageAttendance){
                        $experimentRequest = new GetStudentLabStatusRequest();
                        $experimentRequest->studentId = $studentDetails->studentId;
                        $experimentRequest->paperSubjectId = $subject->academicPaperSubjectId;
                        $experimentStatus = ExperimentCompletionService::getInstance() -> studentLabStatus($experimentRequest);
                        if (  $experimentStatus->labstatus == 1 ){
                            $subject->isShortageAttendance = false;
                        }
                    }
                    if ( $subject->isInternal == 1 &&  $subject->isExternal != 1){
                        $schemeType = "PERCENTAGE";
                        $passCriteria = GradeSchemeService::getInstance()->getSubjectPassCriteriaByAcademicPaperSubject($subject->academicPaperSubjectId, $schemeType);
                        $internalPassCriteria = $overallPassCriteria = null;
                        $internalPassCriteria = $passCriteria->internalPassCriteria;
                        $overallPassCriteria = $passCriteria->overallPassCriteria;
                        $internalPercent = $subject->internalMaxMark ? (100 * $subject->internalMark/ $subject->internalMaxMark) : 0;
                        if ( $internalPercent < $internalPassCriteria || $internalPercent < $overallPassCriteria ){
                            $subject->internalFe = true;
                            $studentDetails->feSubjects[] = json_decode(json_encode($studentDetails->subjects[$key]));
                            if ( !$request->notConsiderValidation ){
                                unset($studentDetails->subjects[$key]);
                                continue;
                            }
                        }
            
                    }
                    
                }
                if($subject->isShortageAttendance && $request->notConsiderValidation){
                    $studentDetails->feSubjects[] = json_decode(json_encode($studentDetails->subjects[$key]));
                }
                if($subject->isShortageAttendance && !$request->notConsiderValidation){
                    $studentDetails->feSubjects[] = json_decode(json_encode($studentDetails->subjects[$key]));
                    unset($studentDetails->subjects[$key]);
                }
                else{
                    $studentDetails->registeredSubjects[] = $subject;
                }
            }
            $studentDetails->subjects = $studentDetails->registeredSubjects;
        }
        // ------------studdent common Fees --------------- 
        $studentDetails->commonFees = [];   
        $studentDetails->totalCommonFees = 0;  
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REGULAR';
        $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRegistrationType;
        }));
        $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
        $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
        $subjectLimitFees = [];
        $subjectLimitCounts = [];
        foreach($allCommonFees as $commonFee){
            if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                if($studentCommonFees->feeType[$commonFee->id]->value){
                    if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject != '1'){
                        $currentFee = new \stdclass;
                        $currentFee->feeName = $commonFee->name;
                        $currentFee->isSubjectFeeLimit = $commonFee->isSubject_fee_limit;
                        $currentFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                        $currentFee->currentValue = $studentCommonFees->feeType[$commonFee->id]->value;
                        $currentFee->maxValue = $currentFee->isSubjectFeeLimit ? $studentCommonFees->feeType[$commonFee->id]->maxValue : 0;
                        $studentDetails->totalCommonFees += $currentFee->value;
                        $studentDetails->commonFees[] = $currentFee;
                    } 
                    else if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject == '1'){
                        if($commonFee->feeSelectionSubjectLimit && $studentCommonFees->feeType[$commonFee->id]->value){
                            $subjectLimitFees[$commonFee->feeSelectionSubjectLimit] =  $studentCommonFees->feeType[$commonFee->id]->value;
                            $subjectLimitCounts[$commonFee->feeSelectionSubjectLimit] = $commonFee->feeSelectionSubjectLimit;
                        }
                    } 
                }
            } 
        }
        if(!empty($subjectLimitFees)){
            $subjectCount = count($studentDetails->subjects);
            sort($subjectLimitCounts);
            $index = array_search($subjectCount, $subjectLimitCounts);
            $resultIndex = ($index !== false && $subjectLimitCounts[$index] == $subjectCount) ? $subjectLimitCounts[$index] : (empty($subjectLimitCounts) ? null : max(array_filter($subjectLimitCounts, function($value) use ($subjectCount) {
                return $value <= $subjectCount;
            })));
            if(!empty($subjectLimitFees[$resultIndex])){
                $currentFee = new \stdclass;
                $currentFee->feeName = "Total Subject Fee";
                $currentFee->isSubjectFeeLimit = 0;
                $currentFee->value = $subjectLimitFees[$resultIndex];
                $studentDetails->totalCommonFees += $currentFee->value;
                $studentDetails->commonFees[] = $currentFee;
            }
        }
        // ------------studdent common Fines ---------------    
        $studentDetails->commonFines = []; 
        $studentDetails->totalCommonFines = 0;
        $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
        $studentCommonFines = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFines,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRegistrationType;
        }));
        $studentCommonFineIdsArray = array_keys((array)$studentCommonFines->fineType);
        $studentCommonFines->fineType = (array)$studentCommonFines->fineType;
        $today = date("Y-m-d H:i");
        if ( $request->considerChallanVerifyDate ) {
            $today = $studentDetails->examRegistrationPaymentProperties->challanAppliedDate? $studentDetails->examRegistrationPaymentProperties->challanAppliedDate :date("Y-m-d H:i");
        }
        if($request->considerRegisteredAndApplied && !empty($registerdStudentDetails)){
            $today = $registerdStudentDetails->studentEntryCreatedDate? $registerdStudentDetails->studentEntryCreatedDate :date("Y-m-d H:i");
        }
        // $maxEndDate = $studentDetails->examRegistrationProperties->registrationWithoutFineEndDate;
        foreach($allCommonFines as $commonFine){
            if ( in_array ( $commonFine->id, $studentCommonFineIdsArray ) ) {
                $maxEndDate = $maxEndDate ?? $studentCommonFines->fineType[$commonFine->id]->endDate;
                $minStartDate = $minStartDate ?? $studentCommonFines->fineType[$commonFine->id]->startDate;
                if((strtotime($today) >= strtotime($studentCommonFines->fineType[$commonFine->id]->startDate)) && ($today <= $studentCommonFines->fineType[$commonFine->id]->endDate )){
                    $currentFine = new \stdclass;
                    $currentFine->fineName = $commonFine->name;
                    $currentFine->value = $studentCommonFines->fineType[$commonFine->id]->value;
                    $studentDetails->totalCommonFines += $currentFine->value;
                    $studentDetails->commonFines[] = $currentFine;
                    if(strtotime($studentCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($maxEndDate)){
                        $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                    }
                    if(strtotime($studentCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($minStartDate)){
                        $minStartDate = $studentCommonFines->fineType[$commonFine->id]->startDate;
                    }
                    // if($studentCommonFines->fineType[$commonFine->id]->endDate >= $maxEndDate){
                    //     $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                    // }
                } 
            }
        }
        // ------------Studdent Subject Fees --------------- 
        $studentDetails->totalSubjectFees = 0;
        $feeAddedSubjectIds = [];
        foreach($studentDetails->subjects as $subject){
            $subject->currentSubjectFeeProperties = reset(array_filter($subject->subjectFeeProperties,function($value)use($studentDetails){
                return $value->examRegistrationType == $studentDetails->examRegistrationType;
            }));
            $subject->currentSubjectFeeProperties->feeType = (array)$subject->currentSubjectFeeProperties->feeType;
            $subject->subjectFeeTemplateIdsArray = array_keys($subject->currentSubjectFeeProperties->feeType);
            $subject->currentFeeTypeTemplateId = ExamRegistrationFeeCommonService::getInstance()->getCurrentSubjectFeeTemplateForStudent($subject,$studentDetails);
            $subject->value =  $subject->currentFeeTypeTemplateId ? $subject->currentSubjectFeeProperties->feeType[$subject->currentFeeTypeTemplateId]->value : 0;
            $studentDetails->totalSubjectFees += $subject->value;
            $feeAddedSubjectIds[$subject->id] = $subject->id;
        }
        $studentDetails->totalSubjectFeesNotApplied = $studentDetails->totalSubjectFees;
        if($request->considerRegisteredAndApplied){
            if($request->considerAppliedSubjectsFeesOnly){
                $studentDetails->totalSubjectFees = 0;
            }
            foreach($registerdStudentDetails->subjects as $subject){
                if( !in_array($subject->id, $feeAddedSubjectIds) || $request->considerAppliedSubjectsFeesOnly){
                    $subject->currentSubjectFeeProperties = reset(array_filter($subject->subjectFeeProperties,function($value)use($registerdStudentDetails){
                        return $value->examRegistrationType == $registerdStudentDetails->examRegistrationType;
                    }));
                    $subject->currentSubjectFeeProperties->feeType = (array)$subject->currentSubjectFeeProperties->feeType;
                    $subject->subjectFeeTemplateIdsArray = array_keys($subject->currentSubjectFeeProperties->feeType);
                    $subject->currentFeeTypeTemplateId = ExamRegistrationFeeCommonService::getInstance()->getCurrentSubjectFeeTemplateForStudent($subject,$studentDetails);
                    $subject->value =  $subject->currentFeeTypeTemplateId ? $subject->currentSubjectFeeProperties->feeType[$subject->currentFeeTypeTemplateId]->value : 0;
                    $studentDetails->totalSubjectFees += $subject->value;
                    if($subject->classType && $subject->classType!="null"){
                        $studentDetails->classTypeSubjectFees[$subject->classType] += $subject->value;
                        $studentDetails->classTypeSubjectFeeCalc[$subject->classType]->subjectCount++; 
                        $studentDetails->classTypeSubjectFeeCalc[$subject->classType]->subjectFee = $subject->value;
                    }
                }
                
            }
        }
        $studentDetails->totalFeeAmount = $studentDetails->totalCommonFines + $studentDetails->totalCommonFees + $studentDetails->totalSubjectFees;
        if($request->considerRegisteredAndApplied && !empty($registerdStudentDetails) && !$request->considerAppliedSubjectsFeesOnly){
            $studentDetails->commonFines = [];
            $studentDetails->commonFees = [];
            $studentDetails->totalSubjectFees = $studentDetails->totalSubjectFeesNotApplied;
        }
        if (strtotime($minStartDate) > strtotime(date("Y-m-d H:i")) && !$request->notConsiderValidation && !$request->hidePaymentValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration not started");
        }
        elseif ( strtotime($maxEndDate)  < strtotime(date("Y-m-d H:i")) && !$request->notConsiderValidation && !$request->hidePaymentValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration closed");
        }
        elseif($studentDetails->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SEMESTER_WISE' && (!$minAttendanceForExamReg->enableDayWiseAttendanceChecking)){
            $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
            $attendanceTermWiseReportRequest->studentId = $studentDetails->studentId;
            $attendanceTermWiseReportRequest->termId = $studentDetails->academicTermId;
            $attendanceTermWiseReportRequest->attendanceClosingDate = $studentDetails->batchProperties->attendanceClosingDate;
            $studentDetails->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
            if($showGenderWiseAttendance){
                $studentDetails->examRegistrationProperties->minimumAttendancePercentage = $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance[strtoupper($studentDetails->studentGender)];
            }
            $studentDetails->isShortageAttendance  = $studentDetails->examRegistrationProperties->minimumAttendancePercentage > $studentDetails->attendanceDetails->attendancePercentage ? true : false;
            if($studentDetails->isShortageAttendance && !$request->notConsiderValidation){
                $studentDetails->canRegister = false;
                $studentDetails->blockReasons = ['Attendance Shortage'];
                throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Attendance Shortage");
            }
        }
        elseif(empty($studentDetails->subjects)  && !$request->notConsiderValidation){
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Couldnot Register Exam");
        }
        // sort the subject by academics order
        usort($studentDetails->subjects, function ($a, $b) {
            return $a->subjectPriority > $b->subjectPriority;
        });
        return($studentDetails); 
    }
    
      /**
     * get Student Details For Exam Registration Fee
     * @param $request
     * @return examRegistration
     */
    public function getStudentExamRegistrationFeeDetails($request){
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        $joinQueary = "";
        $selectColumns = "";
        $clusterRelationQuery = " INNER JOIN group_members sgm ON
                            sgm.groups_id = sg.id AND 
                            sgm.academic_status IN ('ACTIVE') AND
                            sgm.members->>'$.studentId' = spa.id ";
        if($request->mappingType == "EXAM_REGISTRATION"){
            $mapperForRegistrationDetails = StudentExamRegistrationServiceMapper::SEARCH_EXAM_REGISTRATION_FEE_DETAILS ;
        }
        else{
            $mapperForRegistrationDetails = StudentExamRegistrationServiceMapper::SEARCH_STUDENT_EXAM_REGISTRATION_FEE_DETAILS;
        }
        $sortBy = " ORDER BY eer.created_date DESC";
        if( $request->orderBySemester ){
            $sortBy = " ORDER BY eerb.academicTermId ASC, eer.properties ->> '$.examYear' ASC ,eer.properties ->> '$.examMonth' + 0 ASC";
        }
        if(($request->isEnableMinorHonorExamRegistration) ){
            if(($request->isMinorHonorExamRegistrationOnly)){
                $whereQuery .= " AND  ( (eer.properties ->> '$.isHonorCourse' = '1') OR (eer.properties ->> '$.isMinorCourse' = '1'))";
            }
            else{
                $whereQuery .= " AND  ( (eer.properties ->> '$.isHonorCourse' IS NULL OR eer.properties ->> '$.isHonorCourse' != '1') AND (eer.properties ->> '$.isMinorCourse' IS NULL OR eer.properties ->> '$.isMinorCourse' != '1'))";
            }
        }
        if(($request->isMinorExamOnly) ){
            $whereQuery .= " AND (eer.properties ->> '$.isMinorCourse' = '1') ";
        }
        if(($request->isHonourExamOnly) ){
            $whereQuery .= " AND (eer.properties ->> '$.isHonorCourse' = '1') ";
        }
        if(!empty($request->studentId)) {
            $whereQuery .= " AND spa.student_id = '$request->studentId";
        }
        if(!empty($request->academicTermId)){
            $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
            $whereQuery .= " AND  CAST(eerb.properties ->> '$.academicTermId'AS CHAR) IN ( $academicTermIdString )";
        }
        if(!empty($request->groupId)){
            $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
            $whereQuery .= " AND  g.id IN ( $groupIdString )";
        }
        if(!empty($request->examType)){
            $examTypeString = is_array($request->examType) ? "'" . implode("','",$request->examType) . "'" : "'".$request->examType."'";
            $whereQuery .= " AND eer.type IN ( $examTypeString )";
        }
        if(($request->isNotConsiderSpecialExam)){
            $whereQuery .= " AND (eer.properties ->> '$.isSpecialExam' != '1' OR eer.properties ->> '$.isSpecialExam' IS NULL )";
            
        }
        if($request->isNotConsiderStudentClusterRelation){
            $clusterRelationQuery = "";
        }
        if($request->examType == ExamRegistrationTypeConstants::SUPPLEMENTARY){
            $joinQueary .= " INNER JOIN ec_semester_mark_details esmdsem ON
                                esmdsem.groups_id = eerb.groups_id 
                                AND esmdsem.academic_term_id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
                            INNER JOIN student_program_account spa ON 
                                spa.student_id =  esmdsem.student_id
                            INNER JOIN studentaccount sa ON
                                sa.studentID = spa.student_id
                            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 = spa.student_id";
            $selectColumns .= ",esmdsem.mark_details ->>'$.percentage' AS semesterPercentage,
                                esmdsem.mark_details AS semesterMarkDetails,
                                esmdsem.mark_history AS semesterMarkHistory,
                                esmdsem.failed_status AS semesterFailedStatus,
                                esmdsubcon.failed_status AS subjectFailedStatus,
                                esmdsubcon.mark_details ->>'$.percentage' AS subjectPercentage,
                                esmdsubcon.mark_details AS subjectMarkDetails,
                                esmdsubcon.mark_history AS subjectMarkHistory";
        }
        else{
            $joinQueary = " INNER JOIN group_members gm ON
                                gm.groups_id = g.id
                            INNER JOIN student_program_account spa ON 
                                spa.id  = gm.members->>'$.studentId'
                            INNER JOIN student_program_batch_log spbl ON
                                spbl.batch_group_id = g.id AND
                                spbl.term_id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR) AND
                                spbl.program_student_id = spa.id AND spbl.properties->>'$.academicStatus' IN ('ACTIVE','COMPLETED')
                            INNER JOIN studentaccount sa ON
                                sa.studentID = spa.student_id 
                            INNER JOIN `groups` sg ON
                                sg.paperSubjectId = caps.id AND
                                sg.type = 'SUBJECT'
                            $clusterRelationQuery ";
        }
        if($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::APPLIED || $request->registrationStatus == "REGISTERED_AND_APPLIED"){
            $joinQueary .= " INNER JOIN ec_student_assessment_registration esar ON
                    esar.student_id = sa.studentID AND  esar.am_assessment_id = eers.am_assessment_id AND esar.ec_exam_registration_type = eer.type"; 
            if( $request->registrationStatus == "REGISTERED_AND_APPLIED"){
                $whereQuery .= " AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED','APPLIED') ";
            }
            else{
                $whereQuery .= $request->registrationStatus == StudentExamRegistrationStatus::REGISTERED ? " AND esar.properties ->> '$.registrationStatus' = 'REGISTERED' AND esar.properties ->> '$.feeStatus' = 'PAID'" : " AND esar.properties ->> '$.registrationStatus' = 'APPLIED'";
            }
        }
        elseif($request->registrationStatus == StudentExamRegistrationStatus::NOT_APPLIED){
            $joinQueary .= " LEFT JOIN ec_student_assessment_registration esar ON
                esar.student_id = sa.studentID AND  esar.am_assessment_id = eers.am_assessment_id AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED','APPLIED') AND esar.ec_exam_registration_type = eer.type ";
            $whereQuery .= " AND esar.id IS NULL";
        }
        else{
            $joinQueary .= " LEFT JOIN ec_student_assessment_registration esar ON
            esar.student_id = sa.studentID AND  esar.am_assessment_id = eers.am_assessment_id AND esar.ec_exam_registration_type = eer.type ";
        }
        if(!empty($request->examRegistrationId)){
            $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
            $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
        }
        if(!empty($request->academicPaperSubjectId)){
            $academicPaperSubjectIdString = is_array($request->academicPaperSubjectId) ? "'" . implode("','",$request->academicPaperSubjectId) . "'" : "'".$request->academicPaperSubjectId."'";
            $whereQuery .= " AND caps.id IN ( $academicPaperSubjectIdString )";
        }
       
        
        $query = "SELECT DISTINCT
            sa.studentID as studentId,
            sa.studentName,
            sa.admissionNo,
            sa.studentBirthday as studentBirthday,
            sa.studentFather AS fatherName,
            sa.studentAddress as studentAddress,
            sa.studentPhone as studentPhone,
            sa.studentEmail as studentEmail,
            sa.studentGender as studentGender,
            spa.id as studentProgramAccountId,
            spa.properties->>'$.registerNumber' AS registerNo,
            spa.properties->>'$.rollNumber' AS rollNo,
            sa.reservationID,
            eer.id as examRegistrationId,
            eer.name as examRegistrationName,
            eer.properties->>'$.description' as examRegistrationDescription,
            eer.type as examRegistrationType,
            eer.properties as examRegistrationProperties,
            eerb.groups_id as groupId,
            eerb.properties ->> '$.academicTermId' as academicTermId,
            eerb.properties AS batchProperties,
            eerb.fees_properties as batchFeeProperties,
            act.name AS academicTermName,
            g.name AS groupName,
            p.name AS programName,
            eeft.id as batchFeeTemplateId,
            eeft.fee_properties as batchCommonFees,
            eeft.fine_properties as batchCommonFines,
            IF (eeft.operation_properties  IS NULL,0,1) as isConsiderOperation,
            eeft.operation_properties as batchOperationProperties,
            eers.fees_properties as subjectFeeProperties,
            eers.properties as subjectProperties,
            eers.am_assessment_id as assessmentId,
            oe.id as oeExamId,
            caps.id AS academicPaperSubjectId,
            caps.properties ->> '$.isExternal' as isExternal,
            caps.properties ->> '$.isMoocSubject' as isMoocSubject,
            caps.properties ->> '$.isInternal' as isInternal,
            caps.properties ->> '$.internalMaxMark' as internalMaxMark, 
            caps.properties ->> '$.classType' as classType, 
            COALESCE(cap.properties ->> '$.order', 0) * 100 + COALESCE(caps.properties ->> '$.order', 0) as subjectPriority,
            esar.id AS studentAssessmentRegistrationId,
            esar.properties as studentAssessmentRegistrationProperties,
            esar.properties->> '$.registrationType' as assessmentRegistrationType,
            esar.properties->> '$.moocCertificateStatus' as moocCertificateStatus,
            s.code AS subjectCode,
            caps.properties ->> '$.syllabusName' AS syllabusName,
            s.name AS subjectName,
            eserd.total_fee AS examRegistrationPaidAmount,
            eserd.balance_amount_details AS balanceAmountDetails,
            eserd.created_date as studentEntryCreatedDate,
            eserd.properties AS examRegistrationPaymentProperties,
            eserd.id AS examRegistrationPaymentUniqueNo,
            eserd.properties ->> '$.challanNo' as challanNo,
            esbrm.ec_block_student_reason_id as blockStudentReasonId,
            ebsr.name as blockReasonName,
            cpsa.staffName as contactPersonName,
            ebsr.properties ->> '$.description' AS contactPersonDecription,
            im.internal_mark AS internalMark,
            cst.name as subjectTypeName,
            slot.id AS slotId,
            slot.name AS slotName,
            ct.course_Type as courseType,
            deg.name as degreeName
            $selectColumns
        FROM
            ec_exam_registration eer
        INNER JOIN ec_exam_registration_batch eerb ON
            eerb.ec_exam_registration_id = eer.id 
        INNER JOIN academic_term act ON 
            act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
        INNER JOIN `groups` g ON
            g.id = eerb.groups_id
            AND g.`type` = 'BATCH'
        INNER JOIN program p ON 
            p.id = g.properties->>'$.programId'
        INNER JOIN course_type ct ON ct.courseTypeID = p.course_type_id
        INNER JOIN ec_examregistration_fee_templates_mapping eeftm ON
            eeftm.id = eerb.fees_properties->>'$.feeTemplateId'
        INNER JOIN ec_examregistration_fee_templates eeft ON
            eeft.ec_examregistration_fee_templates_mapping_id = eeftm.id
        INNER JOIN ec_exam_registration_subject eers ON
            eers.ec_exam_registration_batch_id = eerb.id
        INNER JOIN cm_academic_paper_subjects caps ON
            caps.id = eers.cm_academic_paper_subjects_id
        INNER JOIN cm_academic_paper cap ON 
            caps.cm_academic_paper_id = cap.id
        INNER JOIN oe_exams oe ON
            oe.assessment_id = eers.am_assessment_id AND oe.is_deleted = 0
        INNER JOIN v4_ams_subject s ON
            s.id = caps.ams_subject_id
        INNER JOIN degree deg ON
            deg.id = p.degree_id
        $joinQueary 
        LEFT JOIN ec_student_exam_registration_details eserd ON
            eserd.student_id = sa.studentID AND 
            eserd.ec_exam_registration_id = eer.id 
        LEFT JOIN ec_student_block_reason_mapping esbrm ON
            esbrm.student_id = sa.studentID AND esbrm.exam_registration_id = eer.id AND
            esbrm.blocking_type = 'REGISTRATION_BLOCKING'
        LEFT JOIN ec_block_student_reason ebsr ON 
            ebsr.id = esbrm.ec_block_student_reason_id AND
            ebsr.type = 'SEMESTER_WISE'
        LEFT JOIN staffaccounts cpsa ON 
            cpsa.staffID = ebsr.contact_person_id 
        LEFT JOIN ec_internal_marks im ON 
            im.groups_id = eerb.groups_id AND
            im.academic_paper_subjects_id = eers.cm_academic_paper_subjects_id AND 
            im.student_id = sa.studentID 
        LEFT JOIN cm_subject_types cst ON
            cst.id = caps.subject_type_id
        LEFT JOIN cm_common_list_object slot ON slot.id =  caps.slot_id
        WHERE
            eer.trashed IS NULL
            AND eer.properties->>'$.publish' = '1' ";
        try {
            $studentExamRegistrationFeeDetails = $this->executeQueryForList($query.$whereQuery.$sortBy.$limitQuery, $this->mapper[$mapperForRegistrationDetails]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student.");
        }
        if( $request->considerEmptyReturn ){
            return $studentExamRegistrationFeeDetails;
        }elseif (empty($studentExamRegistrationFeeDetails) && !$request->notConsiderEmptyValidation) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Exam Registration not declared, Please try again.");
        }
        return $studentExamRegistrationFeeDetails;
       
      
    }
    /**
     * saveStudentExamRegistrationDetails
     * @param StudentExamRegistrationDetails $examRegistration
     * @return $id
     */
    public function saveStudentExamRegistrationDetails (StudentExamRegistrationDetails $studentExamRegistrationDetails)
    {
        $studentExamRegistrationDetails = $this->realEscapeObject($studentExamRegistrationDetails);
        $studentExamRegistrationDetails->createdBy = $GLOBALS['userId'] ?? $studentExamRegistrationDetails->createdBy;
        $studentExamRegistrationDetails->updatedBy = $GLOBALS['userId'] ?? $studentExamRegistrationDetails->updatedBy;
        try{
            $this->insertStudentExamRegistratioDetails($studentExamRegistrationDetails);
          
        }catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage()); 
        }
        return true ;
        
    }
     /**
     * Insert StudentExamRegistratioDetails
     * @param StudentExamRegistrationDetails $studentExamRegistrationDetails
     * @return  $id
     */
    private function insertStudentExamRegistratioDetails(StudentExamRegistrationDetails $studentExamRegistrationDetails)
    {
        $properties = !empty($studentExamRegistrationDetails->properties) ? "'" . json_encode($studentExamRegistrationDetails->properties) . "'" : "'{}'";
        $balanceAmountDetails = !empty($studentExamRegistrationDetails->balanceAmountDetails) ? "'" . json_encode($studentExamRegistrationDetails->balanceAmountDetails) . "'" : "'{}'";
        $query = "INSERT INTO ec_student_exam_registration_details
                  (student_id,ec_exam_registration_id,total_fee,properties,balance_amount_details,created_by,updated_by)
                  VALUES
                  ($studentExamRegistrationDetails->studentId,'$studentExamRegistrationDetails->examRegistrationId','$studentExamRegistrationDetails->totalFee',$properties,$balanceAmountDetails,'$studentExamRegistrationDetails->createdBy','$studentExamRegistrationDetails->updatedBy') 
                  ON DUPLICATE KEY 
                  UPDATE `properties` = JSON_MERGE_PATCH(properties,$properties), 
                  `balance_amount_details` = JSON_MERGE_PATCH(balance_amount_details,$balanceAmountDetails),
                  `total_fee` = '$studentExamRegistrationDetails->totalFee', 
                  updated_by = VALUES(created_by)";
        
        try {
           $this->executeQuery($query);
           return true;
        } catch (\Exception $e) {
             throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
    }
     /**
     * get Student Details For Exam Registration Fee
     * @param $request
     * @return examRegistration
     */
    public function getStudentExamRegistrationTotalFeeDetails($request){
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        if (empty($request->studentId) || empty($request->examRegistrationId)) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Cannot fetch Exam Registration of unknown student! Please try again.");
        }
        if(!empty($request->studentId)) {
            $whereQuery .= " AND spa.student_id = '$request->studentId";
        }
        if(!empty($request->studentExamRegDetailsId)) {
            $whereQuery .= " AND eserd.id = '$request->studentExamRegDetailsId";
        }
        if(!empty($request->examRegistrationId)){
            $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
            $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
        }
        $query = "SELECT DISTINCT
            sa.studentID as studentId,
            sa.studentName,
            sa.studentEmail AS studentEmail,
            sa.studentPhone as studentMobile,
            spa.properties->>'$.registerNumber' AS studentRegisterNo,
            eerb.groups_id as groupId,
            g.name AS groupName,
            eer.id as examRegistrationId,
            eer.name as examRegistrationName,
            eer.type AS examRegistrationType,
            eserd.id as studentExamRegistrationDetailId,
            eserd.total_fee as totalFee,
            eserd.properties as studentExamRegDetailProperties
        FROM
            ec_exam_registration eer
        INNER JOIN ec_exam_registration_batch eerb ON
            eerb.ec_exam_registration_id = eer.id 
        INNER JOIN `groups` g ON
            g.id = eerb.groups_id
            AND g.`type` = 'BATCH'
        INNER JOIN group_members gm ON
            gm.groups_id = g.id
        INNER JOIN student_program_account spa ON 
            spa.id  = gm.members->>'$.studentId'
        INNER JOIN studentaccount sa ON
            sa.studentID = spa.student_id
        INNER JOIN ec_student_exam_registration_details eserd ON
            eserd.student_id = sa.studentID AND eserd.ec_exam_registration_id = eer.id
        WHERE
            eer.trashed IS NULL ";
        try {
            $studentExamRegistrationFeeDetails = $this->executeQueryForObject($query.$whereQuery);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student.");
        }
        if (empty($studentExamRegistrationFeeDetails)) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Exam Registration not declared, Please try again.");
        }
        $studentExamRegistrationFeeDetails->studentExamRegDetailProperties = json_decode($studentExamRegistrationFeeDetails->studentExamRegDetailProperties);
        return $studentExamRegistrationFeeDetails;
    }
    /**
     * get Current Payment Status by student
     * @param $request
     * @return studentPaymentStatusDetails
     */
    public function getCurrentPaymentStatus($request){
        $searchRequest = new \stdClass;
        $searchRequest->studentId = $request->studentId;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $studentPaymentStatusDetails = $this->searchStudentOnlinePayement($searchRequest);
        // $studentPaymentStatusDetails = $this->getCurrentPaymentStatusForStudent($searchRequest);
        array_walk($studentPaymentStatusDetails, function($studentPaymentStatus){
            $studentPaymentStatus->properties = json_decode($studentPaymentStatus->properties);
            $studentPaymentStatus->isCheckStatus = false;
            $studentPaymentStatus->totalFee = $studentPaymentStatus->amount;
            $studentPaymentStatus->onlinePaymentTransactionId = $studentPaymentStatus->txnID;
            $studentPaymentStatus->onlinePaymentTransactionDate = $studentPaymentStatus->transactionDate;
            switch($studentPaymentStatus->status){
                case StudentExamRegistrationOnlinePaymentStatus::PENDING:
                    $studentPaymentStatus->PaymentStatus = 'Pending';
                    $studentPaymentStatus->isCheckStatus = true;
                    break;
                case StudentExamRegistrationOnlinePaymentStatus::FAILED:
                    $studentPaymentStatus->PaymentStatus = 'Failed';
                    $studentPaymentStatus->isCheckStatus = false;
                    break;
                case StudentExamRegistrationOnlinePaymentStatus::SUCCESS:
                    $studentPaymentStatus->PaymentStatus = 'Success';
                    $studentPaymentStatus->isCheckStatus = false;
                    break;
            } 
        });
        return($studentPaymentStatusDetails);
    }
       /**
     * get Current Payment Status For Student
     * @param $request
     * @return studentPaymentStatusDetails
     */
    public function getCurrentPaymentStatusForStudent($request){
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        if (empty($request->studentId) || empty($request->examRegistrationId)) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Cannot fetch Exam Registration of unknown student! Please try again.");
        }
        if(!empty($request->studentId)) {
            $whereQuery .= " AND eserd.student_id = '$request->studentId";
        }
       
        if(!empty($request->examRegistrationId)){
            $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
            $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
        }
        $query = "SELECT DISTINCT
            eserd.id as studentExamRegDetailsId,
            eserd.student_id as studentId,
            eserd.ec_exam_registration_id as examRegistrationId,
            eserd.total_fee as totalFee,
            eserd.properties as paymentProperties,
            eserd.balance_amount_details as balanceAmountDetails,
            eer.name as examRegistrationName
        FROM
            ec_student_exam_registration_details eserd
        INNER JOIN ec_exam_registration eer ON
            eer.id = eserd.ec_exam_registration_id
        WHERE
            1 = 1 ";
        try {
            $studentPaymentStatusDetails = $this->executeQueryForList($query.$whereQuery);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student.");
        }
        if (empty($studentPaymentStatusDetails)) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Could not fetch payment details, Please try again.");
        }
        return $studentPaymentStatusDetails;
    }
     /**
     * Search stduent Supplimentary Exam Registration
     * @param $request
     * @return examRegistration
     */
    public function getStudentSupplementaryExamRegistrationSubjectFeeDetails($request){
        $searchRequest = new \stdClass;
        $isAvoidConditionForInternalOnlySubjectInExamRegistrationStudentSide = false;
        $searchRuleRequest = new SearchRuleRequest;
        $searchRuleRequest->name = 'STUDENT_SUPPLY_REGISTRATION_RULE';
        $ruleObj = reset(RuleService::getInstance()->searchRule($searchRuleRequest));
        if($ruleObj){
            $disableSubjectSelection = $ruleObj->rule->disableSubjectSelection == '1' ? true : false;
            $checkIfBlockAllSubjectPassedAndSemesterFailedInImprovement = $ruleObj->rule->checkIfBlockAllSubjectPassedAndSemesterFailedInImprovement == '1' ? true : false;
            $checkIfBlockAllSubjectPassedAndSemesterFailedInImprovementConditionCourseTypes = $ruleObj->rule->checkIfBlockAllSubjectPassedAndSemesterFailedInImprovementConditionCourseTypes ??  [];
            $isAvoidConditionForInternalOnlySubjectInExamRegistrationStudentSide = $ruleObj->rule->isAvoidConditionForInternalOnlySubjectInExamRegistrationStudentSide == '1' ? true : false;
        }
        $noSubjectErrorMessages = [];
        // this case to check block when regular hall ticket blocking then not able to register the corresponding supply
        // $blockRegularBlockedSubject is enable (SJU) then check any block condition is in corresponding regular ,if any reason founds then student cannot register that subject
        $supplySettingsDetails = CommonService::getInstance()->getSettings(SettingsConstents::SUPPLY_IMPROVE, SettingsConstents::SUPPLY_SETTINGS);
        $supplySettings = json_decode($supplySettingsDetails);
        $blockRegularBlockedSubject = $supplySettings->blockSubjectIfRegularExamBlocked;
        $haveImprovement = false;
        $isNearByPassedExamAsImprovement = false;
        $isImprovementOnly = false;
        $isImprovementOnlyForRegularPassed = false;
        $searchRequest->studentId = $request->studentId;
        $studentCommonFeesIdsArray = [];
        $studentCommonFineIdsArray = [];
        $request->isConsiderAllSubject = false;
        $isConsiderAllSubject = $request->isConsiderAllSubject;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->academicPaperSubjectId = $isConsiderAllSubject ? [] : $request->academicPaperSubjectId;
        $searchRequest->registrationStatus =  $request->registrationStatus;
        $searchRequest->notConsiderEmptyValidation =  $request->notConsiderEmptyValidation;
        $latestExamDetails = new \stdClass;
        $searchRequest->examType = ExamRegistrationTypeConstants::SUPPLEMENTARY;
        $searchRequest->considerRegisteredAndApplied =  $request->considerRegisteredAndApplied;
        $studentDetails = reset($this->getStudentExamRegistrationFeeDetails($searchRequest));
        $requestForBlkUnblkSubjects = new \stdClass;
        $requestForBlkUnblkSubjects->studentId = $request->studentId;
        $requestForBlkUnblkSubjects->examRegistrationId = $request->examRegistrationId;
        $blockedUnblockedSubjects = $this->getBlockedUnblockedSubjectDetails($requestForBlkUnblkSubjects);
        $enableFeSubjectForInternals = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, "ENABLE_FE_SUBJECTS_FOR_SUPPLY_INTERNAL_MARK");
        $showGenderWiseAttendance = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, "EXAM_REGISTRATION_GENDER_WISE_ATTENDANCE_CHECK");
        if( $request->notConsiderValidation && $studentDetails && $enableFeSubjectForInternals ){
            $studentCurrentFeSubject = new \stdClass;
            $studentCurrentFeSubject->studentProgramAccountId = $studentDetails->studentProgramAccountId;
            $feSubjectList = [];
            $studentFeSubjects =  reset(MarksCardService::getInstance()->getStudentRegularFeSubjects($studentCurrentFeSubject));
            foreach($studentFeSubjects->failedSubjects as $key => $feSubject){
                $feSubjectList[$feSubject->paperSubjectId] = $feSubject->paperSubjectId;
            }
        }
        if($request->considerRegisteredAndApplied){
            $registeredSearchRequest = new \stdClass;
            $registeredSearchRequest->studentId = $request->studentId;
            $registeredSearchRequest->examRegistrationId = $request->examRegistrationId;
            $registeredSearchRequest->registrationStatus =  "REGISTERED_AND_APPLIED";
            $registeredSearchRequest->notConsiderEmptyValidation = true;
            $registerdStudentDetails = reset($this->getStudentExamRegistrationFeeDetails($registeredSearchRequest));
        }
        // remove FE students subject in student Exam registration
        if($request->isStudentSideRequest == 1){
            foreach($studentDetails->subjects as $key => $subject){
                $regularStudentHistory = reset(array_filter($subject->subjectMarkHistory,function($value){
                    return $value->examMarkType == "REGULAR";
                }));
                if($regularStudentHistory->studentAttendanceStatus == 'FE'){
                    unset($studentDetails->subjects[$key]);
                }
            }
        }
        $academicPaperSubjectBlocking = [];
        if($blockRegularBlockedSubject){
            $regularBlockReasons = [];
            // fetch regular blocked reasons
            $regularExamBlockedReasonRequest = new \stdClass;
            $regularExamBlockedReasonRequest->academicPaperSubjectId = [];
            $regularExamBlockedReasonRequest->examRegistrationId = "";
            $regularExamBlockedReasonRequest->studentId = $request->studentId;
            // this case to fetch only  subject wise ( block reason) & Hall ticket blocking (blocking type)
            // because blocking will be done only after student registration for regular exam, so blocking method will be hall ticket blocking, block reason type is subject wise
            $regularExamBlockedReasonRequest->blockingType = 'HALL_TICKET_BLOCKING';
            $regularExamBlockedReasonRequest->blockReasonType = 'SUBJECT_WISE';
            // fetch the corresponding regular exam id 
            $getRegularExamIdReg = new \stdClass;
            $getRegularExamIdReg->examRegistrationId =  $request->examRegistrationId;
            $getRegularExamIdReg->groupId =  $studentDetails->groupId;
            $regularExamBlockedReasonRequest->examRegistrationId = ExamRegistrationService::getInstance()->getRegularExamRegistrationIdBySupplyExamRegistrationId($getRegularExamIdReg);
            $regularExamBlockedReasonRequest->academicPaperSubjectId = array_column($studentDetails->subjects,'academicPaperSubjectId');
            if(!empty($regularExamBlockedReasonRequest->academicPaperSubjectId) && !empty( $regularExamBlockedReasonRequest->examRegistrationId)){
                $regularBlockReasons = BlockStudentMappingService::getInstance()->getStudentBlockReasonsDetails($regularExamBlockedReasonRequest);
                foreach($regularBlockReasons as $regularBlockReason){
                    $academicPaperSubjectBlocking[$regularBlockReason->academicPaperSubjectId]->blockReasons[$regularBlockReason->blockReasonId] = $regularBlockReason;
                }
            }
        }
        // remove MAL students subject in student Exam registration
        foreach($studentDetails->subjects as $subject){
            $subject->blockStudentTableId = $blockedUnblockedSubjects[$subject->academicPaperSubjectId] ? $blockedUnblockedSubjects[$subject->academicPaperSubjectId]->blockStudentTableId : null;
            $subject->unBlockStudentTableId = $blockedUnblockedSubjects[$subject->academicPaperSubjectId] ? $blockedUnblockedSubjects[$subject->academicPaperSubjectId]->unBlockStudentTableId : null;
        }
         // remove MAL students subject in student Exam registration
        //  remove Subject wise blocking regular exam in student side 
        if($request->isStudentSideRequest == 1){
            foreach($studentDetails->subjects as $key => $subject){
                if($subject->blockStudentTableId  && !$subject->unBlockStudentTableId){
                    unset($studentDetails->subjects[$key]);
                    $noSubjectErrorMessages[] = $subject->name ."due to mal practice";
                }
                if(!empty($academicPaperSubjectBlocking[$subject->academicPaperSubjectId])){
                    unset($studentDetails->subjects[$key]);
                    $blockReasons = $academicPaperSubjectBlocking[$subject->academicPaperSubjectId]->blockReasons;
                    $blockReasonNames = array_column( $blockReasons,'blockReasonName');
                    $noSubjectErrorMessages[] = $subject->name ." due to ".implode(',',$blockReasonNames);
                }
            }
        }
        if ($request->isStudentSideRequest && !$request->hideAlreadyExistCheck){
            $studentRegisterStatus = reset(array_filter($studentDetails->subjects,function($value){
                if($value->studentAssessmentRegistrationProperties->registrationStatus == "APPLIED" || $value->studentAssessmentRegistrationProperties->registrationStatus == "REGISTERED")
                return $value;
            }));
            if ( empty($studentRegisterStatus)){
                $registeredSearchRequest = new \stdClass;
                $registeredSearchRequest->studentId = $request->studentId;
                $registeredSearchRequest->examRegistrationId = $request->examRegistrationId;
                $registeredSearchRequest->registrationStatus =  "REGISTERED_AND_APPLIED";
                $registeredSearchRequest->notConsiderEmptyValidation = true;
                $alreadyRegisteredOrAppliedSubjcts = reset($this->getStudentExamRegistrationFeeDetails($registeredSearchRequest));
                $studentRegisterStatus = reset(array_filter($alreadyRegisteredOrAppliedSubjcts->subjects,function($value){
                    if($value->studentAssessmentRegistrationProperties->registrationStatus == "APPLIED" || $value->studentAssessmentRegistrationProperties->registrationStatus == "REGISTERED")
                    return $value;
                }));
            }
            if($studentRegisterStatus){
                if ( $studentRegisterStatus->studentAssessmentRegistrationProperties->registrationStatus == "APPLIED" && $studentRegisterStatus->studentAssessmentRegistrationProperties->feeStatus == "FAILED" && $studentRegisterStatus->studentAssessmentRegistrationProperties->paymentOption == "ONLINE_PAYMENT_METHOD"){
                    // do nothing
                }
                else{
                    $searchRequestForPayment = new \stdClass;
                    $searchRequestForPayment->studentId = $request->studentId;
                    $searchRequestForPayment->examRegistrationId = $request->examRegistrationId;
                    $studentPaymentStatusDetails = $this->searchStudentOnlinePayement($searchRequestForPayment);
                    if ($studentPaymentStatusDetails){
                        $studentRecentPaymentPendingStatus = reset(array_filter($studentPaymentStatusDetails,function($value){
                            return $value->status == "PENDING";
                        }));
                        if(empty($studentRecentPaymentPendingStatus)){
                            $eligibleForReapply = true;
                        }
                    }
                    else{
                        $eligibleForReapply = true;
                    }
                    if( $eligibleForReapply && $studentRegisterStatus->studentAssessmentRegistrationProperties->registrationStatus == "APPLIED" &&$studentRegisterStatus->studentAssessmentRegistrationProperties->paymentOption == "ONLINE_PAYMENT_METHOD"){
                        // do nothing
                    }
                    else{
                        throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,"Payment already initiated.");
                
                    }
                }
            }
        }
        $searchRequest->academicPaperSubjectId = $request->academicPaperSubjectId;
        if($studentDetails->blockReasons && !$request->notConsiderValidation) {
            $blockReasonMsg = "Registration Blocked ";
            foreach($studentDetails->blockReasons as $reason){
                $blockReasonMsg .= "<br> * Due to ".$reason->name .". ";
                $blockReasonMsg .= $reason->contactPersonName ? "Please contact ".$reason->contactPersonName :"";
                $blockReasonMsg .= $reason->contactPersonDecription ? " ".$reason->contactPersonDecription :"";
            }
            throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,$blockReasonMsg);
        }
        $improvementArray = ["SUPPLY_IMPROVEMENT","IMPROVEMENT"];
        if(in_array($studentDetails->examRegistrationProperties->examRegistrationType, $improvementArray)){
            $haveImprovement = true;
            $isImprovementOnly = $studentDetails->examRegistrationProperties->examRegistrationType == 'IMPROVEMENT'? true : false;
        }
        $isCombineSupplyOrImprovement = $studentDetails->examRegistrationProperties->combinedExamRegistration == '1' ? true : false;
        $groupId = $studentDetails->groupId;
        $searchRequest = new \stdClass;
        $searchRequest->groupId = $groupId;
        $searchRequest->academicTermId = $studentDetails->academicTermId;
        $searchRequest->type = ExamRegistrationTypeConstants::SUPPLEMENTARY;
        $searchRequest->odrerBy = "ASSENDING_EXAM_MONTH_AND_YEAR";
        $allSupplementaryExamRegistrations = ExamRegistrationService::getInstance()->searchExamRegistrationByOtherDetails($searchRequest);
        $regularOrSupply = ["REGULAR","SUPPLEMENTARY"];
        $regularOrSupplyForPassed = $isImprovementOnlyForRegularPassed ? ["REGULAR"] : ["REGULAR","SUPPLEMENTARY"];
        $studentDetails->supplyImproveTreatedAs = "NOTHING";
        $latestExamYearAndMonth = max(array_map(function($history){ return $history->examYear."-".date("m", mktime(0, 0, 0, (int)$history->examMonth, 10));},$studentDetails->semesterMarkHistory));
        foreach($studentDetails->semesterMarkHistory as $history){
            $examMonth = date("m", mktime(0, 0, 0, (int)$history->examMonth, 10));
            if($history->examYear.'-'.$examMonth ==  $latestExamYearAndMonth){
                $latestExamDetails = $history;
                break; 
            }
        }
        // this case add for SJC requirement
        // student could not register the improvemt exam while checking the corresponding cases
        // 1. student in corresponding course type (PG)
        // 2. student pass all subjects in parent exams 
        //  3.student have been passed in semester
        // 4.this case add for combine supply too
        if($checkIfBlockAllSubjectPassedAndSemesterFailedInImprovement && in_array($studentDetails->courseType,$checkIfBlockAllSubjectPassedAndSemesterFailedInImprovementConditionCourseTypes) && $haveImprovement){
            $studentPassedSubjects = array_filter($studentDetails->subjects,function($subject){
                return $subject->subjectFailedStatus == 'PASSED';
            });
            if( ($latestExamDetails->failedStatus == 'PASSED') && (count($studentPassedSubjects) == count($studentDetails->subjects))){
                throw new ExamControllerException (ExamControllerException::CANT_REGISTER_IMPROVEMENT_EXAM,"Not eligible to register improvement exam");
            }
            elseif(($latestExamDetails->failedStatus == 'FAILED') && (count($studentPassedSubjects) == count($studentDetails->subjects))){
                $isImprovementOnly = true;
                foreach($studentDetails->subjects as $subject){
                    $subject->supplyOrImprovement = ExamRegistrationTypeConstants::IMPROVEMENT;
                }
                $studentDetails->supplyImproveTreatedAs = ExamRegistrationTypeConstants::IMPROVEMENT;
            }
        }
        if($latestExamDetails->failedStatus == "PASSED" && in_array($latestExamDetails->historyType, $regularOrSupplyForPassed) && $haveImprovement){
            $countExamRegistrations = 0;
            foreach( $allSupplementaryExamRegistrations as $supplyExam){
                if($supplyExam->properties->examYear."-".date("m", mktime(0, 0, 0, (int)$supplyExam->properties->examMonth, 10)) > $latestExamYearAndMonth){
                    $countExamRegistrations ++;
                    if($supplyExam->id == $studentDetails->examRegistrationId){
                        foreach($studentDetails->subjects as $subject){
                            if($isNearByPassedExamAsImprovement){ 
                                if(in_array($subject->subjectMarkDetails->latestExamType, $regularOrSupplyForPassed) && $countExamRegistrations == 1 ){
                                    $passedMonthAndYear = $subject->subjectMarkDetails->latestExamYear."-".date("m", mktime(0, 0, 0, (int)$subject->subjectMarkDetails->latestExamMonth, 10));
                                    if($passedMonthAndYear ==  $latestExamYearAndMonth){
                                        $subject->supplyOrImprovement = ExamRegistrationTypeConstants::IMPROVEMENT;
                                        $studentDetails->supplyImproveTreatedAs = ExamRegistrationTypeConstants::IMPROVEMENT;
                                    }
                                    else{
                                        $subject->supplyOrImprovement = "NOTHING";
                                    }
                                }
                                else{
                                    $subject->supplyOrImprovement = "NOTHING";
                                }
                            }
                            else{
                                $subject->supplyOrImprovement = ExamRegistrationTypeConstants::IMPROVEMENT;
                                $studentDetails->supplyImproveTreatedAs = ExamRegistrationTypeConstants::IMPROVEMENT;
                            }
                        }
                        break;
                    } 
                }
            }
        }
        elseif($latestExamDetails->failedStatus == "FAILED" && in_array($latestExamDetails->historyType, $regularOrSupply) && !$isImprovementOnly){
            $countExamRegistrations = 0;
            if($isCombineSupplyOrImprovement && $haveImprovement){
                foreach( $allSupplementaryExamRegistrations as $supplyExam){
                    if($supplyExam->properties->examYear."-".date("m", mktime(0, 0, 0, (int)$supplyExam->properties->examMonth, 10)) > $latestExamYearAndMonth){
                        $countExamRegistrations ++;
                        if($supplyExam->id == $studentDetails->examRegistrationId){
                            $studentDetails->supplyImproveTreatedAs = ExamRegistrationTypeConstants::SUPPLEMENTARY;
                            foreach($studentDetails->subjects as $subject){
                                if($subject->subjectFailedStatus == "FAILED"){
                                    $subject->supplyOrImprovement = ExamRegistrationTypeConstants::SUPPLEMENTARY;
                                }
                                else{
                                    if($isNearByPassedExamAsImprovement){
                                        if(in_array($subject->subjectMarkDetails->latestExamType, $regularOrSupplyForPassed) && $countExamRegistrations == 1 ){
                                            $passedMonthAndYear = $subject->subjectMarkDetails->latestExamYear."-".date("m", mktime(0, 0, 0, (int)$subject->subjectMarkDetails->latestExamMonth, 10));
                                            if($passedMonthAndYear ==  $latestExamYearAndMonth){
                                                $subject->supplyOrImprovement = ExamRegistrationTypeConstants::IMPROVEMENT;
                                                $studentDetails->supplyImproveTreatedAs = "SUPPIMENTARY/IMPROVEMENT";
                                            }
                                            else{
                                                $subject->supplyOrImprovement = "NOTHING";
                                            }
                                        }
                                        else{
                                            $subject->supplyOrImprovement = "NOTHING";
                                        }
                                        
                                     }
                                    else{
                                        $subject->supplyOrImprovement =  ExamRegistrationTypeConstants::IMPROVEMENT;
                                        $studentDetails->supplyImproveTreatedAs = "SUPPIMENTARY/IMPROVEMENT";
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
            }
            else{
                foreach( $allSupplementaryExamRegistrations as $supplyExam){
                    if($supplyExam->properties->examYear."-".date("m", mktime(0, 0, 0, (int)$supplyExam->properties->examMonth, 10)) >= $latestExamYearAndMonth){
                        if($supplyExam->id == $studentDetails->examRegistrationId){
                            $studentDetails->supplyImproveTreatedAs = ExamRegistrationTypeConstants::SUPPLEMENTARY;
                            // if(($key = array_search('FAILED', array_column($studentDetails->subject,'subjectFailedStatus'))) !== FALSE) {
                            //     unset($studentDetails->subject[$key]);
                            // }
                            foreach($studentDetails->subjects as $key => $subject){
                                if($subject->subjectFailedStatus == 'PASSED'){
                                    unset($studentDetails->subjects[$key]);
                                }
                                else{
                                    $studentDetails->registeredSubjects[] = $subject;
                                }
                            }
                            $studentDetails->subjects = $studentDetails->registeredSubjects;
                            foreach($studentDetails->subjects as $key => $subject){
                                $subject->supplyOrImprovement = ExamRegistrationTypeConstants::SUPPLEMENTARY;
                            }
                            break;
                        }
                    }
                }
            }
        }
        if($studentDetails->supplyImproveTreatedAs == "NOTHING" && !$request->notConsiderEmptyValidation){
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Couldnot Register Exam");
        }
        $studentDetails->subjects = (array_filter($studentDetails->subjects,function($value){
            return $value->supplyOrImprovement != "NOTHING";
        }));
        if(($studentDetails->examRegistrationProperties->examRegistrationType == 'SUPPLY_IMPROVEMENT' || $studentDetails->examRegistrationProperties->examRegistrationType ==  ExamRegistrationTypeConstants::IMPROVEMENT ) && $studentDetails->supplyImproveTreatedAs ==  ExamRegistrationTypeConstants::IMPROVEMENT){
            $studentDetails->examRegistrationType =  ExamRegistrationTypeConstants::IMPROVEMENT;
        }
        else if(($studentDetails->examRegistrationProperties->examRegistrationType == 'SUPPLY_IMPROVEMENT' || $studentDetails->examRegistrationProperties->examRegistrationType == ExamRegistrationTypeConstants::SUPPLEMENTARY ) && $studentDetails->supplyImproveTreatedAs == ExamRegistrationTypeConstants::SUPPLEMENTARY){
            $studentDetails->examRegistrationType = ExamRegistrationTypeConstants::SUPPLEMENTARY;  
        }
        foreach($studentDetails->examRegistrationProperties->paymentMethods as $paymentMethod){
            if($paymentMethod == ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD;
                $currentPaymentMethod->name = "College Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::BANK_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::BANK_CHALLAN_METHOD;
                $currentPaymentMethod->name = "Bank Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD;
                $currentPaymentMethod->name = "Online Payment Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
        }
        $studentDetails->totalFeeAmount = 0;
         // ------------Studdent common Fees & Fines --------------- 
        if(count($studentDetails->batchFeeFine) > 1){
            $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
        }
        else{
            $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
        }
        $subjectCount = count($request->academicPaperSubjectId);
        if(empty($subjectCount)){
            $subjectCount = count($studentDetails->subjects);
        }
        if($request->considerRegisteredAndApplied){
            $subjectCount += count($registerdStudentDetails->subjects);
        }
        // ------------studdent common Fees --------------- 
        $studentDetails->commonFees = [];   
        $studentDetails->totalCommonFees = 0;  
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REGULAR';
        $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRegistrationType;
        }));
        $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
        $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
        $subjectLimitFees = [];
        $subjectLimitCounts = [];
        foreach($allCommonFees as $commonFee){
            if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject != '1'){
                    if($studentCommonFees->feeType[$commonFee->id]->value){
                        $currentFee = new \stdclass;
                        $currentFee->feeName = $commonFee->name;
                        $currentFee->isSubjectFeeLimit = $commonFee->isSubject_fee_limit;
                        $currentFee->value = $currentFee->isSubjectFeeLimit ? 0 : $studentCommonFees->feeType[$commonFee->id]->value;
                        $currentFee->currentValue = $studentCommonFees->feeType[$commonFee->id]->value;
                        $currentFee->maxValue = $currentFee->isSubjectFeeLimit ? $studentCommonFees->feeType[$commonFee->id]->maxValue : 0;
                        if($currentFee->isSubjectFeeLimit && $subjectCount > 0){
                            $currentFee->value = $currentFee->currentValue * $subjectCount;
                            if($currentFee->value > $currentFee->maxValue){
                                $currentFee->value = $currentFee->maxValue;
                            }
                        }
                        $studentDetails->totalCommonFees += $currentFee->value;
                        $studentDetails->commonFees[] = $currentFee;
                    }
                }
                else if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject == '1'){
                    if($disableSubjectSelection){
                        if($commonFee->feeSelectionSubjectLimit && $studentCommonFees->feeType[$commonFee->id]->value){
                            $subjectLimitFees[$commonFee->feeSelectionSubjectLimit] =  $studentCommonFees->feeType[$commonFee->id]->value;
                            $subjectLimitCounts[$commonFee->feeSelectionSubjectLimit] = $commonFee->feeSelectionSubjectLimit;
                            
                        }
                    }
                    
                } 
            }
        }
        if(!empty($subjectLimitFees)){
            $subjectCount = count($studentDetails->subjects);
            sort($subjectLimitCounts);
            $index = array_search($subjectCount, $subjectLimitCounts);
            $resultIndex = ($index !== false && $subjectLimitCounts[$index] == $subjectCount) ? $subjectLimitCounts[$index] : (empty($subjectLimitCounts) ? null : max(array_filter($subjectLimitCounts, function($value) use ($subjectCount) {
                return $value <= $subjectCount;
            })));
            if(!empty($subjectLimitFees[$resultIndex])){
                $currentFee = new \stdclass;
                $currentFee->feeName = "Total Subject Fee";
                $currentFee->isSubjectFeeLimit = 0;
                $currentFee->value = $subjectLimitFees[$resultIndex];
                $studentDetails->totalCommonFees += $currentFee->value;
                $studentDetails->commonFees[] = $currentFee;
            }
        }
        // ------------studdent common Fines ---------------    
        $studentDetails->commonFines = []; 
        $studentDetails->totalCommonFines = 0;
        $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
        $studentCommonFines = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFines,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRegistrationType;
        }));
        $studentCommonFineIdsArray = array_keys((array)$studentCommonFines->fineType);
        $studentCommonFines->fineType = (array)$studentCommonFines->fineType;
        $today = date("Y-m-d H:i");
        if ( $request->considerChallanVerifyDate ) {
            $today = $studentDetails->examRegistrationPaymentProperties->challanAppliedDate? $studentDetails->examRegistrationPaymentProperties->challanAppliedDate :date("Y-m-d H:i");
        }
        if($request->considerRegisteredAndApplied && !empty($registerdStudentDetails)){
            $today = $registerdStudentDetails->studentEntryCreatedDate? $registerdStudentDetails->studentEntryCreatedDate :date("Y-m-d H:i");
        }
        // $maxEndDate = $studentDetails->examRegistrationProperties->registrationWithoutFineEndDate;
        foreach($allCommonFines as $commonFine){
            if ( in_array ( $commonFine->id, $studentCommonFineIdsArray ) ) {
                $maxEndDate = $maxEndDate ?? $studentCommonFines->fineType[$commonFine->id]->endDate;
                $minStartDate = $minStartDate ?? $studentCommonFines->fineType[$commonFine->id]->startDate;
                if((strtotime($today) >= strtotime($studentCommonFines->fineType[$commonFine->id]->startDate)) && ($today <= $studentCommonFines->fineType[$commonFine->id]->endDate )){
                    $currentFine = new \stdclass;
                    $currentFine->fineName = $commonFine->name;
                    $currentFine->value = $studentCommonFines->fineType[$commonFine->id]->value;
                    $studentDetails->totalCommonFines += $currentFine->value;
                    $studentDetails->commonFines[] = $currentFine;
                    // if($studentCommonFines->fineType[$commonFine->id]->endDate >= $maxEndDate){
                    //     $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                    // }
                    if(strtotime($studentCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($maxEndDate)){
                        $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                    }
                    if(strtotime($studentCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($minStartDate)){
                        $minStartDate = $studentCommonFines->fineType[$commonFine->id]->startDate;
                    }
                } 
            }
        }
        // ------------Remove Internal Only Subject --------------- 
        $studentDetails->registeredSubjects = [];
        foreach($studentDetails->subjects as $key=> $subject){ 
            if(($request->isStudentSideRequest == 1 )&& !($isAvoidConditionForInternalOnlySubjectInExamRegistrationStudentSide)){
                if($subject->isExternal != '1'){
                    unset($studentDetails->subjects[$key]);
                }
                else{
                    $studentDetails->registeredSubjects[] = $subject;
                }
            }
            else{
                if( $request->notConsiderValidation && $enableFeSubjectForInternals){
                    if ( $feSubjectList[$subject->id] ){
                        $feSubjectRequest = new \stdClass();
                        $feSubjectRequest->paperSubId = $subject->academicPaperSubjectId;
                        $feSubjectRequest->studentProgramId = $studentDetails->studentProgramAccountId;
                        $subjectCommunity  = StudentService::getInstance()->getFeCommunityStudentAttendanceAndInternal($feSubjectRequest);
                        $subject->hasFeConsideration = true;
                        $regularSubjectHistory = reset(array_filter($subject->subjectMarkHistory,function($value){
                            return $value->examMarkType == "REGULAR";
                        }));
                        $requestForExamRegistration = new SearchExamRegistrationRequest;
                        $requestForExamRegistration->id = $regularSubjectHistory->examRegistrationId;
                        $regularExamRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration));
                        $subject->feStatusChanged = 1;
                        if($showGenderWiseAttendance){
                            $regularExamRegistration->properties->genderWiseMinimumAttendance = (array) $regularExamRegistration->properties->genderWiseMinimumAttendance;
                            if ( $regularExamRegistration->properties->genderWiseMinimumAttendance[strtoupper($studentDetails->studentGender)] ){
                                $regularExamRegistration->properties->minimumAttendancePercentage = $regularExamRegistration->properties->genderWiseMinimumAttendance[strtoupper($studentDetails->studentGender)];
                            }
                        }
                        $minimumAttendancePercentage = $regularExamRegistration->properties->minimumAttendancePercentage;
                        if( $subjectCommunity->attendancePercentage->attendancePercentage <  $minimumAttendancePercentage){
                            $subject->feStatusChanged = 0;
                        }
                        if ( $subject->isInternal == 1 &&  $subject->isExternal != 1){
                            $schemeType = "PERCENTAGE";
                            $passCriteria = GradeSchemeService::getInstance()->getSubjectPassCriteriaByAcademicPaperSubject($subject->academicPaperSubjectId, $schemeType);
                            $internalPassCriteria = $overallPassCriteria = null;
                            $internalPassCriteria = $passCriteria->internalPassCriteria;
                            $overallPassCriteria = $passCriteria->overallPassCriteria;
    
                            $internalPercent = $subject->internalMaxMark ? (100 * $subject->internalMark/ $subject->internalMaxMark) : 0;
                            if ( $internalPercent < $internalPassCriteria || $internalPercent < $overallPassCriteria ){
                                $subject->feStatusChanged = 0;
                            }
                        }
                        $subject->feNewEnteredInternalMark = $subjectCommunity->internalMark->mark;
                    }
                    
                }
                $studentDetails->registeredSubjects[] = $subject;
            }
        }
        $studentDetails->subjects = $studentDetails->registeredSubjects;
        
        // ------------Studdent Subject Fees --------------- 
        $studentDetails->totalSubjectFees = 0;
        $feeAddedSubjectIds = [];
        $studentDetails->paidAmount = 0;
        $subjecSelectionCount = count($request->academicPaperSubjectId);
        foreach($studentDetails->subjects as $subject){
            $subject->isRegistered = false;
            $subject->isApplied = false;
            // $subject->isSelected = false;
            if($disableSubjectSelection){
                $subject->isSelected = true;
                $subject->isShowSelected = true;
                $subject->disableSubjectSelection = true;
            }
            else{
                $subject->isSelected = false;
                $subject->isShowSelected = false;
                $subject->disableSubjectSelection = false;
            }
            $subject->isDeleted = false;
            $subject->isAlreadyRegistered = false;
            if( $subjecSelectionCount ){
                if(!in_array($subject->academicPaperSubjectId,$request->academicPaperSubjectId)){
                    $subject->isDeleted = true;
                }
            }
            $subject->currentSubjectFeeProperties = reset(array_filter($subject->subjectFeeProperties,function($value)use($subject){
                return $value->examRegistrationType == $subject->supplyOrImprovement;
            }));
            $subject->currentSubjectFeeProperties->feeType = (array)$subject->currentSubjectFeeProperties->feeType;
            $subject->subjectFeeTemplateIdsArray = array_keys($subject->currentSubjectFeeProperties->feeType);
            $subject->currentFeeTypeTemplateId = ExamRegistrationFeeCommonService::getInstance()->getCurrentSubjectFeeTemplateForStudent($subject,$studentDetails);
            $subject->value =  $subject->currentFeeTypeTemplateId ? $subject->currentSubjectFeeProperties->feeType[$subject->currentFeeTypeTemplateId]->value : 0;
            if($disableSubjectSelection){
                $studentDetails->totalSubjectFees += $subject->value;
            }
            else if ( !$request->removeSubjectFeeForNotApplied ){
                $studentDetails->totalSubjectFees += $subject->value;
            }
            $feeAddedSubjectIds[$subject->id] = $subject->id;
            // if( !$subject->isDeleted ){
            //     if(in_array($subject->academicPaperSubjectId,$request->academicPaperSubjectId)){
            //         $studentDetails->totalSubjectFees += $request->featchAllFees ? $subject->value : 0;
            //         $subject->hasAdded = 1;
            //     }
            // }
            // if(!empty($subject->studentAssessmentRegistrationProperties) ){
            //     if($subject->studentAssessmentRegistrationProperties->registrationStatus == 'REGISTERED'){
            //         if(in_array($subject->academicPaperSubjectId,$request->academicPaperSubjectId)){
            //             $subject->isAlreadyRegistered = true;
            //         }
            //         $subject->isRegistered = true;
            //         $subject->isApplied = false;
            //         if( !$subject->isDeleted && !$subject->hasAdded){
            //             $studentDetails->totalSubjectFees +=  $request->featchAllFees ? 0 : $subject->value ;
            //         }
            //         $subject->isSelected = true;
            //         $subject->isShowSelected = true;
            //         $studentDetails->paidAmount += $subject->value;
            //     }
            //     else if($subject->studentAssessmentRegistrationProperties->registrationStatus == 'APPLIED'){
            //         $subject->isRegistered = false;
            //         $subject->isApplied = true;
            //         if( !$subject->isDeleted && !$subject->hasAdded){
            //             $studentDetails->totalSubjectFees +=  $request->featchAllFees ?  $subject->value : 0;
            //         }
            //     }
            // }
        }
        $studentDetails->totalSubjectFeesNotApplied = $studentDetails->totalSubjectFees;
        $totalFeeAmount = 0;
        if($request->considerRegisteredAndApplied){
            foreach($registerdStudentDetails->subjects as $subject){
                if( !in_array($subject->id, $feeAddedSubjectIds)){
                    $subject->currentSubjectFeeProperties = reset(array_filter($subject->subjectFeeProperties,function($value)use($registerdStudentDetails){
                        return $value->examRegistrationType == $registerdStudentDetails->examRegistrationType;
                    }));
                    $subject->currentSubjectFeeProperties->feeType = (array)$subject->currentSubjectFeeProperties->feeType;
                    $subject->subjectFeeTemplateIdsArray = array_keys($subject->currentSubjectFeeProperties->feeType);
                    $subject->currentFeeTypeTemplateId = ExamRegistrationFeeCommonService::getInstance()->getCurrentSubjectFeeTemplateForStudent($subject,$studentDetails);
                    $subject->value =  $subject->currentFeeTypeTemplateId ? $subject->currentSubjectFeeProperties->feeType[$subject->currentFeeTypeTemplateId]->value : 0;
                    $studentDetails->totalSubjectFees += $subject->value;
                }
                
            }
        }
        $totalFeeAmount = $studentDetails->totalCommonFines + $studentDetails->totalCommonFees + $studentDetails->totalSubjectFees;
        // if(!$request->featchAllFees){
        //     if($studentDetails->totalSubjectFees > 0){
        //         $studentDetails->totalFeeAmount = $totalFeeAmount;
        //     }
        //     else{
        //         $studentDetails->totalFeeAmount = 0;
        //     }
        // }
        // else{
        //     $studentDetails->totalFeeAmount = $totalFeeAmount;
        // }
        $studentDetails->totalFeeAmount = $totalFeeAmount;
        
        $studentDetails->balanceAmount = 0;
        $studentDetails->balanceAmountCopy = 0;
        $studentDetails->paidAmount = 0;
        $studentDetails->amountTobePaid = $totalFeeAmount;
        $studentDetails->allCommonFees = $studentDetails->commonFees;
        $studentDetails->allCommonFines = $studentDetails->commonFines;
        if($request->considerRegisteredAndApplied && !empty($registerdStudentDetails)){
            $studentDetails->commonFines = [];
            $studentDetails->commonFees = [];
            $studentDetails->totalSubjectFees = $studentDetails->totalSubjectFeesNotApplied;
        }
        // if($studentDetails->balanceAmountDetails){
        //     $studentDetails->balanceReturnedStatus = $studentDetails->balanceAmountDetails->balanceReturnedStatus ? true : false;
        //     if($studentDetails->balanceAmountDetails->balanceAmount && $studentDetails->balanceAmountDetails->balanceReturnedStatus == false){
        //         $studentDetails->balanceAmount = (int)$studentDetails->balanceAmountDetails->balanceAmount;
        //     }
        // }
        // $studentDetails->balanceAmountCopy = $studentDetails->balanceAmount;
        // $studentDetails->paidAmount = $studentDetails->paidAmount ? $studentDetails->paidAmount + $studentDetails->totalCommonFees + $studentDetails->totalCommonFines : 0;
        // $studentDetails->totalStudentFee = $studentDetails->totalSubjectFees ? $studentDetails->totalSubjectFees + $studentDetails->totalCommonFees + $studentDetails->totalCommonFines : 0;
        // if(!$request->featchAllFees){
        //     $studentDetails->totalFeeAmount = $studentDetails->paidAmount;
        // }
        // // ---------------- Calculation For save student registration-------------
        // if(($studentDetails->paidAmount >= $studentDetails->totalStudentFee)){
        //     $studentDetails->amountTobePaid = 0;
        //     $studentDetails->balanceAmount += $studentDetails->paidAmount - $studentDetails->totalStudentFee;
        // }
        // else{
        //     $amountTobePaid = $studentDetails->totalStudentFee - $studentDetails->paidAmount;
        //     if($amountTobePaid > $studentDetails->balanceAmount){
        //         $studentDetails->amountTobePaid = $amountTobePaid - $studentDetails->balanceAmount;
        //         $studentDetails->balanceAmount = 0;
        //     }
        //     else{
        //         $studentDetails->balanceAmount -= $amountTobePaid;
        //         $studentDetails->amountTobePaid = 0;
        //     }
        // }
        
        $studentDetails->subjectLimit = $studentDetails->examRegistrationProperties->subjectLimit == 'All' ? 'ALL' :(int)$studentDetails->examRegistrationProperties->subjectLimit ;
        $studentDetails->registeredSubjects = $registerdStudentDetails->subjects ? $registerdStudentDetails->subjects : [];
        $studentDetails->registrationNote = $ruleObj->rule->registrationNote;
        if(empty($studentDetails->subjects) && !$request->notConsiderEmptyValidation){
            if($noSubjectErrorMessages){
                $blockReasonMsg = "";
                foreach($noSubjectErrorMessages as $noSubjectError){
                    $blockReasonMsg .= $noSubjectError."<br> ";
                }
                throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,$blockReasonMsg);
            }
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Couldnot Register Exam !!");
        }
        if (strtotime($studentDetails->examRegistrationProperties->registrationStartDate) > strtotime(date("Y-m-d H:i")) && !$request->notConsiderValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration not started");
        }
        elseif ( strtotime($maxEndDate)  < strtotime(date("Y-m-d H:i")) && !$request->notConsiderValidation && !$request->hidePaymentValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration closed");
        }
        else{
            // sort the subject by academics order
            usort($studentDetails->subjects, function ($a, $b) {
                return $a->subjectPriority > $b->subjectPriority;
            });
            return($studentDetails);  
        }
        
    }
    /**
     * search All Student Details By ExamRegistration
     * @param $request
     * @return studentDetails
     */
    public function searchAllStudentDetailsByExamRegistration($request){
        try{
            $responseData = new \stdClass;
            $request->limitStart = $request->limitStart ? (int)$request->limitStart : 0;
            if($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED){
                $request->registrationStatus = StudentExamRegistrationStatus::REGISTERED;
            }
            else if($request->registrationStatus == StudentExamRegistrationStatus::APPLIED){
                $request->registrationStatus = StudentExamRegistrationStatus::APPLIED;
            }
            $requestForExamRegistration = new SearchExamRegistrationRequest;
            $requestForExamRegistration->id = $request->examRegistrationId;
            $examRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration));
            if($examRegistration->type == ExamRegistrationTypeConstants::SUPPLEMENTARY){
                $request->examType = ExamRegistrationTypeConstants::SUPPLEMENTARY;
            }
            $studentDetails = $this->getAllStudentDetailsByExamRegistration($request);
            $studentDetails = (array)$studentDetails;
            array_walk($studentDetails, function($student,$key) {
                $student->modeOfTransaction = "Back end Method";
                $student->modeOfTransactionId =  '-';
                if($student->registrationProperties->paymentOption =="ONLINE_PAYMENT_METHOD"){
                    $student->modeOfTransaction = "Online Method";
                    $student->modeOfTransactionId =  $student->registrationProperties->onlinePaymentTransactionId;
                    $student->transactionDate =  date("d-m-Y h:i A", strtotime( $student->registrationProperties->onlinePaymentTransactionDate));
                }
                else if ($student->registrationProperties->paymentOption =="COLLEGE_CHALLAN_METHOD"){
                    $student->modeOfTransaction = "College Challan";
                    $student->modeOfTransactionId = $student->challanNo;
                    $student->transactionDate = $student->challanVerifyDate ? date("d-m-Y h:i A", strtotime( $student->challanVerifyDate)) : "";
                }
                $student->challanVerifyDate = $student->challanVerifyDate ? date("d-m-Y h:i A", strtotime( $student->challanVerifyDate)) : "";
                $student->isExpand = false;
            });
            if(!empty($studentDetails)){
                if(reset($studentDetails)->isPubishExamRegistration != '1'){
                    throw new ExamControllerException (ExamControllerException::EXAM_REGISTRATION_NOT_PUBLISHED,"Exam Registration Not Published.");
                }
            }
            $responseData->totalStudentCount = count($studentDetails);
            ksort($studentDetails);
            if(!$request->getStudentsWithoutSlice){
                if (isset($request->offset) && $request->offset>=0){
                    if (isset($request->limitStart) && $request->limitStart>=0) {
                        $studentDetails = array_slice($studentDetails,(int)$request->limitStart,(int)$request->offset);
                    }
                    else{
                        $studentDetails = array_slice($studentDetails,0,(int)$request->offset);
                    }
                }
            }
            $responseData->studentDetails = $studentDetails;
            return $responseData;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
    /**
     * get All Student Details By ExamRegistration
     * @param $request
     * @return studentDetails
     */
    public function getAllStudentDetailsByExamRegistration($request){
        try{
            $request = $this->realEscapeObject($request);
            $whereQuery = "";
            $limitQuery = "";
            $joinQueary = "";
            $selectColumns = "";
            $sortBy = " ORDER BY spa.properties->>'$.registerNumber' ASC , COALESCE(cap.properties ->> '$.order', 0) * 100 + COALESCE(caps.properties ->> '$.order', 0) ASC ";
            if(!empty($request->examRegistrationId)){
                $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            if($request->examType == ExamRegistrationTypeConstants::SUPPLEMENTARY){
                $joinQueary .= " INNER JOIN ec_semester_mark_details esmdsem ON
                                    esmdsem.groups_id = eerb.groups_id 
                                    AND esmdsem.academic_term_id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
                                INNER JOIN student_program_account spa ON 
                                    spa.student_id =  esmdsem.student_id
                                INNER JOIN studentaccount sa ON
                                    sa.studentID = spa.student_id
                                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 = spa.student_id ";
                $selectColumns .= ",esmdsem.mark_details ->>'$.percentage' AS semesterPercentage,
                                    esmdsem.mark_details AS semesterMarkDetails,
                                    esmdsem.mark_history AS semesterMarkHistory,
                                    esmdsem.failed_status AS semesterFailedStatus,
                                    esmdsubcon.failed_status AS subjectFailedStatus,
                                    esmdsubcon.mark_details ->>'$.percentage' AS subjectPercentage,
                                    esmdsubcon.mark_details AS subjectMarkDetails,
                                    esmdsubcon.mark_history AS subjectMarkHistory";
            }
            else{
                if($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::APPLIED){
                    $joinQueary .= " INNER JOIN group_members gm ON
                                    gm.groups_id = g.id
                                INNER JOIN student_program_account spa ON 
                                    spa.id  = gm.members->>'$.studentId'
                                INNER JOIN studentaccount sa ON
                                    sa.studentID = spa.student_id
                                INNER JOIN `groups` sg ON
                                    sg.paperSubjectId = caps.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') ";
                }else{
                    $joinQueary .= " INNER JOIN group_members gm ON
                                    gm.groups_id = g.id
                                INNER JOIN student_program_account spa ON 
                                    spa.id  = gm.members->>'$.studentId'
                                INNER JOIN studentaccount sa ON
                                    sa.studentID = spa.student_id
                                INNER JOIN student_program_batch_log spbl ON
                                    spbl.batch_group_id = g.id AND
                                    spbl.term_id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR) AND
                                    spbl.program_student_id = spa.id 
                                    AND spbl.properties->>'$.academicStatus' IN ('ACTIVE','COMPLETED')
                                INNER JOIN `groups` sg ON
                                    sg.paperSubjectId = caps.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') ";
                }
            }
            if(!empty($request->registrationStatus)){
                if($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::APPLIED){
                    $joinQueary .= " INNER JOIN ec_student_assessment_registration esar ON
                            esar.student_id = sa.studentID AND  esar.am_assessment_id = eers.am_assessment_id AND esar.ec_exam_registration_type = eer.type
                            INNER JOIN ec_student_exam_registration_details eserd ON
                            eserd.student_id = sa.studentID AND eserd.ec_exam_registration_id = eer.id";
                    $selectColumns .= ",eserd.properties as registrationProperties,eserd.total_fee as totalFee,eserd.properties ->> '$.challanNo' as challanNo,eserd.properties ->> '$.challanVerifyDate' as challanVerifyDate";
                    $whereQuery .= $request->registrationStatus == StudentExamRegistrationStatus::REGISTERED ? " AND esar.properties ->> '$.registrationStatus' = 'REGISTERED' AND esar.properties ->> '$.feeStatus' = 'PAID'" : " AND esar.properties ->> '$.registrationStatus' = 'APPLIED'";
                }
                else{
                    $joinQueary .= " LEFT JOIN ec_student_assessment_registration esar ON
                        esar.student_id = sa.studentID AND  esar.am_assessment_id = eers.am_assessment_id AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED','APPLIED') AND esar.ec_exam_registration_type = eer.type ";
                    $whereQuery .= " AND esar.id IS NULL";
                }
            }
            if(!empty($request->registerNo)){
                $whereQuery .= " AND spa.properties->>'$.registerNumber' = '$request->registerNo'";
            }
            if(!empty($request->groupId)){
                $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if(!empty($request->academicTermId)){
                $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
                $whereQuery .= " AND eerb.properties ->> '$.academicTermId' IN ( $academicTermIdString )";
            }
            if(!empty($request->departmentId)){
                $departmentIdString = is_array($request->departmentId) ? "'" . implode("','",$request->departmentId) . "'" : "'".$request->departmentId."'";
                $whereQuery .= " AND g.properties ->> '$.departmentId' IN ( $departmentIdString )";
            }
            if(!empty($request->studentId)){
                $studentIdString = is_array($request->studentId) ? implode(",",$request->studentId) : $request->studentId;
                $whereQuery .= " AND sa.studentID IN ( $studentIdString )";
            }
            $query = "SELECT DISTINCT
                sa.studentID as studentId,
                sa.studentName,
                sa.studentEmail,
                sa.studentPhone,
                spa.properties->>'$.registerNumber' AS registerNo,
                sa.reservationID,
                eer.id as examRegistrationId,
                eer.name as examRegistrationName,
                eer.properties->>'$.description' as examRegistrationDescription,
                eer.type as examRegistrationType,
                eer.properties as examRegistrationProperties,
                eerb.groups_id as groupId,
                eer.properties->>'$.publish' as isPubishExamRegistration,
                eerb.properties ->> '$.academicTermId' as academicTermId,
                eerb.properties AS batchProperties,
                eerb.fees_properties as batchFeeProperties,
                g.name AS groupName,
                d.deptName as deptCode,
                d.departmentDesc as deptName,
                eeft.id as batchFeeTemplateId,
                eeft.fee_properties as batchCommonFees,
                eeft.fine_properties as batchCommonFines,
                IF (eeft.operation_properties  IS NULL,0,1) as isConsiderOperation,
                eeft.operation_properties as batchOperationProperties,
                eers.fees_properties as subjectFeeProperties,
                eers.am_assessment_id as assessmentId,
                caps.id AS academicPaperSubjectId,
                esar.id AS studentAssessmentRegistrationId,
                esar.properties as studentAssessmentRegistrationProperties,
                esar.properties ->> '$.registrationStatus' as studentRegistrationStatus,
                esar.properties ->> '$.paymentOption' as studentRegistrationPaymentOption,
                s.code AS subjectCode,
                caps.properties ->> '$.syllabusName' AS syllabusName,
                s.name AS subjectName,
                slot.id AS slotId,
                slot.name AS slotName
                $selectColumns
            FROM
                ec_exam_registration eer
            INNER JOIN ec_exam_registration_batch eerb ON
                eerb.ec_exam_registration_id = eer.id 
            INNER JOIN `groups` g ON
                g.id = eerb.groups_id
                AND g.`type` = 'BATCH' 
            INNER JOIN department d ON
                d.deptID = g.properties ->> '$.departmentId'
            INNER JOIN ec_examregistration_fee_templates_mapping eeftm ON
                eeftm.id = eerb.fees_properties->>'$.feeTemplateId'
            INNER JOIN ec_examregistration_fee_templates eeft ON
                eeft.ec_examregistration_fee_templates_mapping_id = eeftm.id
            INNER JOIN ec_exam_registration_subject eers ON
                eers.ec_exam_registration_batch_id = eerb.id
            INNER JOIN cm_academic_paper_subjects caps ON
                caps.id = eers.cm_academic_paper_subjects_id
            INNER JOIN cm_academic_paper cap ON 
                caps.cm_academic_paper_id = cap.id
            INNER JOIN v4_ams_subject s ON
                s.id = caps.ams_subject_id
            LEFT JOIN cm_common_list_object slot ON slot.id =  caps.slot_id
            $joinQueary 
            WHERE
                eer.trashed IS NULL ";
            $studentDetails = $this->executeQueryForList($query.$whereQuery.$sortBy.$limitQuery, $this->mapper[StudentExamRegistrationServiceMapper::SEARCH_STUDENT_EXAM_REGISTRATION_FEE_DETAILS]);
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        return $studentDetails;
    }
     /**
     * Delete Student registration (Soft Delete)
     * @param String $id
     * @return NULL
     */
    public function deleteStudentRegistrationDetails($id){
        $id = $this->realEscapeString($id);
        if(empty($id)) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_STUDENT_REGISTRATION,"Student registration not found. Please try again!");
        }
        $query = "DELETE FROM
                ec_student_exam_registration_details 
            WHERE 
                id = '$id'";
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_DELETING_STUDENT_REGISTRATION,"Error deleting student registration! Please try again");
        }
    }
    /** 
     * get Exam MarkEntry For ExamRegistration
     * @param $request
     * @throws ExamControllerException
     */
    public function getExamMarkEntryForExamRegistration($searchRequest){
        $searchRequest = $this->realEscapeObject($searchRequest);
        $whereQuery = "";
        if(!empty($searchRequest->groupId)) {
            $groupIdString = is_array($searchRequest->groupId) ? "'" . implode("','",$searchRequest->groupId) . "'" : "'".$searchRequest->groupId."'";
            $whereQuery .= " AND g.id IN ( $groupIdString )";
        }
        if(!empty($searchRequest->academicPaperSubjectId)) {
            $academicPaperSubjectIdString = is_array($searchRequest->academicPaperSubjectId) ? "'" . implode("','",$searchRequest->academicPaperSubjectId) . "'" : "'".$searchRequest->academicPaperSubjectId."'";
            $whereQuery .= " AND eers.cm_academic_paper_subjects_id IN ( $academicPaperSubjectIdString )";
        }
        if(!empty($searchRequest->examRegistrationId)) {
            $examRegistrationIdString = is_array($searchRequest->examRegistrationId) ? "'" . implode("','",$searchRequest->examRegistrationId) . "'" : "'".$searchRequest->examRegistrationId."'";
            $whereQuery .= " AND eerb.ec_exam_registration_id IN ( $examRegistrationIdString )";
        }
        if(!empty($searchRequest->studentId)) {
            $studentIdString = is_array($searchRequest->studentId) ? "'" . implode("','",$searchRequest->studentId) . "'" : "'".$searchRequest->studentId."'";
            $whereQuery .= " AND esar.student_id IN ( $studentIdString )";
        }
        if(!empty($searchRequest->considerMarkEntry)) {
            $whereQuery .= " AND oetm.mark_obtained IS NOT NULL AND oetm.mark_obtained != '' ";
        }
        $query = "SELECT DISTINCT
                        oetm.id
                    FROM
                        `groups` g
                    INNER JOIN ec_exam_registration_batch eerb ON
                        eerb.groups_id = g.id
                    INNER JOIN ec_exam_registration_subject eers ON
                        eers.ec_exam_registration_batch_id = eerb.id
                    INNER JOIN ec_exam_registration eer ON
                        eer.id = eerb.ec_exam_registration_id
                    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 oe_student_total_mark oetm ON 
                        oetm.student_id = esar.student_id AND oetm.am_assessment_id = esar.am_assessment_id 
                    WHERE 1=1 ";
        try {
            $examMarkEntry =  $this->executeQueryForList($query.$whereQuery);
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $examMarkEntry;
    }
    /**
     * Search stduent Exam Revaluation
     * @param SearchStudentExamRegistrationRequest $request
     * @return examRevaluation
     */
    public function getAllRevaluationsForStudentRegistration(SearchStudentExamRegistrationRequest $request){
        $registrationStatus = ["APPLIED","REGISTERED"];
        $request->mappingType = "EXAM_REGISTRATION";
        $examRevaluations = $this->getStudentRevaluationDetails($request);
        //new digital valuation properties
        $digitalValuationProperties = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_CONTROLLER, SettingsConstents::DIGITAL_VALUATION_PROPERTIES);
        $digitalValuationProperties = $digitalValuationProperties ? current(json_decode($digitalValuationProperties)->revaluation) : "";
        $fileNameExtension = $digitalValuationProperties->fileNameExtension ? $digitalValuationProperties->fileNameExtension :"PDF";
        // fetch All Revaluation Fee Types
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REVALUATION';
        $allRevaluationFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $markEntryNotNeededFeeTypes = array_column(array_filter($allRevaluationFees,function($value){
            return $value->markEntryNeeded != "1";
        }),"id");
        foreach ($examRevaluations as $examRevaluation) {
            $examRevaluation->subjectPhotoCopyList = [];
            $examRevaluation->isApplied = false;
            $examRevaluation->isBlocked = false;
            $examRevaluation->isRegistered = false;
            $examRevaluation->canRegister = true;
            $examRevaluation->blockReasons = [];
            $challanVerificationDate = $examRevaluation->examRevaluationBatchProperties->registrationValuationDate;
            $examRevaluation->paymentOption = $examRevaluation->examRegistrationPaymentProperties->paymentOption;
            $examRevaluation->isAppliedButPaymentFailed = false;
            $examRevaluation->isChallanExperied = true;
            if($challanVerificationDate && strtotime($challanVerificationDate) >= strtotime($today)){
                $examRevaluation->isChallanExperied = false;
            }
            if (strtotime($examRevaluation->registrationStartDate) > strtotime(date("Y-m-d"))) {
                $examRevaluation->isNotStarted = true;
                $examRevaluation->canRegister = false;
                $examRevaluation->isBlocked = true;
                $examRevaluation->blockReasons = ["Registration not started"];
            }
            elseif (strtotime($examRevaluation->registrationEndDate)  < strtotime(date("Y-m-d"))) {
                $examRevaluation->isClosed = true;
                $examRevaluation->isBlocked = true;
                $examRevaluation->canRegister = false;
                $examRevaluation->blockReasons = ["Registration closed"];
            }
            foreach($examRevaluation->subjects as $subject){
                $subject->isAbsent = $subject->subjectMarkDetails->attendanceStatus == 'ABSENT' ? true : false;
                $subject->isMalPractice = $subject->subjectMarkDetails->attendanceStatus == 'MALPRACTICE' ? true : false;
                $subject->isApplied = false;
                if(!empty($subject->studentAssessmentRegistrations)){
                    foreach($subject->studentAssessmentRegistrations as $studentAssessmentRegistration){
                        if(in_array($studentAssessmentRegistration->studentRegistrationStatus,$registrationStatus)){
                            $subject->revaluationTypes[] =  $studentAssessmentRegistration->studentRevaluationType;
                            $subject->isApplied = true;
                            $subject->isRegistered = $studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::REGISTERED ? true : false;
                            if( !$examRevaluation->isRegistered && $studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::REGISTERED){
                                $examRevaluation->isRegistered = true;
                            }
                            if( !$examRevaluation->isApplied && $studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::APPLIED){
                                $examRevaluation->isApplied = true;
                            }
                            if($studentAssessmentRegistration->studentFeeStatus == 'PAID' && in_array($studentAssessmentRegistration->studentRevaluationType,$markEntryNotNeededFeeTypes)){
                                if(!empty($digitalValuationProperties)){
                                    $s3FileRequest = new \stdClass;
                                    $s3FileRequest->folderPath = $GLOBALS['COLLEGE_CODE'] . "/Digital Evaluation" . "/" .$examRevaluation->parentExamRegistrationName . "/" . $subject->code;
                                    $s3DocStudentKeyList = ExamValuationRuleService::getInstance()->getS3FileDetails($s3FileRequest);
                                    $subjectPhotoCopy = new \stdClass;
                                    $fileDetails->path =  $GLOBALS['COLLEGE_CODE'] . "/Digital Evaluation" . "/" . $examRevaluation->parentExamRegistrationName . "/" . $subject->code . "/" . $subject->falseNumber  . ".". $fileNameExtension;
                                    if (in_array($fileDetails->path, $s3DocStudentKeyList)) {
                                        $subjectPhotoCopy->url = ExamValuationRuleService::getInstance()->getS3FilePathExist($fileDetails)->url;
                                        $subjectPhotoCopy->subjectCode = $subject->code;
                                        $subjectPhotoCopy->subjectName = $subject->name;
                                        $subjectPhotoCopy->assessmentId = $subject->assessmentId;
                                        $subjectPhotoCopy->isDownloadAnswerScript = true;
                                        $examRevaluation->subjectPhotoCopyList[] = $subjectPhotoCopy;
                                    }
                                }
                                $certificates = [];
                                $requestForCertificate = new \StdClass;
                                $requestForCertificate->type = "REVALUATION_PHOTOCOPY";
                                $requestForCertificate->groupId = $examRevaluation->groupId ;
                                $requestForCertificate->studentId = $examRevaluation->studentId;
                                $requestForCertificate->assessmentId = $subject->assessmentId;
                                $requestForCertificate->examRegistrationId = $examRevaluation->examRevaluationId;
                                $certificates = CertificateUploadService::getInstance()->getCertificateUpload($requestForCertificate);
                                foreach($certificates as $certificate){
                                    foreach($certificate->certificates as $certificate){
                                        $subjectPhotoCopy = new \stdClass;
                                        $subjectPhotoCopy->url = $certificate->url;
                                        $subjectPhotoCopy->subjectCode = $subject->code;
                                        $subjectPhotoCopy->subjectName = $subject->name;
                                        $subjectPhotoCopy->assessmentId = $subject->assessmentId;
                                        $subjectPhotoCopy->isDownloadAnswerScript = false;
                                        $examRevaluation->subjectPhotoCopyList[] = $subjectPhotoCopy;
                                    }                                    
                                }
                            }
                        }
                        if ($studentAssessmentRegistration->studentFeeStatus == StudentExamRegistrationPaymentStatus::FAILED && $studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::APPLIED && $studentAssessmentRegistration->studentRegistrationPaymentOption ==  ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD) {
                            $examRevaluation->isAppliedButPaymentFailed = true;
                        }
                        if($studentAssessmentRegistration->studentRegistrationPaymentOption ==  ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD && ( $examRevaluation->isApplied) && !$examRevaluation->isAppliedButPaymentFailed ){
                            $searchRequestForPayment = new \stdClass;
                            $searchRequestForPayment->studentId = $examRevaluation->studentId;
                            $searchRequestForPayment->examRegistrationId = $examRevaluation->examRevaluationId;
                            $studentPaymentStatusDetails = $this->searchStudentOnlinePayement($searchRequestForPayment);
                            if(empty($studentPaymentStatusDetails)){
                                $examRevaluation->isAppliedButPaymentFailed = true;
                            }
                            else{
                                $studentRecentPaymentPendingStatus = reset(array_filter($studentPaymentStatusDetails,function($value){
                                    return $value->status == "PENDING";
                                }));
                                if(empty($studentRecentPaymentPendingStatus)){
                                    $examRevaluation->isAppliedButPaymentFailed = true;
                                }
                            }
                        }
                    }
                }
            }
            $examRevaluation->balanceAmount = 0;
            if($examRevaluation->balanceAmountDetails){
                $examRevaluation->balanceReturnedStatus = $examRevaluation->balanceAmountDetails->balanceReturnedStatus ? true : false;
                if($examRevaluation->balanceAmountDetails->balanceAmount && $examRevaluation->balanceAmountDetails->balanceReturnedStatus == false){
                    $examRevaluation->balanceAmount = (int)$examRevaluation->balanceAmountDetails->balanceAmount;
                }
            }
            if(($examRevaluation->examRegistrationPaymentProperties->paymentOption ==  ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD && ( $examRevaluation->isApplied || $examRevaluation->isRegistered ) && !$examRevaluation->isChallanExperied) || ( $examRevaluation->examRegistrationPaymentProperties->paymentOption !=  ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD  && ( $examRevaluation->isApplied || $examRevaluation->isRegistered ))){
                $examRevaluation->canRegister = false;
            }
            if ( $examRevaluation->isAppliedButPaymentFailed ){
                $examRevaluation->canRegister = true;
            }
            $examRevaluation->isPreviouslyFailedInPayment = $examRevaluation->isAppliedButPaymentFailed;
        }
        $studentExamRevaluationDetails = new \stdClass;
        $studentExamRevaluationDetails->examRevaluations = $examRevaluations;
        return $studentExamRevaluationDetails;
    }
     /**
     * get All Student Revaluation Details
     * @param $request
     * @return studentDetails
     */
    public function getStudentRevaluationDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            $whereQuery = "";
            $limitQuery = "";
            $joinQueary = "";
            $selectColumns = "";
            if($request->mappingType == "EXAM_REGISTRATION"){
                $mapperForRevaluationDetails = StudentExamRegistrationServiceMapper::SEARCH_REVALUATION_DETAILS ;
            }
            else{
                $mapperForRevaluationDetails = StudentExamRegistrationServiceMapper::SEARCH_STUDENT_REVALUATION_DETAILS;
            }
            $sortBy = " ORDER BY eer.created_date DESC, spa.properties->>'$.registerNumber' ASC";
            if(!empty($request->examRegistrationId)){
                $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            if(!empty($request->revaluationTypes)){
                $revaluationTypesString = is_array($request->revaluationTypes) ? "'" . implode("','",$request->revaluationTypes) . "'" : "'".$request->revaluationTypes."'";
                $whereQuery .= " AND esar.revaluationType IN ( $revaluationTypesString )";
            }
            if(!empty($request->registrationStatus)){
                if(in_array('NOT_REGISTERED', $request->registrationStatus)){
                    $joinQueary = " LEFT JOIN ec_student_assessment_registration esar ON 
                                    esar.student_id = sa.studentID AND 
                                    esar.am_assessment_id = eersParent.am_assessment_id AND 
                                    esar.ec_exam_registration_type = eer.type AND 
                                    esar.identifying_context->>'$.examRegistrationId' = eer.id ";
                    if(!in_array('APPLIED', $request->registrationStatus) && !in_array('REGISTERED', $request->registrationStatus)){
                        $whereQuery .= " AND esar.id IS NULL";
                    }
                    else if(in_array('REGISTERED', $request->registrationStatus) && in_array('APPLIED', $request->registrationStatus)){
                        $whereQuery .= " AND (esar.id IS NULL OR esar.properties ->> '$.registrationStatus' IN ( 'REGISTERED', 'APPLIED'))";
                    }
                    else if(in_array('REGISTERED', $request->registrationStatus)){
                        $whereQuery .= " AND (esar.id IS NULL OR esar.properties ->> '$.registrationStatus' IN ( 'REGISTERED'))";
                    }
                    else if(in_array('APPLIED', $request->registrationStatus)){
                        $whereQuery .= " AND (esar.id IS NULL OR esar.properties ->> '$.registrationStatus' IN ( 'APPLIED'))";
                    }
                }
                else{
                    $joinQueary = " INNER JOIN ec_student_assessment_registration esar ON 
                                    esar.student_id = sa.studentID AND 
                                    esar.am_assessment_id = eersParent.am_assessment_id AND 
                                    esar.ec_exam_registration_type = eer.type AND 
                                    esar.identifying_context->>'$.examRegistrationId' = eer.id ";
                    $registrationStatusString = "'" . implode("','",$request->registrationStatus) . "'";
                    $whereQuery .= " AND esar.properties ->> '$.registrationStatus' IN ( $registrationStatusString )";
                }
            }
            else{
                $joinQueary = " LEFT JOIN ec_student_assessment_registration esar ON 
                                esar.student_id = sa.studentID AND 
                                esar.am_assessment_id = eersParent.am_assessment_id AND 
                                esar.ec_exam_registration_type = eer.type AND 
                                esar.identifying_context->>'$.examRegistrationId' = eer.id ";
            }
            if(!empty($request->studentId)){
                $studentIdString = is_array($request->studentId) ? "'" . implode("','",$request->studentId) . "'" : "'".$request->studentId."'";
                $whereQuery .= " AND spa.student_id IN ( $studentIdString )";
            }
            if(!empty($request->groupId)){
                $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if(!empty($request->academicTermId)){
                $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
                $whereQuery .= " AND eerb.properties ->> '$.academicTermId' IN ( $academicTermIdString )";
            }
            if(!empty($request->departmentId)){
                $departmentIdString = is_array($request->departmentId) ? "'" . implode("','",$request->departmentId) . "'" : "'".$request->departmentId."'";
                $whereQuery .= " AND g.properties ->> '$.departmentId' IN ( $departmentIdString )";
            }
            $query = "SELECT 
                    DISTINCT sa.studentID as studentId,
                    sa.studentName,
                    sa.studentEmail,
                    sa.studentPhone,
                    sa.studentBirthday as studentBirthday,
                    sa.reservID,
                    spa.properties->>'$.registerNumber' AS registerNo,
                    spa.properties->>'$.rollNumber' AS rollNo,
                    eer.id AS examRevaluationId,
                    eer.name AS examRevaluationName,
                    eer.properties AS examRevaluationProperties,
                    eer.type AS examRevaluationType,
                    eerParent.name AS parentExamRegistrationName,
                    eerParent.type AS parentExamRegistrationType,
                    eerParent.properties AS parentExamRegistrationProperties,
                    eerb.properties AS examRevaluationBatchProperties,
                    eerb.fees_properties AS examRevaluationFeeProperties,
                    eerb.properties->>'$.registrationStartDate' AS registrationStartDate,
                    eerb.properties->>'$.registrationEndDate' AS registrationEndDate,
                    eerb.properties->>'$.subjectLimit' AS subjectLimit,
                    act.name AS academicTermName,
                    eeft.id as batchFeeTemplateId,
                    eeft.fee_properties as batchCommonFees,
                    eeft.fine_properties as batchCommonFines,
                    IF (eeft.operation_properties  IS NULL,0,1) as isConsiderOperation,
                    eeft.operation_properties as batchOperationProperties,
                    eserd.total_fee AS examRegistrationPaidAmount,
                    eserd.balance_amount_details AS balanceAmountDetails,
                    eserd.properties AS examRegistrationPaymentProperties,
                    eserd.properties->>'$.isResultWithHeld' AS isResultWithHeld,
                    g.id AS groupId,
                    g.name AS groupName,
                    d.deptName as deptCode,
                    d.departmentDesc as deptName,
                    eersParent.am_assessment_id as assessmentId,
                    esarParent.falseNo AS falseNumber,
                    esarParent.properties->>'$.alphaNumericCode' AS alphaNumericCode,
                    caps.id AS academicPaperSubjectId,
                    IF(caps.properties ->> '$.classType' = 'PRACTICAL',1,0) AS isPractical,
                    caps.properties ->> '$.classType' AS classType,
                    esar.id AS studentAssessmentRegistrationId,
                    s.code AS subjectCode,
                    caps.properties ->> '$.syllabusName' AS syllabusName,
                    s.name AS subjectName,
                    esar.properties as studentAssessmentRegistrationProperties,
                    esar.identifying_context as studentAssessmentRegistrationIdentifyingContext,
                    esar.revaluationType as studentRevaluationType,
                    esar.properties ->> '$.registrationStatus' as studentRegistrationStatus,
                    esar.properties ->> '$.feeStatus' as studentFeeStatus,
                    esar.properties ->> '$.paymentOption' as studentRegistrationPaymentOption,
                    esmdsem.mark_details ->>'$.percentage' AS semesterPercentage,
                    esmdsem.mark_details AS semesterMarkDetails,
                    esmdsem.mark_history AS semesterMarkHistory,
                    esmdsem.failed_status AS semesterFailedStatus,
                    esmdsub.failed_status AS subjectFailedStatus,
                    esmdsub.mark_details ->>'$.percentage' AS subjectPercentage,
                    esmdsub.mark_details AS subjectMarkDetails,
                    esarParent.valuation_details AS valuationDetails,
                    esarParent.valuation_order_details AS valuationOrderDetails
                FROM
                    ec_exam_registration eer
                INNER JOIN ec_exam_registration_batch eerb ON
                    eerb.ec_exam_registration_id = eer.id 
                INNER JOIN ec_examregistration_fee_templates_mapping eeftm ON
                    eeftm.id = eerb.fees_properties->>'$.feeTemplateId'
                INNER JOIN ec_examregistration_fee_templates eeft ON
                    eeft.ec_examregistration_fee_templates_mapping_id = eeftm.id
                INNER JOIN ec_exam_registration eerParent ON
                    eerParent.id = eer.properties->>'$.parentExamRegistrationId' AND 
                    eerParent.trashed IS NULL
                INNER JOIN ec_exam_registration_batch eerbParent ON
                    eerbParent.ec_exam_registration_id = eerParent.id  AND 
                    eerb.groups_id = eerbParent.groups_id
                INNER JOIN ec_exam_registration_subject eersParent ON     
                    eersParent.ec_exam_registration_batch_id = eerbParent.id 
                INNER JOIN academic_term act ON 
                    act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
                INNER JOIN cm_academic_paper_subjects caps ON
                    caps.id = eersParent.cm_academic_paper_subjects_id AND caps.properties->>'$.isExternal' = '1'
                INNER JOIN v4_ams_subject s ON
                    s.id = caps.ams_subject_id
                INNER JOIN `groups` g ON
                    g.id = eerb.groups_id
                    AND g.`type` = 'BATCH'
                INNER JOIN department d ON
                    d.deptID = g.properties ->> '$.departmentId' 
                INNER JOIN program p ON 
                    p.id = g.properties->>'$.programId'
                INNER JOIN ec_semester_mark_details esmdsem ON
                    esmdsem.groups_id = eerbParent.groups_id 
                    AND esmdsem.academic_term_id = CAST(eerbParent.properties ->> '$.academicTermId'AS CHAR)
                INNER JOIN student_program_account spa ON 
                    spa.student_id  = esmdsem.student_id AND
                    spa.current_program_id = p.id 
                INNER JOIN studentaccount sa ON
                    sa.studentID = spa.student_id
                INNER JOIN ec_subject_mark_details esmdsub ON
                    esmdsub.groups_id = eerbParent.groups_id AND
                    esmdsub.cm_academic_paper_subjects_id = eersParent.cm_academic_paper_subjects_id AND
                    esmdsub.student_id = spa.student_id AND
                    esmdsub.ec_exam_registration_id = eerParent.id
                INNER JOIN ec_student_assessment_registration esarParent ON 
                    esarParent.student_id = sa.studentID AND
                    esarParent.am_assessment_id = eersParent.am_assessment_id AND
                    esarParent.ec_exam_registration_type = eerParent.type
                LEFT JOIN ec_student_exam_registration_details eserd ON
                    eserd.student_id = sa.studentID AND 
                    eserd.ec_exam_registration_id = eer.id 
                $joinQueary 
                WHERE eer.type = 'REVALUATION' AND eer.trashed IS NULL AND eer.properties->>'$.publish' = 1 ";
            $studentDetails = $this->executeQueryForList($query.$whereQuery.$sortBy.$limitQuery, $this->mapper[$mapperForRevaluationDetails]);
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        return $studentDetails;
    }
    /**
     * Search stduent Exam Revaluation Subjects
     * @param  $request
     * @return examRevaluation
     */
    public function getAllRevaluationSubjectsForStudentRegistration( $request){
        $searchRequest = new \stdClass;
        $searchRequest->studentId = $request->studentId;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->registrationStatus = $request->registrationStatus;
        $searchRequest->revaluationTypes = $request->revaluationTypes;
        $searchRequest->notConsiderValidation = $request->notConsiderValidation;
        $searchRuleRequest = new SearchRuleRequest;
        $searchRuleRequest->name = "REVALUATION_SETTINGS_RULE";
        $settingsRule = reset(RuleService::getInstance()->searchRule($searchRuleRequest))->rule;
        $academicPaperSubjectId = [];
        $subjectRevaluationDetails = [];
        $subjects = $request->subjects;
        foreach($subjects as $subject){
            $academicPaperSubjectId[$subject->academicPaperSubjectId] = $subject->academicPaperSubjectId;
            $subjectRevaluationDetails[$subject->academicPaperSubjectId] = [
                "revaluationTypes" => $subject->revaluationTypes,
                "academicPaperSubjectId" => $subject->academicPaperSubjectId
            ];
        }
        $studentDetails =  reset($this->getStudentRevaluationDetails($searchRequest));
        if(!empty($studentDetails->examRevaluationProperties->parentRevaluationRegistrationIds)){
            $searchParentExamRevaluationDetailsRequest = new \stdClass;
            $searchParentExamRevaluationDetailsRequest->studentId = $request->studentId;
            $searchParentExamRevaluationDetailsRequest->examRegistrationId = $studentDetails->examRevaluationProperties->parentRevaluationRegistrationIds;
            $parentExamRevaluationDetails =  reset($this->getParentRevaluationRegistredStudentDetails($searchParentExamRevaluationDetailsRequest));
            $requestForExamRegistration = new SearchExamRegistrationRequest;
            $requestForExamRegistration->ids = $studentDetails->examRevaluationProperties->parentRevaluationRegistrationIds;
            $parentExamRevaluations = ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration);
            $parentExamRevaluationNames = array_column($parentExamRevaluations,'name');
            $errorMsg = "Please Register <b>".implode("  <br> and",$parentExamRevaluationNames) ." </b> revaluation(s) first";
            if(empty($parentExamRevaluationDetails)){
                throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,$errorMsg);
            }
            else{
                // foreach($parentExamRevaluationDetails->subjects as $key=> $parentRevaluationRegisteredSubject){
                //     $parentRevaluationRegisteredSubject->revaluationIds =  array_column($parentRevaluationRegisteredSubject->exams,'id');
                //     $arrayDiff = array_diff($studentDetails->examRevaluationProperties->parentRevaluationRegistrationIds,$parentRevaluationRegisteredSubject->revaluationIds);
                //     if(!empty($arrayDiff)){
                //         unset($parentExamRevaluationDetails->subjects[$key]);
                //     }
                // }
                $parentExamRevaluationDetails->registeredSubjects = array_column($parentExamRevaluationDetails->subjects,'assessmentId');
                foreach($studentDetails->subjects as $subKey=>  $subject){
                    if ( !in_array ( $subject->assessmentId, $parentExamRevaluationDetails->registeredSubjects ) ) {
                        unset($studentDetails->subjects[$subKey]);
                    }
                }
                if(empty($studentDetails->subjects)){
                    throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,$errorMsg);
                }
            }
        }
        foreach($studentDetails->examRevaluationBatchProperties->paymentMethods as $paymentMethod){
            if($paymentMethod == ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD;
                $currentPaymentMethod->name = "College Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::BANK_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::BANK_CHALLAN_METHOD;
                $currentPaymentMethod->name = "Bank Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD;
                $currentPaymentMethod->name = "Online Payment Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
        }
        if ($request->isStudentSideRequest && !$request->hideAlreadyExistCheck){
            $studentRegisterStatus = "";
            foreach($studentDetails->subjects as $subject){
                if (empty($studentRegisterStatus)){
                    $studentRegisterStatus = reset(array_filter($subject->studentAssessmentRegistrations,function($value){
                        if($value->studentAssessmentRegistrationProperties->registrationStatus == "APPLIED" || $value->studentAssessmentRegistrationProperties->registrationStatus == "REGISTERED")
                        return $value;
                    }));
                }
                else{
                    break;
                }
            }
            if($studentRegisterStatus){
                if ( $studentRegisterStatus->studentRegistrationStatus == "APPLIED" && $studentRegisterStatus->studentFeeStatus == "FAILED" && $studentRegisterStatus->studentRegistrationPaymentOption == "ONLINE_PAYMENT_METHOD"){
                    // do nothing
                }
                else{
                    $searchRequestForPayment = new \stdClass;
                    $searchRequestForPayment->studentId = $request->studentId;
                    $searchRequestForPayment->examRegistrationId = $request->examRegistrationId;
                    $studentPaymentStatusDetails = $this->searchStudentOnlinePayement($searchRequestForPayment);
                    if ($studentPaymentStatusDetails){
                        $studentRecentPaymentPendingStatus = reset(array_filter($studentPaymentStatusDetails,function($value){
                            return $value->status == "PENDING";
                        }));
                        if(empty($studentRecentPaymentPendingStatus)){
                            $eligibleForReapply = true;
                        }
                    }
                    else{
                        $eligibleForReapply = true;
                    }
                    if( $eligibleForReapply && $studentRegisterStatus->studentRegistrationStatus == "APPLIED" &&$studentRegisterStatus->studentRegistrationPaymentOption == "ONLINE_PAYMENT_METHOD"){
                        // do nothing
                    }
                    else{
                        throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,"Payment already initiated.");
                    }
                }
            }
        }
        $studentDetails->totalFeeAmount = 0;
        $studentDetails->totalStudentFee = 0;
        $studentDetails->totalSubjectFees = 0;
        $studentDetails->paidAmount = 0;
         // ------------Studdent common Fees & Fines --------------- 
        if(count($studentDetails->batchFeeFine) > 1){
            $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
        }
        else{
            $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
        }
        // ------------studdent common Fees --------------- 
        $studentDetails->commonFees = [];   
        $studentDetails->totalCommonFees = 0;  
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REVALUATION';
        $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRevaluationType;
        }));
        $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
        $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
        foreach($allCommonFees as $commonFee){
            if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                if($commonFee->isCommon ){
                    $currentFee = new \stdclass;
                    $currentFee->feeName = $commonFee->name;
                    $currentFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                    $studentDetails->totalCommonFees += $currentFee->value;
                    $studentDetails->commonFees[] = $currentFee;
                } 
                else{
                    $revaluationFee = new \stdclass;
                    $revaluationFee->id = $commonFee->id;
                    $revaluationFee->feeName = $commonFee->name;
                    $revaluationFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                    $studentDetails->revaluationFee[] = $revaluationFee;
                }
            }
        }  
         // ------------Not fetch Absent Students --------------- 
        $studentDetails->subjects = array_filter($studentDetails->subjects,function($value){
            return $value->subjectMarkDetails->attendanceStatus == "PRESENT";
        });
        $studentDetails->subjects = array_values($studentDetails->subjects);
        if($settingsRule->fetchTheorySubjectsOnly){
            // ------------Remove Practical Subjects --------------- 
            $studentDetails->subjects = array_filter($studentDetails->subjects,function($value){
                return !in_array($value->classType, ["PRACTICAL", "PROJECT","SEMINAR"]);
            });
            $studentDetails->subjects = array_values($studentDetails->subjects);
        }
         // ------------Student Fees--------------- 
        array_walk($studentDetails->subjects,function($subject,$key) use($subjectRevaluationDetails,$studentDetails,$academicPaperSubjectId){
            $subject->feeValue = 0;
            $subject->isSelected = false;
            $subject->revaluationTypes = [];
            $subject->currentPaymentMethod = "";
            $subject->isTobeRegistered = false;
            $subject->studentRevaluationRegistration = [];
            foreach($studentDetails->revaluationFee as $revaluationFee){
                $revaluationRegistrationDetails = new \stdClass;
                $revaluationRegistrationDetails->revaluationId = $revaluationFee->id;
                $revaluationRegistrationDetails->registrationStatus = "";
                $subject->revaluationRegistrationStatus[$revaluationFee->id] = $revaluationRegistrationDetails;
            }
            if(in_array($subject->academicPaperSubjectId,$academicPaperSubjectId)){
                $subject->addedRevaluationTypes = [];
                foreach($studentDetails->revaluationFee as $revaluationFee){
                    $subject->addedRevaluationTypes = (array)$subjectRevaluationDetails[$subject->academicPaperSubjectId]['revaluationTypes'];
                    if(in_array($revaluationFee->id,$subject->addedRevaluationTypes)){
                        $studentDetails->totalStudentFee += (int)$revaluationFee->value;
                        $studentRevaluationDetails = new \stdClass;
                        $studentRevaluationDetails->studentRevaluationType = $revaluationFee->id;
                        $studentRevaluationDetails->isAlreadyRegistered = false;
                        $subject->studentRevaluationRegistration[$studentRevaluationDetails->studentRevaluationType] = $studentRevaluationDetails;
                    }
                }
                $subject->isTobeRegistered = true;
            }
            if(!empty($subject->studentAssessmentRegistrations)){
                foreach($subject->studentAssessmentRegistrations as $studentAssessmentRegistration){
                    $studentAssessmentRegistration->isAlreadyRegistered = false;
                    $subject->revaluationRegistrationStatus[$studentAssessmentRegistration->studentRevaluationType]->registrationStatus = $studentAssessmentRegistration->studentRegistrationStatus;
                    if($studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::REGISTERED){
                        $subject->revaluationTypes[] = $studentAssessmentRegistration->studentRevaluationType;
                        $subject->studentRevaluationRegistration[$studentAssessmentRegistration->studentRevaluationType]->isAlreadyRegistered = true;
                        foreach($studentDetails->revaluationFee as $revaluationFee){
                            if($revaluationFee->id == $studentAssessmentRegistration->studentRevaluationType){
                                $subject->feeValue += (int)$revaluationFee->value;
                                $studentDetails->paidAmount += (int)$revaluationFee->value;
                                $subject->isSelected = true;
                            }
                        }
                        if(!in_array($studentAssessmentRegistration->studentRevaluationType,$subject->addedRevaluationTypes)){
                            $studentRevaluationDetails = new \stdClass;
                            $studentRevaluationDetails->studentRevaluationType = $studentAssessmentRegistration->studentRevaluationType;
                            $studentRevaluationDetails->studentAssessmentRegistrationId = $studentAssessmentRegistration->studentAssessmentRegistrationId;
                            $studentRevaluationDetails->studentAssessmentRegistrationProperties = $studentAssessmentRegistration->studentAssessmentRegistrationProperties;
                            $studentRevaluationDetails->studentAssessmentRegistrationIdentifyingContext = $studentAssessmentRegistration->studentAssessmentRegistrationIdentifyingContext;
                            $studentRevaluationDetails->isDeleted = true;
                            $studentRevaluationDetails->isAlreadyRegistered = false;
                            $subject->studentRevaluationRegistration[$studentAssessmentRegistration->studentRevaluationType] = $studentRevaluationDetails;
                        }
                    }
                    else{
                        foreach($subject->studentRevaluationRegistration as $studentRevaluationRegistration){
                            if($studentAssessmentRegistration->studentRevaluationType == $studentRevaluationRegistration->revaluationType ){
                                $studentRevaluationRegistration->studentAssessmentRegistrationId = $studentAssessmentRegistration->studentAssessmentRegistrationId;
                                $studentRevaluationRegistration->studentAssessmentRegistrationProperties = $studentAssessmentRegistration->studentAssessmentRegistrationProperties;
                                $studentRevaluationRegistration->studentAssessmentRegistrationIdentifyingContext = $studentAssessmentRegistration->studentAssessmentRegistrationIdentifyingContext;
                            }
                        }
                    }
                }
                $studentDetails->totalSubjectFees += $subject->feeValue;
            }
        });
        $studentDetails->balanceAmount = 0;
        if($studentDetails->balanceAmountDetails){
            $studentDetails->balanceReturnedStatus = $studentDetails->balanceAmountDetails->balanceReturnedStatus ? true : false;
            if($studentDetails->balanceAmountDetails->balanceAmount && $studentDetails->balanceAmountDetails->balanceReturnedStatus == false){
                $studentDetails->balanceAmount = (int)$studentDetails->balanceAmountDetails->balanceAmount;
            }
            else{
                $studentDetails->balanceAmount = 0;
            }
        }
        $studentDetails->balanceAmountCopy = $studentDetails->balanceAmount;
        $studentDetails->paidAmount = $studentDetails->paidAmount ? $studentDetails->paidAmount + $studentDetails->totalCommonFees : 0;
        $studentDetails->totalStudentFee = $studentDetails->totalStudentFee ? $studentDetails->totalStudentFee + $studentDetails->totalCommonFees : 0;
        $studentDetails->totalFeeAmount = $studentDetails->paidAmount;
        // ---------------- Calculation For save student registration-------------
        if($request->isSaveStudentExamRegistration){
            if(($studentDetails->paidAmount >= $studentDetails->totalStudentFee)){
                $studentDetails->amountTobePaid = 0;
                $studentDetails->balanceAmount += $studentDetails->paidAmount - $studentDetails->totalStudentFee;
            }
            else{
                $amountTobePaid = $studentDetails->totalStudentFee - $studentDetails->paidAmount;
                if($amountTobePaid > $studentDetails->balanceAmount){
                    $studentDetails->amountTobePaid = $amountTobePaid - $studentDetails->balanceAmount;
                    $studentDetails->balanceAmount = 0;
                }
                else{
                    $studentDetails->balanceAmount -= $amountTobePaid;
                    $studentDetails->amountTobePaid = 0;
                }
            }
        }
        if (strtotime($studentDetails->registrationStartDate) > strtotime(date("Y-m-d")) && !$request->notConsiderValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration not started");
        }
        elseif (strtotime($studentDetails->registrationEndDate)  < strtotime(date("Y-m-d")) && !$request->notConsiderValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration closed");
        }
        if(empty($studentDetails->subjects)){
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Not applicable !!");
        }
        return($studentDetails); 
    }
    /**
     * search All Student Details By ExamRegistration
     * @param $request
     * @return studentDetails
     */
    public function searchAllStudentDetailsByExamRevaluation($request){
        try{
            // revaluation rule
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name = "REVALUATION_SETTINGS_RULE";
            $settingsRule = reset(RuleService::getInstance()->searchRule($searchRuleRequest))->rule;
            // check is publish exam revaluation
            $searchExamRegistrationRequest = new SearchExamRegistrationRequest();
            $searchExamRegistrationRequest->id = $request->examRegistrationId;
            $examRevaluation = reset(ExamRegistrationService::getInstance()->getAllExamRevaluation($searchExamRegistrationRequest));
            if($examRevaluation->properties->publish != '1'){
                throw new ExamControllerException (ExamControllerException::EXAM_REGISTRATION_NOT_PUBLISHED,"Exam registration not published.");
            }
            $registrationStatus = ["APPLIED","REGISTERED"];
            $searchRequest = new \stdClass;
            $searchRequest->studentId = $request->studentId;
            $searchRequest->examRegistrationId = $request->examRegistrationId;
            $searchRequest->academicTermId = $request->academicTermId;
            $searchRequest->departmentId = $request->departmentId;
            $searchRequest->groupId = $request->groupId;
            $searchRequest->isBackEndRegistration = $request->isBackEndRegistration;
            $searchRequest->registrationStatus = $request->registrationStatus;
            if($searchRequest->isBackEndRegistration && in_array('NOT_REGISTERED', $request->registrationStatus)){
                $searchRequest->registrationStatus = [];
            }
            // $searchRequest->revaluationTypes = $request->revaluationTypes;
            $searchRequest->notConsiderValidation = $request->notConsiderValidation;
            $studentDetails =  $this->getStudentRevaluationDetails($searchRequest);
            foreach($studentDetails as $studentKey=> $student){
                if(!empty($student->examRevaluationProperties->parentRevaluationRegistrationIds)){
                    $searchParentExamRevaluationDetailsRequest = new \stdClass;
                    $searchParentExamRevaluationDetailsRequest->studentId = $student->studentId;
                    $searchParentExamRevaluationDetailsRequest->examRegistrationId = $student->examRevaluationProperties->parentRevaluationRegistrationIds;
                    $parentExamRevaluationDetails =  reset($this->getParentRevaluationRegistredStudentDetails($searchParentExamRevaluationDetailsRequest));
                    $requestForExamRegistration = new SearchExamRegistrationRequest;
                    $requestForExamRegistration->ids = $student->examRevaluationProperties->parentRevaluationRegistrationIds;
                    $parentExamRevaluations = ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration);
                    $parentExamRevaluationNames = array_column($parentExamRevaluations,'name');
                    $errorMsg = "";
                    $errorMsg = "Please register ".implode(" and",$parentExamRevaluationNames) ."revaluation(s) first";
                    if(empty($parentExamRevaluationDetails)){
                        foreach($student->subjects as $key=>  $subject){
                            $subject->validationError = true;
                            $subject->validationErrorIcon = "Pending";
                            $subject->validationErrorMsg = "$errorMsg";
                        }
                    }
                    else{
                        // foreach($parentExamRevaluationDetails->subjects as $key=> $parentRevaluationRegisteredSubject){
                        //     $parentRevaluationRegisteredSubject->revaluationIds =  array_column($parentRevaluationRegisteredSubject->exams,'id');
                        //     $arrayDiff = array_diff($parentRevaluationRegisteredSubject->revaluationIds, $student->examRevaluationProperties->parentRevaluationRegistrationIds);
                        //     if(!empty($arrayDiff)){
                        //         unset($parentExamRevaluationDetails->subjects[$key]);
                        //     }
                        // }
                        $parentExamRevaluationDetails->registeredSubjects = array_column($parentExamRevaluationDetails->subjects,'assessmentId');
                        foreach($student->subjects as $key=>  $subject){
                            if ( !in_array ( $subject->assessmentId, $parentExamRevaluationDetails->registeredSubjects ) ) {
                                $subject->validationError = true;
                                $subject->validationErrorIcon = "Pending";
                                $subject->validationErrorMsg = "$errorMsg";
                            }
                        }
                    }
                }
                $student->withHeldStatus =  $student->isResultWithHeld ? true : false;
                foreach($student->subjects as $key=>  $subject){
                    $subject->validationErrorMsg = $subject->validationErrorMsg ?? NULL;
                    $subject->validationErrorIcon = $subject->validationErrorIcon ?? NULL;
                    $subject->validationError = $subject->validationError ?? false; 
                    $subject->isAbsent = $subject->subjectMarkDetails->attendanceStatus == 'ABSENT' ? true : false;
                    $subject->isMalPractice = $subject->subjectMarkDetails->attendanceStatus == 'MALPRACTICE' ? true : false;
                    $subject->isPractical = $settingsRule->fetchTheorySubjectsOnly && $subject->isPractical == "1" ? true : false;
                    if($subject->isAbsent || $subject->isMalPractice || $subject->isPractical){
                        $subject->validationError = true;
                        $subject->validationErrorIcon = $subject->isAbsent ?  "AB" : $subject->validationErrorIcon;
                        $subject->validationErrorIcon = $subject->isMalPractice ?  "MAL" : $subject->validationErrorIcon;
                        $subject->validationErrorIcon = $subject->isPractical ?  "P" : $subject->validationErrorIcon;
                        $subject->validationErrorMsg = $subject->isAbsent ?  "Absent in examination" : $subject->validationErrorMsg;
                        $subject->validationErrorMsg = $subject->isMalPractice ?  "Punishment for malpractice in examination" : $subject->validationErrorMsg;
                        $subject->validationErrorMsg = $subject->isPractical ?  "Practical subject" : $subject->validationErrorMsg;
                    }
                    $subject->isApplied = false;
                    $subject->revaluationTypes = [];
                    if(!empty($subject->studentAssessmentRegistrations)){
                        foreach($subject->studentAssessmentRegistrations as $studentAssessmentRegistration){
                            if(in_array($studentAssessmentRegistration->studentRegistrationStatus,$registrationStatus)){
                                $subject->revaluationTypes[] =  $studentAssessmentRegistration->studentRevaluationType;
                                $subject->isApplied = true;
                                $subject->isRegistered = $studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::REGISTERED ? true : false;
                                $student->isApplied = true;
                                if( !$student->isRegistered && $studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::REGISTERED){
                                    $student->isRegistered = true;
                                }
                            }
                        }
                    }
                    if(in_array('NOT_REGISTERED', $request->registrationStatus) && $searchRequest->isBackEndRegistration){
                        if(count($subject->revaluationTypes) < count($student->examRevaluationProperties->revaluationFeeTypeIds)){
                            $subject->revaluationTypes = array_diff($student->examRevaluationProperties->revaluationFeeTypeIds,$subject->revaluationTypes);
                        }
                        else if(count($subject->revaluationTypes) == count($student->examRevaluationProperties->revaluationFeeTypeIds)){
                            unset($studentDetails[$studentKey]->subjects[$key]);
                        }
                    }
                    $student->dateofPay = "";
                    $student->paymentMethod = "Back end Method";
                    if($student->examRegistrationPaymentProperties->paymentOption =="ONLINE_PAYMENT_METHOD"){
                        $student->paymentMethod = "Online Method";
                        $student->transactionDate =  $student->examRegistrationPaymentProperties->onlinePaymentTransactionDate ? date("d-m-Y h:i A", strtotime( $student->examRegistrationPaymentProperties->onlinePaymentTransactionDate)):"";
                    }
                    else if ($student->examRegistrationPaymentProperties->paymentOption =="COLLEGE_CHALLAN_METHOD"){
                        $student->paymentMethod = "College Challan";
                        $student->transactionDate = $student->examRegistrationPaymentProperties->challanVerifyDate ? date("d-m-Y h:i A", strtotime( $student->examRegistrationPaymentProperties->challanVerifyDate)) : "";
                    }
                }
                $studentDetails[$studentKey]->subjects = array_values($studentDetails[$studentKey]->subjects);
                $student->balanceAmount = 0;
                if($student->balanceAmountDetails){
                    $student->balanceReturnedStatus = $student->balanceAmountDetails->balanceReturnedStatus ? true : false;
                    if($student->balanceAmountDetails->balanceAmount && $student->balanceAmountDetails->balanceReturnedStatus == false){
                        $student->balanceAmount = (int)$student->balanceAmountDetails->balanceAmount;
                    }
                }
                if(count($studentDetails[$studentKey]->subjects) == 0){
                    unset($studentDetails[$studentKey]);
                }
            }
            $studentDetails = array_values($studentDetails);
            array_walk($studentDetails, function($student,$key) {
                $student->isExpand = false;
            });
            return $studentDetails;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
    
     /**
     * Get count of Registered Student
     * @param $request
     * @return countOfRegisteredStudent
     */
    public function getCountOfRegisteredStudents($request){
        try{
            $request = $this->realEscapeObject($request);
            $whereQuery = "";
            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->academicPaperSubjectId)) {
                $academicPaperSubjectIdString = is_array($request->academicPaperSubjectId) ? "'" . implode("','",$request->academicPaperSubjectId) . "'" : "'".$request->academicPaperSubjectId."'";
                $whereQuery .= " AND eers.cm_academic_paper_subjects_id IN ($academicPaperSubjectIdString)";
            }
            if(!empty($request->groupId)) {
                $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
                $whereQuery .= " AND eerb.groups_id IN ($groupIdString)";
            }
            if(!empty($request->assessmentId)) {
                $assessmentIdString = is_array($request->assessmentId) ? "'" . implode("','",$request->assessmentId) . "'" : "'".$request->assessmentId."'";
                $whereQuery .= " AND esar.am_assessment_id IN ( $assessmentIdString )";
            }
            if($request->falseNoGeneratedStudentsOnly) {
                $whereQuery .= " AND esar.falseNo IS NOT NULL";
            }
            $query = "SELECT
                COUNT(esar.id) as countOfStudents
            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 ec_exam_registration_subject eers ON
                eers.am_assessment_id = aa.id
                AND 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 cm_academic_paper_subjects caps ON
                caps.id = eers.cm_academic_paper_subjects_id
            WHERE
                esar.trashed IS NULL AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED') AND eer.type = esar.ec_exam_registration_type AND (CAST(esar.properties ->> '$.syllabusSubType' AS CHAR) != 'MOOC' OR esar.properties ->> '$.syllabusSubType' IS NULL)";
        try {
            $countOfRegisteredStudent = $this->executeQueryForObject($query.$whereQuery);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        return $countOfRegisteredStudent->countOfStudents;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
    
     /**
     * Get Registered Student Valuation Details
     * @param $request
     * @return $students
     */
    public function getRegisteredStudentsValuationDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            $joinQuery = "";
            $whereQuery = "";
            $orderBy = "";
            if(!empty($request->examRegistrationId)) {
                $whereQuery .= " AND eerb.ec_exam_registration_id = '$request->examRegistrationId'";
            }
            if(!empty($request->academicPaperSubjectId)) {
                $academicPaperSubjectIdString = is_array($request->academicPaperSubjectId) ? "'" . implode("','",$request->academicPaperSubjectId) . "'" : "'".$request->academicPaperSubjectId."'";
                $whereQuery .= " AND eers.cm_academic_paper_subjects_id IN ( $academicPaperSubjectIdString )";
            }
            if(!empty($request->groupId)) {
                $whereQuery .= " AND eerb.groups_id = '$request->groupId'";
            }
            if(!empty($request->assessmentId)) {
                $assessmentIdString = is_array($request->assessmentId) ? "'" . implode("','",$request->assessmentId) . "'" : "'".$request->assessmentId."'";
                $whereQuery .= " AND esar.am_assessment_id IN ($assessmentIdString)";
            }
            if($request->fetchThirdValuationStudentsOnly == '1') {
                $joinQuery .= " INNER JOIN externalexam_thirdvalstudents eetvs ON 
                                    eetvs.studentID = sa.studentID AND 
                                    eetvs.am_assessment_id = esar.am_assessment_id ";
                
                // $joinQuery .= " AND esar.am_assessment_id = '$request->assessmentId'";
            }
            if( $request->falseNoRegNoStatus == "falseNumber") {
                $whereQuery .= " AND esar.falseNo IS NOT NULL ";
                $orderBy = " ORDER BY esar.falseNo ASC";
            }
            else{
                $orderBy = " ORDER BY spa.properties->>'$.registerNumber' ASC";
            }
            $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,
                sa.studentName,
                spa.properties->>'$.registerNumber' AS registerNo,
                spa.properties->>'$.rollNumber' AS rollNo,
                sub.code AS subjectCode,
                sub.name AS subjectName,
                caps.id AS academicPaperSubjectId,
                oe.id AS onlineExamId,
                caps.properties ->> '$.externalMaxMark' as externalMaxMark
            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
            ".$joinQuery."
            WHERE
                esar.trashed IS NULL AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED') AND eer.type = esar.ec_exam_registration_type AND (CAST(esar.properties ->> '$.syllabusSubType' AS CHAR) != 'MOOC' OR esar.properties ->> '$.syllabusSubType' IS NULL)";
        try {
            $registeredStudent = $this->executeQueryForList($query.$whereQuery.$orderBy);
            $students = [];
            foreach($registeredStudent as $student){
                $students[$student->id]->id = $student->id;
                $students[$student->id]->studentId = $student->studentId;
                $students[$student->id]->assessmentId = $student->assessmentId;
                $students[$student->id]->falseNumber = $student->falseNumber;
                $students[$student->id]->falseNo = $student->falseNumber;
                $students[$student->id]->valuationDetails = $student->valuationDetails;
                $students[$student->id]->studentName = $student->studentName;
                $students[$student->id]->rollNo = $student->rollNo;
                $students[$student->id]->registerNo = $student->registerNo;
                $students[$student->id]->subjectCode = $student->subjectCode;
                $students[$student->id]->subjectName = $student->subjectName;
                $students[$student->id]->academicPaperSubjectId = $student->academicPaperSubjectId;
                $students[$student->id]->externalMaxMark = $student->externalMaxMark;
                $students[$student->id]->onlineExamId[] = $student->onlineExamId;
            }
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        return $students;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Get Revaluation Registered Student Valuation Details
     * @param $request
     * @return $students
     */
    public function getRevaluationRegisteredStudentsValuationDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            $joinQuery = "";
            $whereQuery = "";
            $orderBy = "";
            if(!empty($request->examRegistrationId)) {
                $whereQuery .= " AND eer.id = '$request->examRegistrationId'";
            }
            if(!empty($request->academicPaperSubjectId)) {
                $whereQuery .= " AND eers.cm_academic_paper_subjects_id = '$request->academicPaperSubjectId'";
            }
            if(!empty($request->academicPaperSubjectIds)) {
                $academicPaperSubjectIdsString = is_array($request->academicPaperSubjectIds) ? "'" . implode("','",$request->academicPaperSubjectIds) . "'" : "'".$request->academicPaperSubjectIds."'";
                $whereQuery .= " AND eers.cm_academic_paper_subjects_id IN ( $academicPaperSubjectIdsString )";
            }
            if(!empty($request->groupId)) {
                $whereQuery .= " AND eerb.groups_id = '$request->groupId'";
            }
            if(!empty($request->assessmentId)) {
                $whereQuery .= " AND esar.am_assessment_id = '$request->assessmentId'";
            }
            if(!empty($request->revaluationType)) {
                $whereQuery .= " AND esar.revaluationType = '$request->revaluationType'";
            }
            if($request->fetchThirdValuationStudentsOnly == '1') {
                
                // $joinQuery .= " INNER JOIN ec_revaluation_mark erm2 ON 
                //                 erm2.student_id = sa.studentID AND erm2.am_assessment_id = esar.am_assessment_id AND erm2.revaluation_type = CAST(esar.identifying_context->>'$.revaluationType'AS CHAR) AND erm2.valuation_count = '2' AND erm2.properties ->> '$.hasEligibleThirdValuation' = '1'";
                $joinQuery .= " INNER JOIN externalexam_thirdvalstudents eetvs ON 
                                    eetvs.studentID = sa.studentID AND 
                                    eetvs.am_assessment_id = esar.am_assessment_id AND
                                    eetvs.revaluation_id = esar.revaluationType";
                
                // $joinQuery .= " AND esar.am_assessment_id = '$request->assessmentId'";
            }
            if( $request->falseNoRegNoStatus == "falseNumber") {
                $whereQuery .= " AND esarParent.falseNo IS NOT NULL ";
                $orderBy = " ORDER BY esarParent.falseNo ASC";
            }
            else{
                $orderBy = " ORDER BY spa.properties->>'$.registerNumber' ASC";
            }
            $query = "SELECT DISTINCT
                    esar.id,
                    sa.studentID as studentId,
                    aa.id AS assessmentId,
                    esarParent.falseNo AS falseNumber,
                    esarParent.falseNo AS falseNo,
                    IF (esar.valuation_details IS NULL, JSON_OBJECT(), esar.valuation_details) AS valuationDetails,
                    sa.studentName,
                    spa.properties->>'$.registerNumber' AS registerNo,
                    spa.properties->>'$.rollNumber' AS rollNo,
                    sub.code AS subjectCode,
                    sub.name AS subjectName,
                    caps.id AS academicPaperSubjectId
                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 eerp ON
                    eerp.id = eerb.ec_exam_registration_id AND
                    eerp.trashed IS NULL
                INNER JOIN ec_exam_registration eer ON
                    eer.properties->>'$.parentExamRegistrationId' = eerp.id AND 
                    eer.trashed IS NULL
                INNER JOIN ec_student_assessment_registration esarParent ON 
                    esarParent.student_id = esar.student_id AND
                    esarParent.am_assessment_id = esar.am_assessment_id AND
                    esarParent.ec_exam_registration_type = eerp.type 
                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
                ".$joinQuery."
                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.$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());
        }
    }
    /**
     * Delete not applied students by assessmentId
     * @param $request
     * @return NULL
     */
    public function deleteNotAppliedStudents($request){
        $request = $this->realEscapeObject($request);
        if(empty($request->assessmentId)) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_STUDENT_REGISTRATION,"Subject missing. Please try again!");
        }
        $query = "DELETE FROM
                    ec_student_assessment_registration
                WHERE
                    am_assessment_id = '$request->assessmentId' AND properties ->> '$.registrationStatus' IN ( 'NOT_REGISTERED', 'NOT_APPLIED')";
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_RESTORING_STUDENT_REGISTRATION,"Error restoring student registration! Please try again");
        }
    }
    
    /**
     * Get Student Exam Notification
     * @param $request
     */
    public function  getStudentExamNotification($request){
        $searchRequest = new \stdClass();
        $searchRequest->studentId = $request->studentId;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $studentDetails = reset($this->getStudentExamRegistrationFeeDetails($searchRequest));
        if(count($studentDetails->batchFeeFine) > 1){
                $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
        }
        else{
            $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
        }
        $currentFineTypes = reset($studentDetails->currentBatchCommonFeeFine->batchCommonFines)->fineType;
        $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->currentExamRegistrationType;
        }));
        // $searchRequestCustomFeild = new \stdClass();
        // $coustomFeilds = CostomFeildMasterService::getInstance()->getAllCoustomFeilds($searchRequestCustomFeild);
        $assignedCustomFeildsWithKey = [];
        if($studentDetails->batchProperties->customFeilds){
            $assignedCustomFeilds = json_decode($studentDetails->batchProperties->customFeilds);
            foreach($assignedCustomFeilds as $assignedCustomFeild){
                if($assignedCustomFeild->type == 'DATE_TIME'){
                    $assignedCustomFeild->date = $assignedCustomFeild->value;
                    $assignedCustomFeild->value = date('d/m/Y', strtotime($assignedCustomFeild->date));
                    $assignedCustomFeild->updatedValue = date('d M Y', strtotime($assignedCustomFeild->date));
                }
                $assignedCustomFeildsWithKey[$assignedCustomFeild->code] = $assignedCustomFeild;
            }
        }
        $studentDetails->assignedCustomFeilds = $assignedCustomFeildsWithKey;
        
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REGULAR';
        $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
        $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
        $subjectLimitFees = [];
        $subjectLimitCounts = [];
        foreach($allCommonFees as $commonFee){
            if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject != '1' ){
                    if($studentCommonFees->feeType[$commonFee->id]->value){
                        $currentFee = new \stdclass;
                        $currentFee->feeName = $commonFee->name;
                        $currentFee->subFees = [];
                        $currentFee->value = $currentFee->isSubjectFeeLimit ? 0 : $studentCommonFees->feeType[$commonFee->id]->value;
                        $studentDetails->commonFees[] = $currentFee;
                    }
                } 
                else if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject == '1'){
                    if($commonFee->feeSelectionSubjectLimit && $studentCommonFees->feeType[$commonFee->id]->value){
                        $subjectLimitFees[$commonFee->feeSelectionSubjectLimit] =  $studentCommonFees->feeType[$commonFee->id]->value;
                        $subjectLimitCounts[$commonFee->feeSelectionSubjectLimit] = $commonFee->feeSelectionSubjectLimit;
                        
                    }
                } 
            }
        }
        if(!empty($subjectLimitFees)){
            $subjectCount = count($studentDetails->subjects);
            sort($subjectLimitCounts);
            $index = array_search($subjectCount, $subjectLimitCounts);
            $resultIndex = ($index !== false && $subjectLimitCounts[$index] == $subjectCount) ? $subjectLimitCounts[$index] : (empty($subjectLimitCounts) ? null : max(array_filter($subjectLimitCounts, function($value) use ($subjectCount) {
                return $value <= $subjectCount;
            })));
            if(!empty($subjectLimitFees[$resultIndex])){
                $currentFee = new \stdclass;
                $currentFee->feeName = "Total Subject Fee";
                $currentFee->isSubjectFeeLimit = 0;
                $currentFee->value = $subjectLimitFees[$resultIndex];
                $studentDetails->commonFees[] = $currentFee;
            }
        }
        // $currentFee = new \stdclass;
        // $currentFee->feeName = "Examination Fee";
        // $currentFee->subFees = [];
        //     $subFee = new \stdclass;
        //     $subFee->feeName = "Each theory paper";
        //     $subFee->feeValue[] = "40/- (B.A., B.Sc., B.Com. & Integrated M.A. Sociology)";
        //     $subFee->feeValue[] = "60/- (B.Voc.)";
        //     $subFee->feeValue[] = "115/- (BBA)";
        //     $subFee->feeValue[] = "85/- (M.A., M.Sc., M.Com.)";
        // $currentFee->subFees[] = $subFee;
        //     $subFee = new \stdclass;
        //     $subFee->feeName = "Each practical paper";
        //     $subFee->feeValue[] = "60/- (B.A., B.Sc. & B.Com.)";
        //     $subFee->feeValue[] = "115/- (B.Voc.)";
        // $currentFee->subFees[] = $subFee;
        // $studentDetails->commonFees[] = $currentFee;
        $paymentMethods =  $studentDetails->examRegistrationProperties->paymentMethods;
        $paymentMethodsArr =  [];
        foreach ( $paymentMethods as $paymentMethod){
            if($paymentMethod == ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD){
                $paymentMethodsArr[] =  "College Challan Method";
            }
            if($paymentMethod == ExamPaymentMethodConstants::BANK_CHALLAN_METHOD){
                $paymentMethodsArr[] =  "Bank Challan Method";
            }
            if($paymentMethod == ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD){
                $paymentMethodsArr[] =  "Online Payment Method";
            }
        }
        $studentDetails->examMonthName = ExamRegistrationService::getInstance()->getMonthName($studentDetails->examRegistrationProperties->examMonth);
        $studentDetails->examYear = $studentDetails->examRegistrationProperties->examYear;
        $semesterNames = CommonExamService::getInstance()->getDifferentSemesterName($studentDetails->academicTermName);
        $studentDetails->semInFullName = $semesterNames->fullName;
        $studentDetails->semNumberSuffix = CommonExamService::getInstance()->addOrdinalNumberSuffix($studentDetails->academicTermId,false);
        
        $studentDetails->paymentMethodStr = implode(' / ', $paymentMethodsArr);
        $studentDetails->notificationNumber = "CCAM/ CE-01/Circ/2022";
        $studentDetails->examRegType = ucfirst(strtolower($studentDetails->examRegistrationType));
        $studentDetails->examDate = date("d-m-Y", strtotime( $studentDetails->examRegistrationProperties->examDate));
        $studentDetails->attendanceClosingDate = date("d-m-Y", strtotime( $studentDetails->examRegistrationProperties->attendanceClosingDate));
        $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
        foreach($allCommonFines as $commonFine){
            foreach($currentFineTypes as $fineType){
                if ( $fineType->id == $commonFine->id ) {
                    $fineType->name = $commonFine->name;
                    $fineType->startDate = date("d-m-Y h:i A", strtotime($fineType->startDate));
                    $fineType->endDate = date("d-m-Y h:i A", strtotime($fineType->endDate));
                    $fineType->endDateOnly = date("d/m/Y", strtotime($fineType->endDate));
                    $fineType->verificationDate = date("d-m-Y h:i A", strtotime($fineType->verificationDate));
                    $studentDetails->commonFines[] = $fineType;
                }
            }
        }
        $collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $templateName = "ExamNotificationTemplate_2";
        $examType = 'EC_EXAM_NOTIFICATION_TEMPLATE';
        $notificationTemplate = StudentMarkListService::getInstance()->getUniversityMarkListTemplate($examType);
        if($notificationTemplate == "Template_1"){
            $templateName = "ExamNotificationTemplate_1";
        }else if($notificationTemplate == "Template_2"){
            $templateName = "ExamNotificationTemplate_2";
        }
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/ExamNotificationTemplate/$templateName.twig"), [ 'data'=>$studentDetails,'college'=>$collegeData ]);
        $prtContent = NULL;
        $prtContent .= '<html><head>';
        $prtContent .= "<style>
            
            </style>";
        $prtContent .= '</head><title>Exam Notification</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' => "10mm",
            'margin-right' => "10mm",
            '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 Student College Challan
     * @param $request
     */
    public function  getStudentCollegeChallanTemplate($request){
        $searchRequest = new \stdClass();
        $searchRequest->studentId = $request->studentId;
        $studentCommonFeesIdsArray = [];
        $studentCommonFineIdsArray = [];
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->registrationStatus = StudentExamRegistrationStatus::APPLIED;
        $studentDetails = reset($this->getStudentExamRegistrationFeeDetails($searchRequest));
        if(count($studentDetails->batchFeeFine) > 1){
                $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
        }
        else{
            $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
        }
        $studentDetails->examRegType = ucfirst(strtolower($studentDetails->examRegistrationType));
        $studentDetails->examDate = date("d-m-Y", strtotime( $studentDetails->examRegistrationProperties->examDate));
        $studentDetails->monthYear = date("M Y", strtotime( "1-".$studentDetails->examRegistrationProperties->examMonth."-".$studentDetails->examRegistrationProperties->examYear));
        $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
         // ------------studdent common Fees --------------- 
         $studentDetails->commonFees = [];   
         $studentDetails->totalCommonFees = 0;  
         $feeRequest = new \stdClass;
         $feeRequest->examType = 'REGULAR';
         $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
         $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
             return $value->examRegistrationType == $studentDetails->assessmentRegistrationType;
         }));
        $subjectCount = count($studentDetails->subjects);
        $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
        $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
        $subjectLimitFees = [];
        $subjectLimitCounts = [];
         foreach($allCommonFees as $commonFee){
             if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                 if($studentCommonFees->feeType[$commonFee->id]->value){
                     if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject != '1'){
                         $currentFee = new \stdclass;
                         $currentFee->name = $commonFee->name;
                         $currentFee->isSubjectFeeLimit = $commonFee->isSubject_fee_limit;
                         $currentFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                         $currentFee->currentValue = $studentCommonFees->feeType[$commonFee->id]->value;
                         $currentFee->maxValue = $currentFee->isSubjectFeeLimit ? $studentCommonFees->feeType[$commonFee->id]->maxValue : 0;
                         if($currentFee->isSubjectFeeLimit && $subjectCount > 0){
                            $currentFee->value = $currentFee->currentValue * $subjectCount;
                            if($currentFee->value > $currentFee->maxValue){
                                $currentFee->value = $currentFee->maxValue;
                            }
                         }
                         $studentDetails->totalCommonFees += $currentFee->value;
                         $studentDetails->allFees[] = $currentFee;
                     } 
                    else if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject == '1'){
                        if($commonFee->feeSelectionSubjectLimit && $studentCommonFees->feeType[$commonFee->id]->value){
                            $subjectLimitFees[$commonFee->feeSelectionSubjectLimit] =  $studentCommonFees->feeType[$commonFee->id]->value;
                            $subjectLimitCounts[$commonFee->feeSelectionSubjectLimit] = $commonFee->feeSelectionSubjectLimit;
                            
                        }
                    } 
                 }
             }
         }
         if(!empty($subjectLimitFees)){
            $subjectCount = count($studentDetails->subjects);
            sort($subjectLimitCounts);
            $index = array_search($subjectCount, $subjectLimitCounts);
            $resultIndex = ($index !== false && $subjectLimitCounts[$index] == $subjectCount) ? $subjectLimitCounts[$index] : (empty($subjectLimitCounts) ? null : max(array_filter($subjectLimitCounts, function($value) use ($subjectCount) {
                return $value <= $subjectCount;
            })));
            if(!empty($subjectLimitFees[$resultIndex])){
                $currentFee = new \stdclass;
                $currentFee->feeName = "Total Subject Fee";
                $currentFee->isSubjectFeeLimit = 0;
                $currentFee->value = $subjectLimitFees[$resultIndex];
                $studentDetails->totalCommonFees += $currentFee->value;
                $studentDetails->allFees[] = $currentFee;
            }
        }
        // ------------Studdent Subject Fees --------------- 
        $studentDetails->totalSubjectFees = 0;
        foreach($studentDetails->subjects as $subject){
            if(empty($subject->studentAssessmentRegistrationProperties)){
                continue;
            }
            $subject->currentSubjectFeeProperties = reset(array_filter($subject->subjectFeeProperties,function($value)use($studentDetails){
                return $value->examRegistrationType == $studentDetails->assessmentRegistrationType;
            }));
            $subject->currentSubjectFeeProperties->feeType = (array)$subject->currentSubjectFeeProperties->feeType;
            $subject->subjectFeeTemplateIdsArray = array_keys($subject->currentSubjectFeeProperties->feeType);
            $subject->currentFeeTypeTemplateId = ExamRegistrationFeeCommonService::getInstance()->getCurrentSubjectFeeTemplateForStudent($subject,$studentDetails);
            $subject->value =  $subject->currentFeeTypeTemplateId ? $subject->currentSubjectFeeProperties->feeType[$subject->currentFeeTypeTemplateId]->value : 0;
            $studentDetails->totalSubjectFees += $subject->value;
        }
        $currentFine = new \stdclass;
        $currentFine->name = "Total Paper Fees";
        $currentFine->value = $studentDetails->totalSubjectFees;
        $studentDetails->allFees[] = $currentFine;
         // ------------studdent common Fines ---------------    
         $studentDetails->commonFines = []; 
         $studentDetails->totalCommonFines = 0;
         $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
         $studentCommonFines = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFines,function($value)use($studentDetails){
             return $value->examRegistrationType == $studentDetails->assessmentRegistrationType;
         }));
         $studentCommonFineIdsArray = array_keys((array)$studentCommonFines->fineType);
         $studentCommonFines->fineType = (array)$studentCommonFines->fineType;
         $today = date("Y-m-d H:i");
         if ( $request->previewType == 'PRINT_COPY' ) {
            $today = $studentDetails->examRegistrationPaymentProperties->challanAppliedDate? $studentDetails->examRegistrationPaymentProperties->challanAppliedDate :date("Y-m-d H:i");
         }
         $maxEndDate = $studentDetails->examRegistrationProperties->registrationWithoutFineEndDate;
         foreach($allCommonFines as $commonFine){
             if ( in_array ( $commonFine->id, $studentCommonFineIdsArray ) ) {
                 if((strtotime($today) >= strtotime($studentCommonFines->fineType[$commonFine->id]->startDate)) && ($today <= $studentCommonFines->fineType[$commonFine->id]->endDate )){
                    $verificationDate = $verificationDate  ?? $studentCommonFines->fineType[$commonFine->id]->verificationDate;
                    $currentFine = new \stdclass;
                    $currentFine->name = $commonFine->name;
                    $currentFine->value = $studentCommonFines->fineType[$commonFine->id]->value;
                    $studentDetails->totalCommonFines += $currentFine->value;
                    $studentDetails->allFees[] = $currentFine;
                    if($studentCommonFines->fineType[$commonFine->id]->endDate >= $maxEndDate){
                        $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                    }
                    if(strtotime($studentCommonFines->fineType[$commonFine->id]->verificationDate) >= strtotime($verificationDate)){
                        $verificationDate = $studentCommonFines->fineType[$commonFine->id]->verificationDate;
                    }
                    
                 } 
             }
         }
         $studentDetails->verificationDate = $verificationDate;
         $studentDetails->totalFeeAmount = $studentDetails->totalCommonFines + $studentDetails->totalCommonFees + $studentDetails->totalSubjectFees;
         $studentDetails->currentDate = date('d-m-Y');
         $studentDetails->totalFeeAmountInWords = CommonUtil::convertNumberToWords( $studentDetails->totalFeeAmount );
         $studentDetails->challanNo = $studentDetails->examRegistrationPaymentProperties->challanNo;
         $barcodeObj = new TCPDFBarcode( $studentDetails->challanNo , 'C128');
         $studentDetails->barcodeObj = $barcodeObj->getBarcodeHTML($w = 1, $h = 40, $color = 'black');
        global $COLLEGE_NAME, $autonomous, $PLACE;
        $studentDetails->collegeName =  $COLLEGE_NAME;
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/CollegeChallanTemplate/CollegeChallanDefault.twig"), [ 'data'=>$studentDetails ]);
        // $responseHtml = "ASDADA";
        $prtContent = NULL;
        $prtContent .= '<html><head>';
        $prtContent .= "<style>
            
            </style>";
        $prtContent .= '</head><title>College Challan </title><body>';
        $prtContent .= $responseHtml;
        $prtContent .= '</body></html>';
        $totalWidth = 310;
        $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;
       
    }
    /**
     * Verify If Challan No Already Exist
     * @param $request
     * @return $id
     */
    public function checkChallanNoAlreadyExist ($request)
    {
        $request = $this->realEscapeObject($request);
       
        $query = "SELECT
               eserd.properties->>'$.challanNo' as challanNo
            FROM
                ec_student_exam_registration_details eserd
            WHERE
                eserd.properties->>'$.challanNo' = '$request->challanNo'";
        try{
            $registeredStudent = $this->executeQueryForObject($query);
          
        }catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage()); 
        }
        return $registeredStudent ;
        
    }
    /**
     * Get Challan Details
     * @param $request
     * @return $id
     */
    public function getStudentChallanDetails ($request)
    {
        $request = $this->realEscapeObject($request);
       
        $query = "SELECT 
                    eserd.student_id  as studentId, 
                    eserd.ec_exam_registration_id as examRegistrationId 
                FROM
                    ec_student_exam_registration_details eserd
                INNER JOIN 
                    ec_exam_registration eer ON eer.id = eserd.ec_exam_registration_id 
                WHERE 
                    eer.`type` = '$request->examType' AND  eserd.properties->>'$.challanNo' = '$request->challanNo'";
        try{
            $challanDetails = $this->executeQueryForObject($query);
          
        }catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage()); 
        }
        return $challanDetails ;
        
    }
    /**
     * Get Student College Challan
     * @param $request
     */
    public function  getStudentExamTimeTable($request){
        $searchRequest = new \stdClass();
        $searchRequest->studentId = $request->studentId;
        if($request->examType == 'SUPPLEMENTARY'){
            $searchRequest->examRegistrationType = 'SUPPLEMENTARY';
            $searchRequest->examRegistrationId = $request->examRegistrationId;
        }
        else{
            $searchRequest->academicTermId = $request->academicTermId;
            $searchRequest->examRegistrationType = 'REGULAR';
        }
        $searchRequest->considerPublishedTimeTable = 1;
        $examTimeTable = reset(HallTicketsService::getInstance()->getRegisteredStudentSubjectsDetailsForHallTickets($searchRequest));
        $programResult = new \stdClass;                
        
        $found = 0;
        foreach($examTimeTable->subjects as $subject){
            if($subject->assessmentDate){
                $found = 1;
            }
            $subject->blocked = false;
            $subject->assessmentDate =  $subject->assessmentDate ? date("d/m/Y", strtotime($subject->assessmentDate)) : '';
            $subject->assessmentStartTime =  $subject->assessmentStartTime &&  $subject->assessmentStartTime != 'null' ? date("h:i A", strtotime($subject->assessmentStartTime)) : '';
            $subject->assessmentEndTime =  $subject->assessmentEndTime && $subject->assessmentEndTime != 'null' ? date("h:i A", strtotime($subject->assessmentEndTime)) : '';
        }
        $templateName = "Template_1";
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/ExamTimeTable/$templateName.twig"), [ 'data'=>$examTimeTable ]);
    
        if(  $found == 0 ){
            $responseHtml = '';
        }
        $programResult->dispalyHtmlData = $responseHtml;
        $programResult->examDetails = $examTimeTable;
        return  $programResult;
       
    }
   
    /**
     * Save with held status to student exam registration
     * @param Object $request
     * @author Krishnajith V
     */
    public function saveWithHeldStatus($request){
        $request = $this->realEscapeObject($request);
        if ($request->examRegistrationId && $request->studentId) {
            try {
                $withHeldStatus = $request->withHeldStatus ? 1 : 0;
                $sql = "UPDATE ec_student_exam_registration_details SET properties = JSON_SET(properties, '$.isResultWithHeld',$withHeldStatus) WHERE ec_exam_registration_id = '$request->examRegistrationId' AND student_id = '$request->studentId'";
                $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     * Search stduent Exam Revaluation Subjects For manage registration
     * @param  $request
     * @return examRevaluation
     */
    public function getAllRevaluationSubjectsForManageStudentRegistration( $request){
        // revaluation rule
        $searchRuleRequest = new SearchRuleRequest;
        $searchRuleRequest->name = "REVALUATION_SETTINGS_RULE";
        $settingsRule = reset(RuleService::getInstance()->searchRule($searchRuleRequest))->rule;
        $registrationStatus = ["APPLIED","REGISTERED"];
        $searchRequest = new \stdClass;
        $searchRequest->studentId = $request->studentId;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->academicPaperSubjectId = $request->academicPaperSubjectId;
        $searchRequest->notConsiderValidation = $request->notConsiderValidation;
        $searchRequest->registrationStatus = $request->registrationStatus;
        $searchRequest->isBackEndRegistration = $request->isBackEndRegistration;
        if($searchRequest->isBackEndRegistration == 'true' && in_array('NOT_REGISTERED', $request->registrationStatus)){
            $searchRequest->registrationStatus = [];
        }
        
        $studentDetails =  reset($this->getStudentRevaluationDetails($searchRequest));
        $studentDetails->selectedSubjectCount = 0;
        if(!empty($studentDetails->examRevaluationProperties->parentRevaluationRegistrationIds)){
            $searchParentExamRevaluationDetailsRequest = new \stdClass;
            $searchParentExamRevaluationDetailsRequest->studentId = $request->studentId;
            $searchParentExamRevaluationDetailsRequest->examRegistrationId = $studentDetails->examRevaluationProperties->parentRevaluationRegistrationIds;
            $parentExamRevaluationDetails =  reset($this->getParentRevaluationRegistredStudentDetails($searchParentExamRevaluationDetailsRequest));
            $requestForExamRegistration = new SearchExamRegistrationRequest;
            $requestForExamRegistration->ids = $studentDetails->examRevaluationProperties->parentRevaluationRegistrationIds;
            $parentExamRevaluations = ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration);
            $parentExamRevaluationNames = array_column($parentExamRevaluations,'name');
            $errorMsg = "Please Register <b>".implode("  <br> and",$parentExamRevaluationNames) ." </b> revaluation(s) first";
            if(empty($parentExamRevaluationDetails)){
                throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,$errorMsg);
            }
            else{
                // foreach($parentExamRevaluationDetails->subjects as $key=> $parentRevaluationRegisteredSubject){
                //     $parentRevaluationRegisteredSubject->revaluationIds =  array_column($parentRevaluationRegisteredSubject->exams,'id');
                //     $arrayDiff = array_diff($studentDetails->examRevaluationProperties->parentRevaluationRegistrationIds,$parentRevaluationRegisteredSubject->revaluationIds);
                //     if(!empty($arrayDiff)){
                //         unset($parentExamRevaluationDetails->subjects[$key]);
                //     }
                // }
                $parentExamRevaluationDetails->registeredSubjects = array_column($parentExamRevaluationDetails->subjects,'assessmentId');
                foreach($studentDetails->subjects as $subKey=>  $subject){
                    if ( !in_array ( $subject->assessmentId, $parentExamRevaluationDetails->registeredSubjects ) ) {
                        unset($studentDetails->subjects[$subKey]);
                    }
                }
                if(empty($studentDetails->subjects)){
                    throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,$errorMsg);
                }
            }
        }
        $studentDetails->totalFeeAmount = $studentDetails->totalStudentFee = $studentDetails->totalSubjectFees = $studentDetails->paidAmount = 0;
         // ------------Studdent common Fees & Fines --------------- 
        if(count($studentDetails->batchFeeFine) > 1){
            $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
        }
        else{
            $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
        }
        // ------------studdent common Fees --------------- 
        $studentDetails->commonFees = [];   
        $studentDetails->totalCommonFees = 0;  
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REVALUATION';
        $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRevaluationType;
        }));
        $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
        $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
        foreach($allCommonFees as $commonFee){
            if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                if($commonFee->isCommon ){
                    $currentFee = new \stdclass;
                    $currentFee->feeName = $commonFee->name;
                    $currentFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                    $studentDetails->totalCommonFees += $currentFee->value;
                    $studentDetails->commonFees[] = $currentFee;
                } 
                else{
                    $revaluationFee = new \stdclass;
                    $revaluationFee->id = $commonFee->id;
                    $revaluationFee->feeName = $commonFee->name;
                    $revaluationFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                    $studentDetails->revaluationFee[] = $revaluationFee;
                }
            }
        }  
         // ------------Not fetch Absent Students --------------- 
        $studentDetails->subjects = array_filter($studentDetails->subjects,function($value){
            return $value->subjectMarkDetails->attendanceStatus == "PRESENT";
        });
        $studentDetails->subjects = array_values($studentDetails->subjects);
        if($settingsRule->fetchTheorySubjectsOnly){
            // ------------Remove Practical Subjects --------------- 
            $studentDetails->subjects = array_filter($studentDetails->subjects,function($value){
                return !in_array($value->classType, ["PRACTICAL", "PROJECT","SEMINAR"]);
            });
            $studentDetails->subjects = array_values($studentDetails->subjects);
        }
         // ------------Student Fees--------------- 
         foreach($studentDetails->subjects as $key=>  $subject){
            $subject->feeValue = 0;
            $subject->revaluationTypeArray = [];
            $subject->registeredRevaluationType = [];
            $subject->revaluationTypes = [];
            $subject->availableRevaluationTypes = [];
            $subject->isAlreadyApplied = false;
            foreach($studentDetails->revaluationFee as $revaluationFee){
                $revaluationRegistrationDetails = new \stdClass;
                $revaluationRegistrationDetails->revaluationId = $revaluationFee->id;
                $revaluationRegistrationDetails->registrationStatus = "";
                $subject->revaluationRegistrationStatus[$revaluationFee->id] = $revaluationRegistrationDetails;
            }
            if(!empty($subject->studentAssessmentRegistrations)){
                foreach($subject->studentAssessmentRegistrations as $studentAssessmentRegistration){
                    if(in_array($studentAssessmentRegistration->studentRegistrationStatus,$registrationStatus)){
                        $subject->revaluationTypes[] =  $studentAssessmentRegistration->studentRevaluationType;
                        $subject->isAlreadyApplied = true;
                    }
                    if($studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::REGISTERED){
                        foreach($studentDetails->revaluationFee as $revaluationFee){
                            if($revaluationFee->id == $studentAssessmentRegistration->studentRevaluationType){
                                if( !$request->notConsiderPaidAmount ){
                                    $studentDetails->paidAmount += (int)$revaluationFee->value;
                                }
                            }
                        }
                    }
                }
            }
        }
        $studentDetails->selectedSubjectCount = count(array_filter($studentDetails->subjects,function($subject){
            return $subject->isAlreadyApplied;
        }));
        foreach($studentDetails->subjects as $key=>  $subject){
            if(in_array('NOT_REGISTERED', $request->registrationStatus) && $searchRequest->isBackEndRegistration){
                if(count($subject->revaluationTypes) < count($studentDetails->examRevaluationProperties->revaluationFeeTypeIds)){
                    $subject->availableRevaluationTypes = array_diff($studentDetails->examRevaluationProperties->revaluationFeeTypeIds,$subject->revaluationTypes);
                }
                else if(count($subject->revaluationTypes) == count($studentDetails->examRevaluationProperties->revaluationFeeTypeIds)){
                    unset($studentDetails->subjects[$key]);
                }
            }
            foreach($studentDetails->revaluationFee as $revaluationFee){
                if(in_array($revaluationFee->id, $subject->availableRevaluationTypes)){
                    $revaluationTypeArray = new \stdClass;
                    $revaluationTypeArray->id = $revaluationFee->id;
                    $revaluationTypeArray->name = $revaluationFee->feeName;
                    $subject->revaluationTypeArray[$revaluationFee->id] = $revaluationTypeArray;
                }
            }
            $subject->revaluationTypeArray = array_values($subject->revaluationTypeArray);
        }
        $studentDetails->subjects = array_values($studentDetails->subjects);
        $studentDetails->balanceAmount = 0;
        // if($studentDetails->balanceAmountDetails){
        //     $studentDetails->balanceReturnedStatus = $studentDetails->balanceAmountDetails->balanceReturnedStatus ? true : false;
        //     if($studentDetails->balanceAmountDetails->balanceAmount && $studentDetails->balanceAmountDetails->balanceReturnedStatus == false){
        //         $studentDetails->balanceAmount = (int)$studentDetails->balanceAmountDetails->balanceAmount;
        //     }
        //     else{
        //         $studentDetails->balanceAmount = 0;
        //     }
        // }
        $studentDetails->balanceAmountCopy = $studentDetails->balanceAmount;
        $studentDetails->paidAmount = $studentDetails->paidAmount ? $studentDetails->paidAmount + $studentDetails->totalCommonFees : 0;
        $studentDetails->totalFeeAmount = $studentDetails->paidAmount;
        // ---------------- Calculation For save student registration-------------
        // if($request->isSaveStudentExamRegistration){
        //     if(($studentDetails->paidAmount >= $studentDetails->totalStudentFee)){
        //         $studentDetails->amountTobePaid = 0;
        //         $studentDetails->balanceAmount += $studentDetails->paidAmount - $studentDetails->totalStudentFee;
        //     }
        //     else{
        //         $amountTobePaid = $studentDetails->totalStudentFee - $studentDetails->paidAmount;
        //         if($amountTobePaid > $studentDetails->balanceAmount){
        //             $studentDetails->amountTobePaid = $amountTobePaid - $studentDetails->balanceAmount;
        //             $studentDetails->balanceAmount = 0;
        //         }
        //         else{
        //             $studentDetails->balanceAmount -= $amountTobePaid;
        //             $studentDetails->amountTobePaid = 0;
        //         }
        //     }
        // }
        // if (strtotime($studentDetails->registrationStartDate) > strtotime(date("Y-m-d")) && !$request->notConsiderValidation) {
        //     throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration not started");
        // }
        // elseif (strtotime($studentDetails->registrationEndDate)  < strtotime(date("Y-m-d")) && !$request->notConsiderValidation) {
        //     throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration closed");
        // }
        if(empty($studentDetails->subjects)){
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Not applicable !!");
        }
        return($studentDetails); 
    }
    /** 
     * get Exam MarkEntry For Exam Revaluation 
     * @param $request
     * @throws ExamControllerException
     */
    public function getExamMarkEntryForExamRevaluation($searchRequest){
        $searchRequest = $this->realEscapeObject($searchRequest);
        $whereQuery = "";
        if(!empty($searchRequest->groupId)) {
            $groupIdString = is_array($searchRequest->groupId) ? "'" . implode("','",$searchRequest->groupId) . "'" : "'".$searchRequest->groupId."'";
            $whereQuery .= " AND g.id IN ( $groupIdString )";
        }
        if(!empty($searchRequest->academicPaperSubjectId)) {
            $academicPaperSubjectIdString = is_array($searchRequest->academicPaperSubjectId) ? "'" . implode("','",$searchRequest->academicPaperSubjectId) . "'" : "'".$searchRequest->academicPaperSubjectId."'";
            $whereQuery .= " AND eersParent.cm_academic_paper_subjects_id IN ( $academicPaperSubjectIdString )";
        }
        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 esar.student_id IN ( $studentIdString )";
        }
        $query = "SELECT DISTINCT
                        oetm.id
                    FROM
                        ec_exam_registration eer
                    INNER JOIN ec_exam_registration_batch eerb ON
                        eerb.ec_exam_registration_id = eer.id 
                    INNER JOIN ec_exam_registration eerParent ON
                        eerParent.id = eer.properties->>'$.parentExamRegistrationId' AND 
                        eerParent.trashed IS NULL
                    INNER JOIN ec_exam_registration_batch eerbParent ON
                        eerbParent.ec_exam_registration_id = eerParent.id  AND 
                        eerb.groups_id = eerbParent.groups_id
                    INNER JOIN ec_exam_registration_subject eersParent ON     
                        eersParent.ec_exam_registration_batch_id = eerbParent.id 
                    INNER JOIN `groups` g ON
                        g.id = eerb.groups_id
                        AND g.`type` = 'BATCH'
                    INNER JOIN ec_student_assessment_registration esar ON
                        esar.am_assessment_id = eersParent.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 oe_student_total_mark oetm ON 
                        oetm.student_id = esar.student_id AND oetm.am_assessment_id = esar.am_assessment_id AND oetm.valuation_type = 'REVALUATION'
                    WHERE 1=1 ";
        try {
            $examMarkEntry =  $this->executeQueryForList($query.$whereQuery);
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $examMarkEntry;
    }
    /**
     * update Balance amount details in exam registration
     * @param Object $request
     * @author Krishnajith V
     */
    public function updateBalceAmountDetailsInExamRegistration($request){
        $request = $this->realEscapeObject($request);
        $currentStaffId = $GLOBALS['userId'];
        if ($request->examRegistrationId && $request->studentId) {
            $searchRequest = new \stdClass;
            $searchRequest->examRegistrationId = $request->examRegistrationId;
            $searchRequest->studentId = $request->studentId;
            $studentExamRegistrationDetails = reset(StudentExamRegistrationService::getInstance()->getCurrentPaymentStatusForStudent($searchRequest));
            if(!$studentExamRegistrationDetails){
                throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"No details found!");
            }
            $balanceAmountDetails = json_decode($studentExamRegistrationDetails->balanceAmountDetails);
            $studentExamRegistrationDetails->updatedTime = date("Y-m-d H:i");
            $balanceAmountDetails->balanceReturnedLog = $balanceAmountDetails->balanceReturnedLog ?? [] ;
            $balanceReturnedLog = new \stdClass;
            $balanceReturnedLog->balanceAmount = $balanceAmountDetails->balanceAmount;
            $balanceReturnedLog->updatedTime = date("Y-m-d H:i");
            $balanceReturnedLog->updatedBy = $currentStaffId;
            $balanceAmountDetails->balanceReturnedLog[] = $balanceReturnedLog;
            $balanceAmountDetails->balanceAmount = 0;
            $balanceAmountDetails->balanceReturnedStatus = false;
            $balanceAmountDetails = !empty($balanceAmountDetails) ? "'" . json_encode($balanceAmountDetails) . "'" : "'{}'";
            try {
                $sql = "UPDATE ec_student_exam_registration_details SET balance_amount_details = $balanceAmountDetails WHERE ec_exam_registration_id = '$request->examRegistrationId' AND student_id = '$request->studentId'";
                $this->executeQueryForObject($sql);
                $this->logger->info(Events::EC_UPDATE_STUDENT_BALANCE_AMOUND_DETAILS,[
                    "staff" => new Staff(["id" => $currentStaffId]),
                    "request" => $studentExamRegistrationDetails,
                    "status" => StatusConstants::SUCCESS
                ]);
            }catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     * Get revaluation student registered report
     * @param Object $request
     * @author Krishnajith V
     */
    public function getRevaluationStudentRegisteredReport($request){
        $request = $this->realEscapeObject($request);
        $searchRequest = new \stdClass;
        $data = new \stdClass;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->studentId = $request->studentId;
        $searchRequest->registrationStatus = $request->registrationStatus;
        $studentDetails = reset($this->searchAllStudentDetailsByExamRevaluation($searchRequest));
        $data->collegeData = CommonExamService::getInstance()->getCollegeDetails();
        if(!$studentDetails){
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"No details found!");
        }
        $request = new \stdClass;
        $request->examType = 'REVALUATION';
        $request->excludeCommonFees = '1';
        $feesTypes = CommonExamService::getInstance()->getAllFeesTypes($request);
        foreach($studentDetails->subjects as $subject){
            foreach($feesTypes as $fee){
                if(in_array($fee->id, $subject->revaluationTypes)){
                    $subject->revaluationNames[] = $fee->name;
                }
            }
        }
        $data->student = $studentDetails;
        $templateName = "RevaluationRegisteredStudentReportTemplate";
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/RevaluationRegisteredStudentReport/$templateName.twig"), [ 'data'=>$data ]);
        $prtContent = NULL;
        $prtContent .= '<html><head><link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">';
        $prtContent .= "<style>
            .displayOnlyDisplayData { display: none; }
            </style>";
        $prtContent .= '</head><title>Revaluation Registered 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;
    }
    /**
     * Search stduent Regular Exam Registration For Bulk Exam Registration
     * @param $request
     * @return examRegistration
     */
    public function getStudentRegularExamRegistrationSubjectFeeDetailsForBulkStudentRegistration($request){
        $searchRequest = new \stdClass;
        $searchRequest->studentId = $request->studentId;
        $studentCommonFeesIdsArray = [];
        $studentCommonFineIdsArray = [];
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->registrationStatus =  $request->registrationStatus;
        $searchRequest->groupId =  $request->groupId;
        $searchRequest->notConsiderEmptyValidation = true;
        $students = $this->getStudentExamRegistrationFeeDetails($searchRequest);
        foreach($students as $studentDetails){
            $studentDetails->totalFeeAmount = 0;
            // ------------Studdent common Fees & Fines --------------- 
            if(count($studentDetails->batchFeeFine) > 1){
                $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
            }
            else{
                $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
            }
            // ------------Remove Attendance Shortage Subjects Student Side--------------- 
            if($studentDetails->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SUBJECT_WISE'){
                $studentDetails->registeredSubjects = [];
                foreach($studentDetails->subjects as $key=> $subject){ 
                    $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
                    $attendanceTermWiseReportRequest->studentId = $studentDetails->studentId;
                    $attendanceTermWiseReportRequest->termId = $studentDetails->academicTermId;
                    $attendanceTermWiseReportRequest->paperSubjectId = $subject->academicPaperSubjectId;
                    $attendanceTermWiseReportRequest->attendanceClosingDate = $studentDetails->batchProperties->attendanceClosingDate;
                    $subject->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
                    $subject->isShortageAttendance  = ($subject->properties->minimumAttendancePercentage > $subject->attendanceDetails->attendancePercentage) ? true : false;
                    if($subject->isShortageAttendance && !$request->notConsiderValidation){
                        unset($studentDetails->subjects[$key]);
                    }
                    else{
                        $studentDetails->registeredSubjects[] = $subject;
                    }
                }
                $studentDetails->subjects = $studentDetails->registeredSubjects;
            }
            // ------------studdent common Fees --------------- 
            $studentDetails->commonFees = [];   
            $studentDetails->totalCommonFees = 0;  
            $feeRequest = new \stdClass;
            $feeRequest->examType = 'REGULAR';
            $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
            $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
                return $value->examRegistrationType == $studentDetails->examRegistrationType;
            }));
            $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
            $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
            $subjectLimitFees = [];
            $subjectLimitCounts = [];
            foreach($allCommonFees as $commonFee){
                if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                    if($studentCommonFees->feeType[$commonFee->id]->value){
                        if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject != '1'){
                            $currentFee = new \stdclass;
                            $currentFee->feeName = $commonFee->name;
                            $currentFee->isSubjectFeeLimit = $commonFee->isSubject_fee_limit;
                            $currentFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                            $currentFee->currentValue = $studentCommonFees->feeType[$commonFee->id]->value;
                            $currentFee->maxValue = $currentFee->isSubjectFeeLimit ? $studentCommonFees->feeType[$commonFee->id]->maxValue : 0;
                            $studentDetails->totalCommonFees += $currentFee->value;
                            $studentDetails->commonFees[] = $currentFee;
                        } 
                        else if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject == '1'){
                            if($commonFee->feeSelectionSubjectLimit && $studentCommonFees->feeType[$commonFee->id]->value){
                                $subjectLimitFees[$commonFee->feeSelectionSubjectLimit] =  $studentCommonFees->feeType[$commonFee->id]->value;
                                $subjectLimitCounts[$commonFee->feeSelectionSubjectLimit] = $commonFee->feeSelectionSubjectLimit;
                            }
                        } 
                    }
                }
            }
            if(!empty($subjectLimitFees)){
                $subjectCount = count($studentDetails->subjects);
                sort($subjectLimitCounts);
                $index = array_search($subjectCount, $subjectLimitCounts);
                $resultIndex = ($index !== false && $subjectLimitCounts[$index] == $subjectCount) ? $subjectLimitCounts[$index] : (empty($subjectLimitCounts) ? null : max(array_filter($subjectLimitCounts, function($value) use ($subjectCount) {
                    return $value <= $subjectCount;
                })));
                if(!empty($subjectLimitFees[$resultIndex])){
                    $currentFee = new \stdclass;
                    $currentFee->feeName = "Total Subject Fee";
                    $currentFee->isSubjectFeeLimit = 0;
                    $currentFee->value = $subjectLimitFees[$resultIndex];
                    $studentDetails->totalCommonFees += $currentFee->value;
                    $studentDetails->commonFees[] = $currentFee;
                }
            }
            // ------------studdent common Fines ---------------    
            $studentDetails->commonFines = []; 
            $studentDetails->totalCommonFines = 0;
            $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
            $studentCommonFines = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFines,function($value)use($studentDetails){
                return $value->examRegistrationType == $studentDetails->examRegistrationType;
            }));
            $studentCommonFineIdsArray = array_keys((array)$studentCommonFines->fineType);
            $studentCommonFines->fineType = (array)$studentCommonFines->fineType;
            $today = date("Y-m-d H:i");
            if ( $request->considerChallanVerifyDate ) {
                $today = $studentDetails->examRegistrationPaymentProperties->challanAppliedDate? $studentDetails->examRegistrationPaymentProperties->challanAppliedDate :date("Y-m-d H:i");
            }
            // $maxEndDate = $studentDetails->examRegistrationProperties->registrationWithoutFineEndDate;
            foreach($allCommonFines as $commonFine){
                if ( in_array ( $commonFine->id, $studentCommonFineIdsArray ) ) {
                    $maxEndDate = $maxEndDate ?? $studentCommonFines->fineType[$commonFine->id]->endDate;
                    $minStartDate = $minStartDate ?? $studentCommonFines->fineType[$commonFine->id]->startDate;
                    if((strtotime($today) >= strtotime($studentCommonFines->fineType[$commonFine->id]->startDate)) && ($today <= $studentCommonFines->fineType[$commonFine->id]->endDate )){
                        $currentFine = new \stdclass;
                        $currentFine->fineName = $commonFine->name;
                        $currentFine->value = $studentCommonFines->fineType[$commonFine->id]->value;
                        $studentDetails->totalCommonFines += $currentFine->value;
                        $studentDetails->commonFines[] = $currentFine;
                        if(strtotime($studentCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($maxEndDate)){
                            $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                        }
                        if(strtotime($studentCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($minStartDate)){
                            $minStartDate = $studentCommonFines->fineType[$commonFine->id]->startDate;
                        }
                        // if($studentCommonFines->fineType[$commonFine->id]->endDate >= $maxEndDate){
                        //     $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                        // }
                    } 
                }
            }
            // ------------Studdent Subject Fees --------------- 
            $studentDetails->totalSubjectFees = 0;
            foreach($studentDetails->subjects as $subject){
                $subject->currentSubjectFeeProperties = reset(array_filter($subject->subjectFeeProperties,function($value)use($studentDetails){
                    return $value->examRegistrationType == $studentDetails->examRegistrationType;
                }));
                $subject->currentSubjectFeeProperties->feeType = (array)$subject->currentSubjectFeeProperties->feeType;
                $subject->subjectFeeTemplateIdsArray = array_keys($subject->currentSubjectFeeProperties->feeType);
                $subject->currentFeeTypeTemplateId = ExamRegistrationFeeCommonService::getInstance()->getCurrentSubjectFeeTemplateForStudent($subject,$studentDetails);
                $subject->value =  $subject->currentFeeTypeTemplateId ? $subject->currentSubjectFeeProperties->feeType[$subject->currentFeeTypeTemplateId]->value : 0;
                $studentDetails->totalSubjectFees += $subject->value;
            }
            $studentDetails->totalFeeAmount = $studentDetails->totalCommonFines + $studentDetails->totalCommonFees + $studentDetails->totalSubjectFees;
            if($studentDetails->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SEMESTER_WISE'){
                $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
                $attendanceTermWiseReportRequest->studentId = $studentDetails->studentId;
                $attendanceTermWiseReportRequest->termId = $studentDetails->academicTermId;
                $attendanceTermWiseReportRequest->attendanceClosingDate = $studentDetails->batchProperties->attendanceClosingDate;
                $studentDetails->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
                $studentDetails->isShortageAttendance  = $studentDetails->examRegistrationProperties->minimumAttendancePercentage > $studentDetails->attendanceDetails->attendancePercentage ? true : false;
            }
        }
        return($students); 
    }
      /**
     * get count of batch students
     * @param $request
     * @return $countOfStudents
     */
    public function countOfStudentsAssignedBatch($request){
        $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->examRegistrationId)){
            $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
            $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
        }
        $query = "SELECT count(distinct sa.studentID ) as `countOfStudents` 
                FROM
                    ec_exam_registration eer
                INNER JOIN ec_exam_registration_batch eerb ON
                    eerb.ec_exam_registration_id = eer.id 
                INNER JOIN `groups` g ON
                    g.id = eerb.groups_id
                    AND g.`type` = 'BATCH'
                INNER JOIN group_members gm ON
                    gm.groups_id = g.id
                INNER JOIN student_program_account spa ON 
                    spa.id  = gm.members->>'$.studentId'
                INNER JOIN student_program_batch_log spbl ON
                    spbl.batch_group_id = g.id AND
                    spbl.term_id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR) AND
                    spbl.program_student_id = spa.id AND 
                    spbl.properties->>'$.academicStatus' IN ('ACTIVE','COMPLETED')
                INNER JOIN studentaccount sa ON
                    sa.studentID = spa.student_id
                WHERE
                    eer.trashed IS NULL
                    AND eer.properties->>'$.publish' = '1' ";
        try {
            $countOfStudents = $this->executeQueryForObject($query.$whereQuery);
            $countOfStudents = $countOfStudents ? $countOfStudents->countOfStudents : 0;
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student.");
        }
        return $countOfStudents;
    }
     /**
     * get count of Registered students In Batch
     * @param $request
     * @return $countOfStudents
     */
    public function countOfRegisteredStudentsInBatch($request){
        $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->examRegistrationId)){
            $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
            $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
        }
        $query = "SELECT DISTINCT
                    count(distinct  esar.student_id ) as `countOfStudents` 
                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 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
                WHERE
                    eer.properties->>'$.publish' = '1' AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED') AND eer.type = esar.ec_exam_registration_type";
        try {
            $countOfStudents = $this->executeQueryForObject($query.$whereQuery);
            $countOfStudents = $countOfStudents ? $countOfStudents->countOfStudents : 0;
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student.");
        }
        return $countOfStudents;
    }
     /**
     * Save student Online payament Details
     * @param  $onlinePayment
     * @return String $id
     */
    public function saveStudentRegistrationOnlinePaymentStatus ($onlinePayment){
        $currentStaffId = $GLOBALS['userId'] ? $GLOBALS['userId'] : $onlinePayment->studentId;
        $onlinePayment = $this->realEscapeObject($onlinePayment);
        try{
            $this->validateSaveOnlinePaymentStatus($onlinePayment);
            if(!empty($onlinePayment->id )){
                $onlinePayment->id = $this->updateStudentOnlinePaymentStatus($onlinePayment);
            }
            else{
                $onlinePayment->id = $this->insertStudentOnlinePaymentStatus($onlinePayment);
            }
            
            $this->logger->info(Events::EC_SAVE_STUDENT_ONLINE_PAYMENT_DETAILS,[
            "staff" => new Staff(["id" => $currentStaffId]),
                "request" => $onlinePayment,
                "status" => StatusConstants::SUCCESS
            ]);
        }catch(\Exception $e) {
            $this->logger->info(Events::EC_SAVE_STUDENT_ONLINE_PAYMENT_DETAILS,[
                "staff" => new Staff(["id" => $currentStaffId]),
                "request" => $onlinePayment,
                "errorCode" => $e->getCode(),
                "errorMessage" => $e->getMessage(),
                "status" => StatusConstants::FAILED
            ]);
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        return $onlinePayment->id;
    }
     /**
     * validate Save Online Payment Status Before Saving
     * @param  $onlinePayment
     * @return NULL
     */
    private function validateSaveOnlinePaymentStatus( $onlinePayment){
        if(empty($onlinePayment->studentId))
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_STUDENT_REGISTRATION,"Student is empty! Please select student for registration"); 
        if(empty($onlinePayment->txnID) || (empty($onlinePayment->amount) && $onlinePayment->amount != 0 ) || empty($onlinePayment->type) || empty($onlinePayment->transactionDate))
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_STUDENT_REGISTRATION,"Payment Request Invaild.");
       
    }
    /**
     * Insert Student online transaction
     * @param $onlinePayment
     * @return String $id
     */
    private function insertStudentOnlinePaymentStatus($onlinePayment){
        $properties = !empty($onlinePayment->properties) ? "'".json_encode($onlinePayment->properties)."'" : "'{}'";
        $id = SecurityUtils::getRandomString();
        $query = "INSERT INTO ec_online_payment
            (studentID,txnID,`status`,amount,transactionDate,`type`,payment_gateway_txn_id,properties)
        VALUES
            ('$onlinePayment->studentId','$onlinePayment->txnID','$onlinePayment->status','$onlinePayment->amount','$onlinePayment->transactionDate','$onlinePayment->type','$onlinePayment->paymentGateWayTransactionId',$properties
            ON DUPLICATE KEY UPDATE `properties` = JSON_MERGE_PATCH(`properties`,$properties), payment_gateway_txn_id = VALUES(payment_gateway_txn_id), `status` = VALUES(`status`)";
        
        try {
            $onlinePayment->id = $this->executeQuery($query,true);
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $onlinePayment->id;
    }
     /**
     * Update Student online transaction
     * @param  $onlinePayment
     * @return NULL
     */
    private function updateStudentOnlinePaymentStatus( $onlinePayment){
        $properties = !empty($onlinePayment->properties) ? "'".json_encode($onlinePayment->properties)."'" : "'{}'";      
        $query = "UPDATE ec_online_payment 
        SET 
            studentID = '$onlinePayment->studentId',
            txnID = '$onlinePayment->txnID',
            `status` = '$onlinePayment->status',
            `amount` = '$onlinePayment->amount',
            `transactionDate` = '$onlinePayment->transactionDate',
            `type` = '$onlinePayment->type',
            `payment_gateway_txn_id` = '$onlinePayment->paymentGateWayTransactionId',
            properties = JSON_MERGE_PATCH(`properties`,$properties)
        WHERE 
            id = '$onlinePayment->id'";
        try {
            $this->executeQuery($query);
            return $onlinePayment->id;
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
    }
     /**
     * Search Online Payment Status
     * @param  $request
     * @return onlinePayment
     */
    public function searchStudentOnlinePayement($request){
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        if(!empty($request->id)) {
            $whereQuery .= " AND eop.id = '$request->id'";
        }
        if(!empty($request->studentId)) {
            $whereQuery .= " AND eop.studentID = '$request->studentId'";
        }
        if(!empty($request->examRegistrationId)) {
            $whereQuery .= " AND eop.properties->>'$.examRegistrationId' = '$request->examRegistrationId'";
        }
        if(!empty($request->txnID)) {
            $whereQuery .= " AND eop.txnID = '$request->txnID'";
        }
        $query = "SELECT
            eop.id as id,
            eop.studentID as studentId,
            eop.txnID as txnID,
            eop.status as status,
            eop.amount as amount,
            eop.transactionDate as transactionDate,
            eop.type as type,
            eop.payment_gateway_txn_id as paymentGatewayTxnId,
            eop.properties->>'$.examRegistrationId' as examRegistrationId,
            eer.name as examRegistrationName,
            eop.properties as properties
        FROM
            ec_online_payment eop
        INNER JOIN ec_exam_registration eer ON 
            eer.id = eop.properties->>'$.examRegistrationId'
        WHERE
            1 = 1 AND eop.is_active = '1' ";
        try {
            $onlinePayment = $this->executeQueryForList($query.$whereQuery);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch online paymant status details! Please try again");
        }
        return $onlinePayment;
    }
     /**
     * Delete Student online transaction
     * @param $onlinePayment
     */
    public function deleteStudentOnlinePaymentStatus($onlinePayment){
        if(!empty($onlinePayment->examRegistrationId) && !empty($onlinePayment->studentId)){
            $query = "UPDATE ec_online_payment 
                        SET 
                            is_active = '0'
                        WHERE 
                            properties->>'$.examRegistrationId' = '$onlinePayment->examRegistrationId' AND 
                            studentID = '$onlinePayment->studentId'";
                        
            try {
                $this->executeQuery($query);
            } catch (\Exception $e) {
                throw new ExamControllerException($e->getCode(),$e->getMessage());
            }
        }
    }
    /**
     * Get Student Exam Fee Receipt
     * @param $request
     */
    public function  getStudentExamFeeReceipt($request){
        $examType = 'EC_EXAM_FEE_RECIPT_TEMPLATE';
        $feeReceiptTemplate = StudentMarkListService::getInstance()->getUniversityMarkListTemplate($examType);
        $feeReceiptConstantValue = "";
        $searchExamRuleRequest = new SearchRuleRequest;
        $searchExamRuleRequest->name = 'EXAM_REGISTRATION_CREATION_RULE';
        $ruleObj = reset(RuleService::getInstance()->searchRule($searchExamRuleRequest));
        if($ruleObj){
            $feeReceiptConstantValue = $ruleObj->rule->feeReceiptConstantValue ?? "";
        }
        $searchRequest = new \stdClass();
        $searchRequest->studentId = $request->studentId;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->registrationStatus = $request->isAppliedSubjectsOnly == '1' ? StudentExamRegistrationStatus::APPLIED : StudentExamRegistrationStatus::REGISTERED;
        
        $requestForExamRegistration = new SearchExamRegistrationRequest;
        $requestForExamRegistration->id = $request->examRegistrationId;
        $examRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration));
        $searchRequest->examType = $examRegistration->type;
        
        $studentDetails = reset($this->getStudentExamRegistrationFeeDetails($searchRequest));
        $studentDetails = $this->setStudentAdditonalProfileDetails($studentDetails);
        $studentDetails->birthday = $studentDetails->birthday ?  date("d-m-Y", strtotime( $studentDetails->birthday)) : "";
        if($feeReceiptConstantValue){
            $studentDetails->feeReceiptNo = $feeReceiptConstantValue."" .date("Y"). "EX " .str_pad($studentDetails->examRegistrationPaymentUniqueNo, 5, '0', STR_PAD_LEFT);
        }
        $studentDetails->dateofPay = "";
        $studentDetails->paymentMethod = "Back end Method";
        if($studentDetails->examRegistrationPaymentProperties->paymentOption =="ONLINE_PAYMENT_METHOD"){
            $studentDetails->paymentMethod = "Online Method";
            $studentDetails->linwaysTxnId = $studentDetails->examRegistrationPaymentProperties->clientTxnId;
            $studentDetails->transactionDate =  date("d-m-Y h:i A", strtotime( $studentDetails->examRegistrationPaymentProperties->onlinePaymentTransactionDate));
        }
        else if ($studentDetails->examRegistrationPaymentProperties->paymentOption =="COLLEGE_CHALLAN_METHOD"){
            $studentDetails->paymentMethod = "College Challan";
            $studentDetails->transactionDate = $studentDetails->examRegistrationPaymentProperties->challanVerifyDate ? date("d-m-Y h:i A", strtotime( $studentDetails->examRegistrationPaymentProperties->challanVerifyDate)) : "";
        }
        $studentDetails->examRegistrationPaidAmountInWords = ucwords(CommonUtil::convertNumberToWords(round($studentDetails->examRegistrationPaidAmount)));
        $studentDetails->studentImage  = StudentService::getInstance()->getStudentProfilePic($studentDetails->id)->docpath;
        $studentDetails->studentSignature  = StudentService::getInstance()->getStudentSignPic($studentDetails->id)->docpath;
        $studentDetails->today =  date("d-m-Y");
        $studentDetails->examMonthName = ExamRegistrationService::getInstance()->getMonthName($studentDetails->examRegistrationProperties->examMonth);
        $studentDetails->examYear = $studentDetails->examRegistrationProperties->examYear;
        $studentDetails->isAppliedSubjectsOnly = $request->isAppliedSubjectsOnly == '1' ? true : false;
        $collegeData = CommonExamService::getInstance()->getCollegeDetails();
        if($feeReceiptTemplate == 'Template_16'){
            $templateName = "ExamFeeReceiptTemplate16";
        }
        else if($feeReceiptTemplate == 'Template_13'){
            $templateName = "ExamFeeReceiptTemplate13";
        }
        else if($feeReceiptTemplate == 'Template_20'){
            $templateName = "ExamFeeReceiptTemplate20";
        }
        else if($feeReceiptTemplate == 'Template_2'){
            $templateName = "ExamFeeReceiptTemplate2";
        }
        else if($feeReceiptTemplate == 'Template_3'){
            $templateName = "ExamFeeReceiptTemplate3";
            $pageSize = $this->setPageSize(297,210);
        }
        else if($feeReceiptTemplate == 'Template_22'){
            $templateName = "ExamFeeReceiptTemplate22";
        }
        else if($feeReceiptTemplate == 'Template_28'){
            $templateName = "ExamFeeReceiptTemplate28";
            $marginBottom = 2;
            $marginTop = 2;
        }
        else{
            $templateName = "ExamFeeReceiptTemplate1";
        }
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/ExamFeeReceipt/$templateName.twig"), [ 'data'=>$studentDetails,'college'=>$collegeData ]);
        $prtContent = NULL;
        $prtContent .= '<html><head>';
        $prtContent .= "<style>
            
            </style>";
        $prtContent .= '</head><title>Exam Fee Receipt </title><body>';
        $prtContent .= $responseHtml;
        $prtContent .= '</body></html>';
        $totalWidth = $pageSize->width ? $pageSize->width : 210;
        $totalHeight = $pageSize->height ? $pageSize->height : 297;
        $marginTop = $marginTop ? $marginTop : 9;
        $marginBottom = $marginBottom ? $marginBottom : 9;
        $options = array(
            'page-width'     => $totalWidth."mm",
            'page-height'    => $totalHeight."mm",
            'dpi'            => 96,
            'margin-top' => $marginTop."mm",
            'margin-left' => "10mm",
            'margin-right' => "10mm",
            'margin-bottom' => $marginBottom."mm",
            // '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 Parent Revaluation Student Details
     * @param $request
     * @return studentDetails
     */
    public function getParentRevaluationRegistredStudentDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            $whereQuery = "";
            $limitQuery = "";
            $joinQueary = "";
            $selectColumns = "";
            $students = [];
            
            $sortBy = " ";
            if(!empty($request->examRegistrationId)){
                $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            if(!empty($request->studentId)){
                $studentIdString = is_array($request->studentId) ? "'" . implode("','",$request->studentId) . "'" : "'".$request->studentId."'";
                $whereQuery .= " AND spa.student_id IN ( $studentIdString )";
            }
            $query = "SELECT 
                    DISTINCT sa.studentID as studentId,
                    sa.studentName as studentName,
                    spa.properties->>'$.registerNumber' AS registerNo,
                    eer.id AS examRevaluationId,
                    eer.name AS examRevaluationName,
                    eer.properties AS examRevaluationProperties,
                    eer.type AS examRevaluationType,
                    eerParent.name AS parentExamRegistrationName,
                    eerParent.type AS parentExamRegistrationType,
                    eerParent.properties AS parentExamRegistrationProperties,
                    eerb.properties AS examRevaluationBatchProperties,
                    eserd.balance_amount_details AS balanceAmountDetails,
                    eserd.properties AS examRegistrationPaymentProperties,
                    eserd.properties->>'$.isResultWithHeld' AS isResultWithHeld,
                    g.id AS groupId,
                    g.name AS groupName,
                    eersParent.am_assessment_id as assessmentId,
                    caps.id AS academicPaperSubjectId,
                    IF(caps.properties ->> '$.classType' = 'PRACTICAL',1,0) AS isPractical,
                    esar.id AS studentAssessmentRegistrationId,
                    s.code AS subjectCode,
                    caps.properties ->> '$.syllabusName' AS syllabusName,
                    s.name AS subjectName,
                    esar.properties as studentAssessmentRegistrationProperties,
                    esar.identifying_context as studentAssessmentRegistrationIdentifyingContext,
                    esar.revaluationType as studentRevaluationType,
                    esar.properties ->> '$.registrationStatus' as studentRegistrationStatus,
                    esar.properties ->> '$.feeStatus' as studentFeeStatus,
                    esar.properties ->> '$.paymentOption' as studentRegistrationPaymentOption
                FROM
                    ec_exam_registration eer
                INNER JOIN ec_exam_registration_batch eerb ON
                    eerb.ec_exam_registration_id = eer.id 
                INNER JOIN ec_exam_registration eerParent ON
                    eerParent.id = eer.properties->>'$.parentExamRegistrationId' AND 
                    eerParent.trashed IS NULL
                INNER JOIN ec_exam_registration_batch eerbParent ON
                    eerbParent.ec_exam_registration_id = eerParent.id  AND 
                    eerb.groups_id = eerbParent.groups_id
                INNER JOIN ec_exam_registration_subject eersParent ON     
                    eersParent.ec_exam_registration_batch_id = eerbParent.id 
                INNER JOIN cm_academic_paper_subjects caps ON
                    caps.id = eersParent.cm_academic_paper_subjects_id AND caps.properties->>'$.isExternal' = '1'
                INNER JOIN v4_ams_subject s ON
                    s.id = caps.ams_subject_id
                INNER JOIN `groups` g ON
                    g.id = eerb.groups_id
                    AND g.`type` = 'BATCH'
                INNER JOIN `groups` sg ON
                    sg.paperSubjectId = caps.id AND
                    sg.type = 'SUBJECT'
                INNER JOIN group_members sgm ON
                    sgm.groups_id = sg.id AND 
                    sgm.academic_status IN ('ACTIVE') 
                INNER JOIN program p ON 
                    p.id = g.properties->>'$.programId'
                INNER JOIN student_program_account spa ON 
                    spa.id  = sgm.members->>'$.studentId' AND
                    spa.current_program_id = p.id AND 
                    spa.properties->>'$.academicStatus' IN ('ACTIVE','COMPLETED')
                INNER JOIN studentaccount sa ON
                    sa.studentID = spa.student_id
                INNER JOIN ec_student_exam_registration_details eserd ON
                    eserd.student_id = sa.studentID AND 
                    eserd.ec_exam_registration_id = eer.id 
                INNER JOIN ec_student_assessment_registration esar ON 
                    esar.student_id = sa.studentID AND 
                    esar.am_assessment_id = eersParent.am_assessment_id AND 
                    esar.ec_exam_registration_type = eer.type AND 
                    esar.identifying_context->>'$.examRegistrationId' = eer.id
               
                WHERE eer.type = 'REVALUATION' AND eer.trashed IS NULL AND eer.properties->>'$.publish' = 1 AND (esar.id IS NULL OR esar.properties ->> '$.registrationStatus' IN ( 'REGISTERED'))";
            $studentDetails = $this->executeQueryForList($query.$whereQuery.$sortBy.$limitQuery);
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        foreach($studentDetails as $student){
            $students[$student->studentId]->studentId = $student->studentId;
            $students[$student->studentId]->name = $student->studentName;
            $students[$student->studentId]->registerNo = $student->registerNo;
            $students[$student->studentId]->subjects[$student->subjectCode]->code = $student->subjectCode;
            $students[$student->studentId]->subjects[$student->subjectCode]->name = $student->subjectName;
            $students[$student->studentId]->subjects[$student->subjectCode]->assessmentId = $student->assessmentId;
            $students[$student->studentId]->subjects[$student->subjectCode]->exams[$student->examRevaluationId]->id = $student->examRevaluationId;
            $students[$student->studentId]->subjects[$student->subjectCode]->exams[$student->examRevaluationId]->name = $student->examRevaluationName;
            $students[$student->studentId]->subjects[$student->subjectCode]->exams[$student->examRevaluationId]->examRevaluationName = $student->examRevaluationName;
            $students[$student->studentId]->subjects[$student->subjectCode]->exams[$student->examRevaluationId]->examRevaluationProperties = json_decode($student->examRevaluationProperties);
            $students[$student->studentId]->subjects[$student->subjectCode]->exams[$student->examRevaluationId]->parentExamRegistrationName = $student->parentExamRegistrationName;
            $students[$student->studentId]->subjects[$student->subjectCode]->exams[$student->examRevaluationId]->examRevaluationBatchProperties = json_decode($student->examRevaluationBatchProperties);
            $students[$student->studentId]->subjects[$student->subjectCode]->exams[$student->examRevaluationId]->examRevaluationBatchProperties = json_decode($student->examRevaluationBatchProperties);
            
        }
        return $students;
    }
     /**
     * Search packet students
     * @param $request
     * @return $students
     */
    public function searchPacketStudentsRevaluation($request){
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        $mapperRequest = StudentExamRegistrationServiceMapper::SEARCH_ASSESSMENT_STUDENTS;
        if(!empty($request->assessmentId)) {
            $assessmentIdString = is_array($request->assessmentId) ? "'" . implode("','",$request->assessmentId) . "'" : "'".$request->assessmentId."'";
            $whereQuery .= " AND aa.id IN ($assessmentIdString";
        }
        if(!empty($request->groupId)) {
            $whereQuery .= " AND aa.identifying_context->>'$.groupId' = '$request->groupId'";
        }
        if(!empty($request->examRegistrationId)) {
            $whereQuery .= " AND eer.id = '$request->examRegistrationId'";
        }
        if(!empty($request->paperSubjectId)) {
            $whereQuery .= " AND eers.cm_academic_paper_subjects_id = '$request->paperSubjectId'";
        }
        if(!empty($request->packetNo)) {
            $whereQuery .= " AND esar.valuation_details->>'$.packetNo' = '$request->packetNo'";
            $mapperRequest = StudentExamRegistrationServiceMapper::STUDENTS_WITH_PACKET_DETAILS;
        }
        elseif ($request->packetUnAssignedStudents) {
            $whereQuery .= " AND (esar.valuation_details->>'$.packetNo' IS NULL OR esar.valuation_details->>'$.packetNo'='')";
            $mapperRequest = StudentExamRegistrationServiceMapper::STUDENTS_WITH_PACKET_DETAILS;
        }
        $query = "SELECT
            esar.id,
            sa.studentName,
            spa.properties->>'$.registerNumber' AS regNo,
            sa.studentID,
            esar.am_assessment_id,
            esarParent.properties,
            IF (esar.valuation_details IS NULL, JSON_OBJECT(), esar.valuation_details) AS valuation_details,
            IF (esar.valuation_order_details IS NULL, JSON_OBJECT(), esar.valuation_order_details) AS valuation_order_details,
            IF (esar.valuation_order_details IS NULL, 0, 1) AS isDisabledEdit,
            esar.trashed,
            FALSE AS edit,
            caps.id AS paperSubjectId,
            s.code AS subjectCode,
            s.name AS subjectName
        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.identifying_context ->> '$.assessmentId' = 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 eerp ON
                eerp.id = eerb.ec_exam_registration_id AND
                eerp.trashed IS NULL
            INNER JOIN ec_exam_registration eer ON
                eer.properties->>'$.parentExamRegistrationId' = eerp.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 s ON
                s.id = caps.ams_subject_id
            LEFT JOIN ec_student_assessment_registration esarParent ON
                esar.student_id = esarParent.student_id AND 
                esar.am_assessment_id = esarParent.am_assessment_id AND
                eerp.type = esarParent.ec_exam_registration_type
            WHERE
                esar.trashed IS NULL AND esar.identifying_context->>'$.examRegistrationId' = eer.id AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED') AND eer.type = esar.ec_exam_registration_type ";
        try {
            $students = $this->executeQueryForList($query.$whereQuery.$limitQuery, $this->mapper[$mapperRequest]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_STUDENT_REGISTRATION,"Cannot fetch exams! Please try again");
        }
        array_walk($students, function($student) {
            $student->error = "";});
        return $students;
    }
    /**
     * Get Student College Challan Revaluation
     * @param $request
     */
    public function  getStudentCollegeChallanTemplateRevaluation($request){
        $searchRequest = new \stdClass();
        $searchRequest->studentId = $request->studentId;
        $studentCommonFeesIdsArray = [];
        $studentCommonFineIdsArray = [];
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $subjects = $request->subjects;
        $studentDetails =  reset($this->getStudentRevaluationDetails($searchRequest));
        $studentDetails->examRegType = ucfirst(strtolower($studentDetails->examRevaluationType));
        
        
          // ------------Studdent common Fees & Fines --------------- 
        if(count($studentDetails->batchFeeFine) > 1){
            $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
        }
        else{
            $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
        }
        // ------------studdent common Fees --------------- 
        $studentDetails->commonFees = [];   
        $studentDetails->totalCommonFees = 0;  
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REVALUATION';
        
        $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRevaluationType;
        }));
        $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
        $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
        foreach($allCommonFees as $commonFee){
            if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                if($commonFee->isCommon ){
                    $currentFee = new \stdclass;
                    $currentFee->name = $commonFee->name;
                    $currentFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                    $studentDetails->totalCommonFees += $currentFee->value;
                    $studentDetails->commonFees[] = $currentFee;
                    $studentDetails->allFees[] = $currentFee;
                } 
                else{
                    $revaluationFee = new \stdclass;
                    $revaluationFee->id = $commonFee->id;
                    $revaluationFee->feeName = $commonFee->name;
                    $revaluationFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                    $studentDetails->revaluationFee[] = $revaluationFee;
                }
            }
        }
        array_walk($studentDetails->subjects,function($subject,$key) use($studentDetails){
            $subject->feeValue = 0;
            $subject->isSelected = false;
            $subject->revaluationTypes = [];
            $subject->currentPaymentMethod = "";
            $subject->isTobeRegistered = false;
            $subject->studentRevaluationRegistration = [];
            foreach($studentDetails->revaluationFee as $revaluationFee){
                $revaluationRegistrationDetails = new \stdClass;
                $revaluationRegistrationDetails->revaluationId = $revaluationFee->id;
                $revaluationRegistrationDetails->registrationStatus = "";
                $subject->revaluationRegistrationStatus[$revaluationFee->id] = $revaluationRegistrationDetails;
            }
            if(!empty($subject->studentAssessmentRegistrations)){
                foreach($subject->studentAssessmentRegistrations as $studentAssessmentRegistration){
                    $studentAssessmentRegistration->isAlreadyRegistered = false;
                    $subject->revaluationRegistrationStatus[$studentAssessmentRegistration->studentRevaluationType]->registrationStatus = $studentAssessmentRegistration->studentRegistrationStatus;
                    if($studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::REGISTERED || $studentAssessmentRegistration->studentRegistrationStatus == StudentExamRegistrationStatus::APPLIED){
                        $subject->revaluationTypes[] = $studentAssessmentRegistration->studentRevaluationType;
                        foreach($studentDetails->revaluationFee as $revaluationFee){
                            if($revaluationFee->id == $studentAssessmentRegistration->studentRevaluationType){
                                $subject->feeValue += (int)$revaluationFee->value;
                                $studentDetails->paidAmount += (int)$revaluationFee->value;
                                $subject->isSelected = true;
                            }
                        }
                    }
                }
                $studentDetails->totalSubjectFees += $subject->feeValue;
            }
        });
        $currentFine = new \stdclass;
        $currentFine->name = "Total Paper Fees";
        $currentFine->value = $studentDetails->totalSubjectFees;
        $studentDetails->allFees[] = $currentFine;
         // ------------studdent common Fines ---------------    
         $today = date("Y-m-d H:i");
         if ( $request->previewType == 'PRINT_COPY' ) {
            $today = $studentDetails->examRegistrationPaymentProperties->challanAppliedDate? $studentDetails->examRegistrationPaymentProperties->challanAppliedDate :date("Y-m-d H:i");
         }
         $verificationDate = $studentDetails->examRevaluationBatchProperties->registrationValuationDate;
         $studentDetails->verificationDate = $verificationDate;
         $studentDetails->totalFeeAmount = $studentDetails->totalCommonFees + $studentDetails->totalSubjectFees;
         $studentDetails->currentDate = date('d-m-Y');
         $studentDetails->totalFeeAmountInWords = CommonUtil::convertNumberToWords( $studentDetails->totalFeeAmount );
         $studentDetails->challanNo = $studentDetails->examRegistrationPaymentProperties->challanNo;
         $barcodeObj = new TCPDFBarcode( $studentDetails->challanNo , 'C128');
         $studentDetails->barcodeObj = $barcodeObj->getBarcodeHTML($w = 1, $h = 40, $color = 'black');
        global $COLLEGE_NAME, $autonomous, $PLACE;
        $studentDetails->collegeName =  $COLLEGE_NAME;
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/CollegeChallanTemplate/CollegeChallanRevaluationDefault.twig"), [ 'data'=>$studentDetails ]);
        // $responseHtml = "ASDADA";
        $prtContent = NULL;
        $prtContent .= '<html><head>';
        $prtContent .= "<style>
            
            </style>";
        $prtContent .= '</head><title>College Challan </title><body>';
        $prtContent .= $responseHtml;
        $prtContent .= '</body></html>';
        $totalWidth = 310;
        $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 Student Exam Fee Receipt
     * @param $request
     */
    public function  getStudentRevaluationExamFeeReceipt($request){
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REVALUATION';
        $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $revaluationFees = array_filter($allCommonFees, function($commonFee) {
            return !$commonFee->isCommon;
        });
        $revaluationFees = array_column($revaluationFees, null, 'id');
        $searchRequest = new \stdClass();
        $searchRequest->studentId = $request->studentId;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->registrationStatus = ['REGISTERED'];
        $studentDetails = reset($this->getStudentRevaluationDetails($searchRequest));
        foreach($studentDetails->subjects as $subject){
            foreach($subject->studentAssessmentRegistrations as $studentAssessmentRegistration){
                if($studentAssessmentRegistration->studentRevaluationType){
                    $studentAssessmentRegistration->revaluationName = $revaluationFees[$studentAssessmentRegistration->studentRevaluationType]->name;
                }
            }
        }
        $studentDetails->birthday = $studentDetails->birthday ?  date("d-m-Y", strtotime( $studentDetails->birthday)) : "";
        $studentDetails->dateofPay = "";
        $studentDetails->paymentMethod = "Back end Method";
        if($studentDetails->examRegistrationPaymentProperties->paymentOption =="ONLINE_PAYMENT_METHOD"){
            $studentDetails->paymentMethod = "Online Method";
            $studentDetails->transactionDate =  date("d-m-Y h:i A", strtotime( $studentDetails->examRegistrationPaymentProperties->onlinePaymentTransactionDate));
        }
        else if ($studentDetails->examRegistrationPaymentProperties->paymentOption =="COLLEGE_CHALLAN_METHOD"){
            $studentDetails->paymentMethod = "College Challan";
            $studentDetails->transactionDate = $studentDetails->examRegistrationPaymentProperties->challanVerifyDate ? date("d-m-Y h:i A", strtotime( $studentDetails->examRegistrationPaymentProperties->challanVerifyDate)) : "";
        }
        $studentDetails->studentImage  = StudentService::getInstance()->getStudentProfilePic($studentDetails->id)->docpath;
        $studentDetails->studentSignature  = StudentService::getInstance()->getStudentSignPic($studentDetails->id)->docpath;
        $studentDetails->today =  date("d-m-Y");
        
        $collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $data = "";
        $templateName = "ExamRevaluationFeeReceiptTemplate1";
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/ExamFeeReceipt/$templateName.twig"), [ 'data'=>$studentDetails,'college'=>$collegeData ]);
        $prtContent = NULL;
        $prtContent .= '<html><head>';
        $prtContent .= "<style>
            
            </style>";
        $prtContent .= '</head><title>Exam Fee Receipt </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' => "10mm",
            'margin-right' => "10mm",
            '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;
       
    }
    
     /**
     * search All Student Details By Special ExamRegistration
     * @param $request
     * @return studentDetails
     */
    public function searchAllStudentDetailsBySpecialExamRegistration($request){
        try{
            $responseData = new \stdClass;
            $request->limitStart = $request->limitStart ? (int)$request->limitStart : 0;
            if($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED){
                $request->registrationStatus = StudentExamRegistrationStatus::REGISTERED;
            }
            else if($request->registrationStatus == StudentExamRegistrationStatus::APPLIED){
                $request->registrationStatus = StudentExamRegistrationStatus::APPLIED;
            }
            $requestForExamRegistration = new SearchExamRegistrationRequest;
            $requestForExamRegistration->id = $request->examRegistrationId;
            $examRegistration = reset(ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration));
            if($examRegistration->type == ExamRegistrationTypeConstants::SUPPLEMENTARY){
                $request->examType = ExamRegistrationTypeConstants::SUPPLEMENTARY;
            }
            $studentDetails = $this->getAllStudentDetailsBySpecialExamRegistration($request);
            $studentDetails = (array)$studentDetails;
            array_walk($studentDetails, function($student,$key) {
                $student->modeOfTransaction = "Back end Method";
                $student->modeOfTransactionId =  '-';
                if($student->registrationProperties->paymentOption =="ONLINE_PAYMENT_METHOD"){
                    $student->modeOfTransaction = "Online Method";
                    $student->modeOfTransactionId =  $student->registrationProperties->onlinePaymentTransactionId;
                    $student->transactionDate =  date("d-m-Y h:i A", strtotime( $student->registrationProperties->onlinePaymentTransactionDate));
                }
                else if ($student->registrationProperties->paymentOption =="COLLEGE_CHALLAN_METHOD"){
                    $student->modeOfTransaction = "College Challan";
                    $student->modeOfTransactionId = $student->challanNo;
                    $student->transactionDate = $student->challanVerifyDate ? date("d-m-Y h:i A", strtotime( $student->challanVerifyDate)) : "";
                }
                $student->challanVerifyDate = $student->challanVerifyDate ? date("d-m-Y h:i A", strtotime( $student->challanVerifyDate)) : "";
                $student->isExpand = false;
            });
            if(!empty($studentDetails)){
                if(reset($studentDetails)->isPubishExamRegistration != '1'){
                    throw new ExamControllerException (ExamControllerException::EXAM_REGISTRATION_NOT_PUBLISHED,"Exam Registration Not Published.");
                }
            }
            $responseData->totalStudentCount = count($studentDetails);
            ksort($studentDetails);
            if (isset($request->offset) && $request->offset>=0){
                if (isset($request->limitStart) && $request->limitStart>=0) {
                    $studentDetails = array_slice($studentDetails,(int)$request->limitStart,(int)$request->offset);
                }
                else{
                    $studentDetails = array_slice($studentDetails,0,(int)$request->offset);
                }
            }
            $responseData->studentDetails = $studentDetails;
            return $responseData;
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
    }
    
    /**
     * get All Student Details By ExamRegistration
     * @param $request
     * @return studentDetails
     */
    public function getAllStudentDetailsBySpecialExamRegistration($request){
        try{
            $request = $this->realEscapeObject($request);
            $whereQuery = "";
            $limitQuery = "";
            $joinQueary = "";
            $selectColumns = "";
            $sortBy = " ORDER BY spa.properties->>'$.registerNumber' ASC ,s.name ASC ";
            $joinQueary .= " INNER JOIN ec_student_assessment_registration esar ON
                            esar.am_assessment_id = eers.am_assessment_id AND esar.ec_exam_registration_type = eer.type AND esar.properties ->> '$.isSpecialExamAssigned' = '1'";
            if(!empty($request->examRegistrationId)){
                $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            if(!empty($request->registrationStatus)){
                if($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::APPLIED){
                    $joinQueary .= " INNER JOIN ec_student_exam_registration_details eserd ON
                        eserd.ec_exam_registration_id = eer.id";
                    $selectColumns .= ",eserd.properties as registrationProperties,eserd.total_fee as totalFee,eserd.properties ->> '$.challanNo' as challanNo,eserd.properties ->> '$.challanVerifyDate' as challanVerifyDate";
                    $whereQuery .= $request->registrationStatus == StudentExamRegistrationStatus::REGISTERED ? " AND esar.properties ->> '$.registrationStatus' = 'REGISTERED' AND esar.properties ->> '$.feeStatus' = 'PAID'" : " AND esar.properties ->> '$.registrationStatus' = 'APPLIED'";
                }
                else if($request->registrationStatus == StudentExamRegistrationStatus::NOT_REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::NOT_APPLIED ){
                    $whereQuery .= " AND esar.properties ->> '$.registrationStatus' = 'NOT_REGISTERED' ";
                }
            }
            if(!empty($request->registerNo)){
                $whereQuery .= " AND spa.properties->>'$.registerNumber' = '$request->registerNo'";
            }
            if(!empty($request->groupId)){
                $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if(!empty($request->academicTermId)){
                $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
                $whereQuery .= " AND eerb.properties ->> '$.academicTermId' IN ( $academicTermIdString )";
            }
            if(!empty($request->departmentId)){
                $departmentIdString = is_array($request->departmentId) ? "'" . implode("','",$request->departmentId) . "'" : "'".$request->departmentId."'";
                $whereQuery .= " AND g.properties ->> '$.departmentId' IN ( $departmentIdString )";
            }
            $query = "SELECT DISTINCT
                sa.studentID as studentId,
                sa.studentName,
                sa.studentEmail,
                sa.studentPhone,
                spa.properties->>'$.registerNumber' AS registerNo,
                sa.reservationID,
                eer.id as examRegistrationId,
                eer.name as examRegistrationName,
                eer.properties->>'$.description' as examRegistrationDescription,
                eer.type as examRegistrationType,
                eer.properties as examRegistrationProperties,
                eerb.groups_id as groupId,
                eer.properties->>'$.publish' as isPubishExamRegistration,
                eerb.properties ->> '$.academicTermId' as academicTermId,
                eerb.properties AS batchProperties,
                eerb.fees_properties as batchFeeProperties,
                g.name AS groupName,
                d.deptName as deptCode,
                d.departmentDesc as deptName,
                eeft.id as batchFeeTemplateId,
                eeft.fee_properties as batchCommonFees,
                eeft.fine_properties as batchCommonFines,
                IF (eeft.operation_properties  IS NULL,0,1) as isConsiderOperation,
                eeft.operation_properties as batchOperationProperties,
                eers.fees_properties as subjectFeeProperties,
                eers.am_assessment_id as assessmentId,
                caps.id AS academicPaperSubjectId,
                esar.id AS studentAssessmentRegistrationId,
                esar.properties as studentAssessmentRegistrationProperties,
                esar.properties ->> '$.registrationStatus' as studentRegistrationStatus,
                esar.properties ->> '$.paymentOption' as studentRegistrationPaymentOption,
                s.code AS subjectCode,
                caps.properties ->> '$.syllabusName' AS syllabusName,
                s.name AS subjectName
                $selectColumns
            FROM
                ec_exam_registration eer
            INNER JOIN ec_exam_registration_batch eerb ON
                eerb.ec_exam_registration_id = eer.id 
            INNER JOIN `groups` g ON
                g.id = eerb.groups_id
                AND g.`type` = 'BATCH' 
            INNER JOIN department d ON
                d.deptID = g.properties ->> '$.departmentId'
            INNER JOIN ec_examregistration_fee_templates_mapping eeftm ON
                eeftm.id = eerb.fees_properties->>'$.feeTemplateId'
            INNER JOIN ec_examregistration_fee_templates eeft ON
                eeft.ec_examregistration_fee_templates_mapping_id = eeftm.id
            INNER JOIN ec_exam_registration_subject eers ON
                eers.ec_exam_registration_batch_id = eerb.id
            INNER JOIN cm_academic_paper_subjects caps ON
                caps.id = eers.cm_academic_paper_subjects_id
            INNER JOIN v4_ams_subject s ON
                s.id = caps.ams_subject_id
            $joinQueary 
            INNER JOIN student_program_account spa ON 
                spa.id  =  esar.student_id 
            INNER JOIN studentaccount sa ON
                sa.studentID = spa.student_id
            WHERE
                eer.trashed IS NULL ";
            $studentDetails = $this->executeQueryForList($query.$whereQuery.$sortBy.$limitQuery, $this->mapper[StudentExamRegistrationServiceMapper::SEARCH_STUDENT_EXAM_REGISTRATION_FEE_DETAILS]);
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        return $studentDetails;
    }
    /**
     * Search stduent Special Exam Registration
     * @param $request
     * @return examRegistration
     */
    public function getStudentSpecialExamRegistrationSubjectFeeDetails($request){
        $searchRuleRequest = new SearchRuleRequest;
        $searchRuleRequest->name = 'STUDENT_SUPPLY_REGISTRATION_RULE';
        $ruleObj = reset(RuleService::getInstance()->searchRule($searchRuleRequest));
        if($ruleObj){
            $disableSubjectSelection = $ruleObj->rule->disableSubjectSelection == '1' ? true : false;
        }
        $searchRequest = new \stdClass;
        $searchRequest->studentId = $request->studentId;
        $studentCommonFeesIdsArray = [];
        $studentCommonFineIdsArray = [];
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->academicPaperSubjectId = $request->academicPaperSubjectId;
        $searchRequest->registrationStatus =  $request->registrationStatus;
        $searchRequest->notConsiderEmptyValidation =  $request->notConsiderEmptyValidation;
        $searchRequest->examType = ExamRegistrationTypeConstants::SUPPLEMENTARY;
        $studentDetails = reset($this->getStudentSpecialExamRegistrationFeeDetails($searchRequest));
        foreach($studentDetails->examRegistrationProperties->paymentMethods as $paymentMethod){
            if($paymentMethod == ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD;
                $currentPaymentMethod->name = "College Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::BANK_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::BANK_CHALLAN_METHOD;
                $currentPaymentMethod->name = "Bank Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD;
                $currentPaymentMethod->name = "Online Payment Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
        }
        // if ($request->isStudentSideRequest){
        //     $studentRegisterStatus = reset(array_filter($studentDetails->subjects,function($value){
        //         if($value->studentAssessmentRegistrationProperties->registrationStatus == "APPLIED" || $value->studentAssessmentRegistrationProperties->registrationStatus == "REGISTERED")
        //         return $value;
        //     }));
        //     if($studentRegisterStatus){
        //         throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,"Payment already initiated.");
        //     }
        // }
        $studentDetails->totalFeeAmount = 0;
         // ------------Studdent common Fees & Fines --------------- 
        if(count($studentDetails->batchFeeFine) > 1){
            $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
        }
        else{
            $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
        }
        $subjectCount = count($request->academicPaperSubjectId);
        // ------------studdent common Fees --------------- 
        $studentDetails->commonFees = [];   
        $studentDetails->totalCommonFees = 0;  
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REGULAR';
        $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRegistrationType;
        }));
        $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
        $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
        $subjectLimitFees = [];
        $subjectLimitCounts = [];
        foreach($allCommonFees as $commonFee){
            if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                if($commonFee->isCommon  && $commonFee->considerFeeSelectionSubject != '1'){
                    if($studentCommonFees->feeType[$commonFee->id]->value){
                        $currentFee = new \stdclass;
                        $currentFee->feeName = $commonFee->name;
                        $currentFee->isSubjectFeeLimit = $commonFee->isSubject_fee_limit;
                        $currentFee->value = $currentFee->isSubjectFeeLimit ? 0 : $studentCommonFees->feeType[$commonFee->id]->value;
                        $currentFee->currentValue = $studentCommonFees->feeType[$commonFee->id]->value;
                        $currentFee->maxValue = $currentFee->isSubjectFeeLimit ? $studentCommonFees->feeType[$commonFee->id]->maxValue : 0;
                        if($currentFee->isSubjectFeeLimit && $subjectCount > 0 && $request->featchAllFees){
                            $currentFee->value = $currentFee->currentValue * $subjectCount;
                            if($currentFee->value > $currentFee->maxValue){
                                $currentFee->value = $currentFee->maxValue;
                            }
                        }
                        $studentDetails->totalCommonFees += $currentFee->value;
                        $studentDetails->commonFees[] = $currentFee;
                    }
                } 
                else if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject == '1'){
                    if($disableSubjectSelection){
                        if($commonFee->feeSelectionSubjectLimit && $studentCommonFees->feeType[$commonFee->id]->value){
                            $subjectLimitFees[$commonFee->feeSelectionSubjectLimit] =  $studentCommonFees->feeType[$commonFee->id]->value;
                            $subjectLimitCounts[$commonFee->feeSelectionSubjectLimit] = $commonFee->feeSelectionSubjectLimit;
                            
                        }
                    }
                } 
            }
        }
        if(!empty($subjectLimitFees)){
            $subjectCount = count($studentDetails->subjects);
            sort($subjectLimitCounts);
            $index = array_search($subjectCount, $subjectLimitCounts);
            $resultIndex = ($index !== false && $subjectLimitCounts[$index] == $subjectCount) ? $subjectLimitCounts[$index] : (empty($subjectLimitCounts) ? null : max(array_filter($subjectLimitCounts, function($value) use ($subjectCount) {
                return $value <= $subjectCount;
            })));
            if(!empty($subjectLimitFees[$resultIndex])){
                $currentFee = new \stdclass;
                $currentFee->feeName = "Total Subject Fee";
                $currentFee->isSubjectFeeLimit = 0;
                $currentFee->value = $subjectLimitFees[$resultIndex];
                $studentDetails->totalCommonFees += $currentFee->value;
                $studentDetails->commonFees[] = $currentFee;
            }
        }
        // ------------studdent common Fines ---------------    
        $studentDetails->commonFines = []; 
        $studentDetails->totalCommonFines = 0;
        $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
        $studentCommonFines = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFines,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRegistrationType;
        }));
        $studentCommonFineIdsArray = array_keys((array)$studentCommonFines->fineType);
        $studentCommonFines->fineType = (array)$studentCommonFines->fineType;
        $today = date("Y-m-d H:i");
        if ( $request->considerChallanVerifyDate ) {
            $today = $studentDetails->examRegistrationPaymentProperties->challanAppliedDate? $studentDetails->examRegistrationPaymentProperties->challanAppliedDate :date("Y-m-d H:i");
        }
        // $maxEndDate = $studentDetails->examRegistrationProperties->registrationWithoutFineEndDate;
        foreach($allCommonFines as $commonFine){
            if ( in_array ( $commonFine->id, $studentCommonFineIdsArray ) ) {
                $maxEndDate = $maxEndDate ?? $studentCommonFines->fineType[$commonFine->id]->endDate;
                $minStartDate = $minStartDate ?? $studentCommonFines->fineType[$commonFine->id]->startDate;
                if((strtotime($today) >= strtotime($studentCommonFines->fineType[$commonFine->id]->startDate)) && ($today <= $studentCommonFines->fineType[$commonFine->id]->endDate )){
                    $currentFine = new \stdclass;
                    $currentFine->fineName = $commonFine->name;
                    $currentFine->value = $studentCommonFines->fineType[$commonFine->id]->value;
                    $studentDetails->totalCommonFines += $currentFine->value;
                    $studentDetails->commonFines[] = $currentFine;
                    // if($studentCommonFines->fineType[$commonFine->id]->endDate >= $maxEndDate){
                    //     $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                    // }
                    if(strtotime($studentCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($maxEndDate)){
                        $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                    }
                    if(strtotime($studentCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($minStartDate)){
                        $minStartDate = $studentCommonFines->fineType[$commonFine->id]->startDate;
                    }
                } 
            }
        }
        // ------------Remove Internal Only Subject --------------- 
        // $studentDetails->registeredSubjects = [];
        // foreach($studentDetails->subjects as $key=> $subject){ 
        //     if($subject->isExternal != '1'){
        //         unset($studentDetails->subjects[$key]);
        //     }
        //     else{
        //         $studentDetails->registeredSubjects[] = $subject;
        //     }
        // }
        // $studentDetails->subjects = $studentDetails->registeredSubjects;
        
        // ------------Studdent Subject Fees --------------- 
        $studentDetails->totalSubjectFees = 0;
        $studentDetails->paidAmount = 0;
        foreach($studentDetails->subjects as $subject){
            $subject->supplyOrImprovement = "SUPPLEMENTARY";
            $subject->isRegistered = false;
            $subject->isApplied = false;
            $subject->isSelected = false;
            $subject->isSelected = false;
            $subject->isShowSelected = false;
            $subject->isDeleted = false;
            $subject->isAlreadyRegistered = false;
            if($disableSubjectSelection){
                $subject->isSelected = true;
                $subject->isShowSelected = true;
                $subject->disableSubjectSelection = true;
            }
            else{
                $subject->isSelected = false;
                $subject->isShowSelected = false;
                $subject->disableSubjectSelection = false;
            }
            if(!in_array($subject->academicPaperSubjectId,$request->academicPaperSubjectId)){
                $subject->isDeleted = true;
            }
            $subject->currentSubjectFeeProperties = reset(array_filter($subject->subjectFeeProperties,function($value)use($subject){
                return $value->examRegistrationType == 'SUPPLEMENTARY';
            }));
            $subject->currentSubjectFeeProperties->feeType = (array)$subject->currentSubjectFeeProperties->feeType;
            $subject->subjectFeeTemplateIdsArray = array_keys($subject->currentSubjectFeeProperties->feeType);
            $subject->currentFeeTypeTemplateId = ExamRegistrationFeeCommonService::getInstance()->getCurrentSubjectFeeTemplateForStudent($subject,$studentDetails);
            $subject->value =  $subject->currentFeeTypeTemplateId ? $subject->currentSubjectFeeProperties->feeType[$subject->currentFeeTypeTemplateId]->value : 0;
            if(in_array($subject->academicPaperSubjectId,$request->academicPaperSubjectId)){
                $studentDetails->totalSubjectFees += $request->featchAllFees ? $subject->value : 0;
            }
            elseif($request->registrationStatus == 'REGISTERED_AND_APPLIED' ){
                $studentDetails->totalSubjectFees += $request->featchAllFees ? $subject->value : 0;
            }
            if(!empty($subject->studentAssessmentRegistrationProperties) ){
                if($subject->studentAssessmentRegistrationProperties->registrationStatus == 'REGISTERED'){
                    if(in_array($subject->academicPaperSubjectId,$request->academicPaperSubjectId)){
                        $subject->isAlreadyRegistered = true;
                    }
                    $subject->isRegistered = true;
                    $subject->isApplied = false;
                    $studentDetails->totalSubjectFees +=  $request->featchAllFees ? 0 : $subject->value ;
                    $subject->isSelected = true;
                    $subject->isShowSelected = true;
                    $studentDetails->paidAmount += $subject->value;
                }
                else if($subject->studentAssessmentRegistrationProperties->registrationStatus == 'APPLIED'){
                    $subject->isRegistered = false;
                    $subject->isApplied = true;
                }
            }
        }
        $totalFeeAmount = 0;
        $totalFeeAmount = $studentDetails->totalCommonFines + $studentDetails->totalCommonFees + $studentDetails->totalSubjectFees;
        if(!$request->featchAllFees){
            if($studentDetails->totalSubjectFees > 0){
                $studentDetails->totalFeeAmount = $totalFeeAmount;
            }
            else{
                $studentDetails->totalFeeAmount = 0;
            }
        }
        else{
            $studentDetails->totalFeeAmount = $totalFeeAmount;
        }
        $studentDetails->balanceAmount = 0;
        if($studentDetails->balanceAmountDetails){
            $studentDetails->balanceReturnedStatus = $studentDetails->balanceAmountDetails->balanceReturnedStatus ? true : false;
            if($studentDetails->balanceAmountDetails->balanceAmount && $studentDetails->balanceAmountDetails->balanceReturnedStatus == false){
                $studentDetails->balanceAmount = (int)$studentDetails->balanceAmountDetails->balanceAmount;
            }
        }
        $studentDetails->balanceAmountCopy = $studentDetails->balanceAmount;
        $studentDetails->paidAmount = $studentDetails->paidAmount ? $studentDetails->paidAmount + $studentDetails->totalCommonFees + $studentDetails->totalCommonFines : 0;
        $studentDetails->totalStudentFee = $studentDetails->totalSubjectFees ? $studentDetails->totalSubjectFees + $studentDetails->totalCommonFees + $studentDetails->totalCommonFines : 0;
        if(!$request->featchAllFees){
            $studentDetails->totalFeeAmount = $studentDetails->paidAmount;
        }
        // ---------------- Calculation For save student registration-------------
        if(($studentDetails->paidAmount >= $studentDetails->totalStudentFee)){
            $studentDetails->amountTobePaid = 0;
            $studentDetails->balanceAmount += $studentDetails->paidAmount - $studentDetails->totalStudentFee;
        }
        else{
            $amountTobePaid = $studentDetails->totalStudentFee - $studentDetails->paidAmount;
            if($amountTobePaid > $studentDetails->balanceAmount){
                $studentDetails->amountTobePaid = $amountTobePaid - $studentDetails->balanceAmount;
                $studentDetails->balanceAmount = 0;
            }
            else{
                $studentDetails->balanceAmount -= $amountTobePaid;
                $studentDetails->amountTobePaid = 0;
            }
        }
        $studentDetails->subjectLimit = $studentDetails->examRegistrationProperties->subjectLimit == 'All' ? 'ALL' :(int)$studentDetails->examRegistrationProperties->subjectLimit ;
        if(empty($studentDetails->subjects) && !$request->notConsiderEmptyValidation){
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Couldnot Register Exam !!");
        }
        if (strtotime($studentDetails->examRegistrationProperties->registrationStartDate) > strtotime(date("Y-m-d H:i")) && !$request->notConsiderValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration not started");
        }
        elseif ( strtotime($maxEndDate)  < strtotime(date("Y-m-d H:i")) && !$request->notConsiderValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration closed");
        }
        else{
             // sort the subject by academics order
            usort($studentDetails->subjects, function ($a, $b) {
                return $a->subjectPriority > $b->subjectPriority;
            });
            return($studentDetails);  
        }
        
    }
    /**
     * get Student Details For Special Exam Registration Fee
     * @param $request
     * @return examRegistration
     */
    public function getStudentSpecialExamRegistrationFeeDetails($request){
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        $joinQueary = "";
        $selectColumns = "";
        if($request->mappingType == "EXAM_REGISTRATION"){
            $mapperForRegistrationDetails = StudentExamRegistrationServiceMapper::SEARCH_EXAM_REGISTRATION_FEE_DETAILS ;
        }
        else{
            $mapperForRegistrationDetails = StudentExamRegistrationServiceMapper::SEARCH_STUDENT_EXAM_REGISTRATION_FEE_DETAILS;
        }
        $sortBy = " ORDER BY eer.created_date DESC";
        $joinQueary .= " INNER JOIN ec_student_assessment_registration esar ON
                        esar.am_assessment_id = eers.am_assessment_id AND esar.ec_exam_registration_type = eer.type AND esar.properties ->> '$.isSpecialExamAssigned' = '1'"; 
        if(!empty($request->studentId)) {
            $whereQuery .= " AND spa.student_id = '$request->studentId";
        }
        if(!empty($request->academicTermId)){
            $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
            $whereQuery .= " AND  CAST(eerb.properties ->> '$.academicTermId'AS CHAR) IN ( $academicTermIdString )";
        }
        if(!empty($request->groupId)){
            $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
            $whereQuery .= " AND  g.id IN ( $groupIdString )";
        }
        if(!empty($request->examType)){
            $examTypeString = is_array($request->examType) ? "'" . implode("','",$request->examType) . "'" : "'".$request->examType."'";
            $whereQuery .= " AND eer.type IN ( $examTypeString )";
        }
        if($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::APPLIED || $request->registrationStatus == "REGISTERED_AND_APPLIED"){
            if( $request->registrationStatus == "REGISTERED_AND_APPLIED"){
                $whereQuery .= " AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED','APPLIED') ";
            }
            else{
                $whereQuery .= $request->registrationStatus == StudentExamRegistrationStatus::REGISTERED ? " AND esar.properties ->> '$.registrationStatus' = 'REGISTERED' AND esar.properties ->> '$.feeStatus' = 'PAID'" : " AND esar.properties ->> '$.registrationStatus' = 'APPLIED'";
            }
        }
        else if($request->registrationStatus == StudentExamRegistrationStatus::NOT_REGISTERED){
            $whereQuery .= " AND esar.properties ->> '$.registrationStatus' IN ('NOT_REGISTERED')";
        }
        if(!empty($request->examRegistrationId)){
            $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
            $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
        }
        if(!empty($request->academicPaperSubjectId)){
            $academicPaperSubjectIdString = is_array($request->academicPaperSubjectId) ? "'" . implode("','",$request->academicPaperSubjectId) . "'" : "'".$request->academicPaperSubjectId."'";
            $whereQuery .= " AND caps.id IN ( $academicPaperSubjectIdString )";
        }
        $query = "SELECT DISTINCT
            sa.studentID as studentId,
            sa.studentName,
            sa.studentBirthday as studentBirthday,
            sa.studentAddress as studentAddress,
            sa.studentPhone as studentPhone,
            sa.studentEmail as studentEmail,
            spa.properties->>'$.registerNumber' AS registerNo,
            sa.reservationID,
            eer.id as examRegistrationId,
            eer.name as examRegistrationName,
            eer.properties->>'$.description' as examRegistrationDescription,
            eer.type as examRegistrationType,
            eer.properties as examRegistrationProperties,
            eerb.groups_id as groupId,
            eerb.properties ->> '$.academicTermId' as academicTermId,
            eerb.properties AS batchProperties,
            eerb.fees_properties as batchFeeProperties,
            act.name AS academicTermName,
            g.name AS groupName,
            eeft.id as batchFeeTemplateId,
            eeft.fee_properties as batchCommonFees,
            eeft.fine_properties as batchCommonFines,
            IF (eeft.operation_properties  IS NULL,0,1) as isConsiderOperation,
            eeft.operation_properties as batchOperationProperties,
            eers.fees_properties as subjectFeeProperties,
            eers.properties as subjectProperties,
            eers.am_assessment_id as assessmentId,
            caps.id AS academicPaperSubjectId,
            caps.properties ->> '$.isExternal' as isExternal,
            esar.id AS studentAssessmentRegistrationId,
            esar.properties as studentAssessmentRegistrationProperties,
            s.code AS subjectCode,
            caps.properties ->> '$.syllabusName' AS syllabusName,
            s.name AS subjectName,
            eserd.total_fee AS examRegistrationPaidAmount,
            eserd.balance_amount_details AS balanceAmountDetails,
            eserd.created_date as studentEntryCreatedDate,
            eserd.properties AS examRegistrationPaymentProperties,
            esbrm.ec_block_student_reason_id as blockStudentReasonId,
            ebsr.name as blockReasonName,
            cpsa.staffName as contactPersonName,
            ebsr.properties ->> '$.description' AS contactPersonDecription
            $selectColumns
        FROM
            ec_exam_registration eer
        INNER JOIN ec_exam_registration_batch eerb ON
            eerb.ec_exam_registration_id = eer.id 
        INNER JOIN academic_term act ON 
            act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
        INNER JOIN `groups` g ON
            g.id = eerb.groups_id
            AND g.`type` = 'BATCH'
        INNER JOIN ec_examregistration_fee_templates_mapping eeftm ON
            eeftm.id = eerb.fees_properties->>'$.feeTemplateId'
        INNER JOIN ec_examregistration_fee_templates eeft ON
            eeft.ec_examregistration_fee_templates_mapping_id = eeftm.id
        INNER JOIN ec_exam_registration_subject eers ON
            eers.ec_exam_registration_batch_id = eerb.id
        INNER JOIN cm_academic_paper_subjects caps ON
            caps.id = eers.cm_academic_paper_subjects_id
        INNER JOIN v4_ams_subject s ON
            s.id = caps.ams_subject_id
        $joinQueary 
        INNER JOIN student_program_account spa ON 
            spa.student_id  = esar.student_id
        INNER JOIN studentaccount sa ON
            sa.studentID = spa.student_id
        LEFT JOIN ec_student_exam_registration_details eserd ON
            eserd.student_id = sa.studentID AND 
            eserd.ec_exam_registration_id = eer.id 
        LEFT JOIN ec_student_block_reason_mapping esbrm ON
            esbrm.student_id = sa.studentID AND esbrm.exam_registration_id = eer.id AND
            esbrm.blocking_type = 'REGISTRATION_BLOCKING'
        LEFT JOIN ec_block_student_reason ebsr ON 
            ebsr.id = esbrm.ec_block_student_reason_id AND
            ebsr.type = 'SEMESTER_WISE'
        LEFT JOIN staffaccounts cpsa ON 
            cpsa.staffID = ebsr.contact_person_id 
        WHERE
            eer.trashed IS NULL
            AND eer.properties->>'$.publish' = '1' AND eer.properties->>'$.isSpecialExam' = '1'";
        try {
            $studentExamRegistrationFeeDetails = $this->executeQueryForList($query.$whereQuery.$sortBy.$limitQuery, $this->mapper[$mapperForRegistrationDetails]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student.");
        }
        if (empty($studentExamRegistrationFeeDetails) && !$request->notConsiderEmptyValidation) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Exam Registration not declared, Please try again.");
        }
        return $studentExamRegistrationFeeDetails;
       
      
    }
    /**
     * Save student exam seat number
     * @param Object $request
     */
    public function saveStudentExamSeatNumber($request){
        $request = $this->realEscapeObject($request);
        if ($request->examRegistrationId && $request->studentId) {
            try {
                $sql = "UPDATE ec_student_exam_registration_details SET properties = JSON_SET(properties, '$.universityExamSeatNo','$request->seatNo') WHERE ec_exam_registration_id = '$request->examRegistrationId' AND student_id = '$request->studentId'";
                $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ExamControllerException($e->getCode(), $e->getMessage());
            }
        }
        return true;
    }
    /**
     * Get student assigned halls for exam
     * @param Object $request
     */
    public function getStudentAssignedHallsForExam($request){
        $request = $this->realEscapeObject($request);
        try {
            $sql = "SELECT 
                        eeh.id, 
                        eeh.name, 
                        ehagas.am_assessment_id AS assessmentId 
                    FROM 
                        ec_hall_arrangement_group_assigned_student ehagas 
                    INNER JOIN ec_hall_arrangement_group_assigned_hall ehagah ON 
                        ehagah.id = ehagas.ec_hall_arrangement_group_assigned_hall_id 
                    INNER JOIN ec_exam_hall eeh ON 
                        eeh.id = ehagah.ec_exam_hall_id 
                    WHERE 
                        ehagas.student_id = '$request->studentId' AND ehagah.is_locked = '1' ";
            $assignedStudents = (array)$this->executeQueryForList($sql);
            $studentExamHalls = [];
            foreach($assignedStudents as $student){
                $studentExamHalls[$student->assessmentId] = $student;
            }
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $studentExamHalls;
    }
      /**
     * Search stduent Exam Registration For Minor Honours
     * @param SearchStudentExamRegistrationRequest $request
     * @return examRegistration
     */
    public function getMinorHonoursExamRegistrationsForStudentRegistration(SearchStudentExamRegistrationRequest $request){
        $request->mappingType = "EXAM_REGISTRATION";
        $haveImprovement = false;
        $isEnableMinorHonorExamRegistration = false;
        $isShowApplicationForm = false;
        $searchExamRuleRequest = new SearchRuleRequest;
        $searchExamRuleRequest->name = 'EXAM_REGISTRATION_CREATION_RULE';
        $ruleObj = reset(RuleService::getInstance()->searchRule($searchExamRuleRequest));
        if($ruleObj){
            $isEnableMinorHonorExamRegistration = $ruleObj->rule->isEnableMinorHonorExamRegistration == '1' ? true : false;
            $isShowApplicationForm = $ruleObj->rule->isShowApplicationForm == '1' ? true : false;
        }
        $request->isEnableMinorHonorExamRegistration = $isEnableMinorHonorExamRegistration;
        $latestExamDetails = new \stdClass;
        $request->isNotConsiderSpecialExam = true;
        $request->notConsiderEmptyValidation = true;
        $searchRuleRequest = new SearchRuleRequest;
        $searchRuleRequest->name = "HALL_TICKET_STUDENT_SIDE";
        $hallTicketRule = reset(RuleService::getInstance()->searchRule($searchRuleRequest));
        $enableHallticketStudentSide = $hallTicketRule->rule->enableHallTicket ? true : false;
        $showExamRegReceiptSettingsJSON = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, SettingsConstants::ENABLE_EXAM_REGISTRATION_RECEIPT);
        $showExamRegReceipt = json_decode($showExamRegReceiptSettingsJSON)->enableReceiptRegular;
        $showAppliedSubjectsInExamReg = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, SettingsConstants::SHOW_APPLIED_SUBJECTS_IN_EXAM_REGISTRATION);
        $examRegistrations = $this->getStudentExamRegistrationFeeDetails($request);
        $assignedHalls = $this->getStudentAssignedHallsForExam($request);
        foreach ($examRegistrations as $examKey=> $examRegistration) {
            $isMinorCourse = $examRegistration->examRegistrationProperties->isMinorCourse == '1' ? true : false;
            $isHonorCourse = $examRegistration->examRegistrationProperties->isHonorCourse == '1' ? true : false;
            $examRegistration->isApplied = false;
            $examRegistration->isBlocked = false;
            $examRegistration->isRegistered = false;
            $examRegistration->canRegister = true;
            $examRegistration->blockReasons = [];
            $examRegistration->paymentStatus = "Not Paid";
            $examRegistration->status = "Not Registered";
            $examRegistration->blockedSubjectCount = 0;
            if(count($examRegistration->batchFeeFine) > 1){
                $examRegistration->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($examRegistration);
            }
            else{
                $examRegistration->currentBatchCommonFeeFine = reset($examRegistration->batchFeeFine);
            }
            $examRegistration->commonFines = []; 
            $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
            $examRegistrationCommonFines = reset(array_filter($examRegistration->currentBatchCommonFeeFine->batchCommonFines,function($value)use($examRegistration){
                return $value->examRegistrationType == $examRegistration->examRegistrationType;
            }));
            $studentCommonFineIdsArray = array_keys((array)$examRegistrationCommonFines->fineType);
            $examRegistrationCommonFines->fineType = (array)$examRegistrationCommonFines->fineType;
            $today = date("Y-m-d H:i");
            // $maxEndDate = $examRegistration->examRegistrationProperties->registrationWithoutFineEndDate ? $examRegistration->examRegistrationProperties->registrationWithoutFineEndDate : '';
            foreach($allCommonFines as $commonFine){
                if ( in_array ( $commonFine->id, $studentCommonFineIdsArray ) ) {
                    $maxEndDate = $maxEndDate ?? $examRegistrationCommonFines->fineType[$commonFine->id]->endDate;
                    $minStartDate = $minStartDate ?? $examRegistrationCommonFines->fineType[$commonFine->id]->startDate;
                    if(strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($maxEndDate)){
                        $maxEndDate = $examRegistrationCommonFines->fineType[$commonFine->id]->endDate;
                    }
                    if(strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($minStartDate)){
                        $minStartDate = $examRegistrationCommonFines->fineType[$commonFine->id]->startDate;
                    }
                    if($examRegistration->examRegistrationPaymentProperties->challanAppliedDate){
                        if(strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($examRegistration->examRegistrationPaymentProperties->challanAppliedDate) && strtotime($examRegistrationCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($examRegistration->examRegistrationPaymentProperties->challanAppliedDate) ){
                            $challanVerificationDate = $examRegistrationCommonFines->fineType[$commonFine->id]->verificationDate;
                            
                        }
                    }
                }
            }
            $examRegistration->isChallanExperied = true;
            if($challanVerificationDate && strtotime($challanVerificationDate) >= strtotime($today)){
                $examRegistration->isChallanExperied = false;
            }
            $examRegistration->registrationStartDate = $minStartDate;
            $examRegistration->registrationEndDate = $maxEndDate;
            foreach($examRegistration->subjects as $subKey=> $subject){
                $subject->isBlocked = false;
                $subject->hallName = $assignedHalls[$subject->assessmentId]->name;
                if($isEnableMinorHonorExamRegistration){
                    $syllabusTypeSubjects = [];
                    $searchRequestForSubject = new \stdClass();
                    $searchRequestForSubject->academicPaperSubjectId = $subject->academicPaperSubjectId; 
                    $searchRequestForSubject->groupId = $examRegistration->groupId;
                    $searchRequestForSubject->syllabusType = "";
                    if($isMinorCourse || $isHonorCourse){
                        $searchRequestForSubject->syllabusType =  $isMinorCourse ? SyllabusTypeConstants::MINOR : SyllabusTypeConstants::HONOURS;
                    }
                    else{
                        $searchRequestForSubject->syllabusType = SyllabusTypeConstants::MAJOR;
                    }
                    if( $subject->studentAssessmentRegistrationProperties->syllabusSubType == 'MOOC' ){
                        $subject->isMoocSubject = '1';
                        $examRegistration->hasMoocSubject = 1;
                        $subject->isApprovedMoocCertificate = false;
                        $requestForCertificate = new \stdClass();
                        $certificateDetails = new \stdClass(); 
                        $requestForCertificate->groupId = $examRegistration->groupId;
                        $requestForCertificate->studentId = $examRegistration->studentId;
                        $requestForCertificate->assessmentId = $subject->assessmentId;
                        $requestForCertificate->type = 'MOOC_COURSE_CERTIFICATES';
                        if ( $subject->moocCertificateStatus != 'REJECTED' ){
                            $subject->uploadedCertificates = CertificateUploadService::getInstance()->getCertificateUpload($requestForCertificate);
                        }
                        if ( $subject->moocCertificateStatus == 'REJECTED' ){
                            $examRegistration->isMoocCertificateRejected = 1;
                        }
                        // $requestForAdditionalDetails->studentId = $examRegistration->studentId;
                        // $requestForAdditionalDetails->groupId = $examRegistration->groupId;
                        // $requestForAdditionalDetails->isFetchAppliedStudentsOnly = true;
                        $subject->isApprovedMoocCertificate = $subject->moocCertificateStatus == 'APPROVED' ? true : false;
                    }
                    $searchRequestForSubject->isEnableMinorHonorExamRegistration = true;
                    $syllabusTypeSubjects = CommonExamService::getInstance()->getAssignedSubjectsInBatch($searchRequestForSubject);
                    if(empty($syllabusTypeSubjects)){
                        unset($examRegistrations[$examKey]->subjects[$subKey]);
                    }
                }
                if($examRegistration->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SUBJECT_WISE'){
                    $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
                    $attendanceTermWiseReportRequest->studentId = $examRegistration->studentId;
                    $attendanceTermWiseReportRequest->termId = $examRegistration->academicTermId;
                    $attendanceTermWiseReportRequest->paperSubjectId = $subject->academicPaperSubjectId;
                    $subject->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
                    if($subject->properties->minimumAttendancePercentage > $subject->attendanceDetails->attendancePercentage){
                        $subject->isBlocked = true;
                        $subject->blockReasons = ['Attendance Shortage'];
                        $examRegistration->blockedSubjectCount ++;
                    }
                }
                $subject->isApplied = false;
                if($subject->studentAssessmentRegistrationId && $subject->studentAssessmentRegistrationProperties){
                    $subject->paymentStatus = $subject->studentAssessmentRegistrationProperties->feeStatus;
                    $subject->status = $subject->studentAssessmentRegistrationProperties->registrationStatus;
                    if(($subject->paymentStatus == StudentExamRegistrationPaymentStatus::PAID || $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING)&& ($subject->status == StudentExamRegistrationStatus::REGISTERED || $subject->status == StudentExamRegistrationStatus::APPLIED)){
                        $subject->isRegistered = $subject->status == StudentExamRegistrationStatus::REGISTERED ? true : false;
                        if(!$examRegistration->isRegistered){
                            $examRegistration->paymentStatus = $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PAID ? "Paid" : "Pending";
                            $examRegistration->status = $subject->status == StudentExamRegistrationStatus::REGISTERED ? "Registered" : "Applied";
                            $examRegistration->isRegistered = $subject->status == StudentExamRegistrationStatus::REGISTERED ? true : false;
                            $examRegistration->isApplied = !$examRegistration->isApplied && $subject->status == StudentExamRegistrationStatus::APPLIED ? true : $examRegistration->isApplied;
                            $examRegistration->isReApply = $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING ? true : false;
                            $examRegistration->isCheckPaymentStatus = !$examRegistration->isCheckPaymentStatus && $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING ? true : $examRegistration->isCheckPaymentStatus;
                            if($examRegistration->examRegistrationType == 'REGULAR'){
                                $examRegistration->canRegister = $examRegistration->canRegister && $examRegistration->isRegistered ? false : true;
                            }
                        }
                        else{ 
                            if($examRegistration->examRegistrationType == 'SUPPLEMENTARY'){
                                $examRegistration->isApplied = !$examRegistration->isApplied && $subject->status == StudentExamRegistrationStatus::APPLIED ? true : $examRegistration->isApplied;
                                $examRegistration->isCheckPaymentStatus = !$examRegistration->isCheckPaymentStatus && $subject->paymentStatus == StudentExamRegistrationPaymentStatus::PENDING ? true : $examRegistration->isCheckPaymentStatus;
                            }
                            else{
                                $examRegistration->isReApply = false;
                                $examRegistration->isCheckPaymentStatus = false;
                            }                   
                            if($examRegistration->examRegistrationType == 'REGULAR'){
                                $examRegistration->canRegister = false;
                            }
                        }
                        $subject->isApplied = true;
                    }
                    else{
                        $subject->isApplied = false;
                    }
                    
                }
                else{
                    $subject->isApplied = false;
                }
            }
            if (strtotime($minStartDate) > strtotime(date("Y-m-d H:i"))) {
                $examRegistration->isBlocked = true;
                $examRegistration->canRegister = false;
                $examRegistration->isNotStarted = true;
                $examRegistration->blockReasons = ["Registration not started"];
            }
            elseif (strtotime($maxEndDate)  < strtotime(date("Y-m-d H:i"))) {
                $examRegistration->isClosed = true;
                $examRegistration->isBlocked = true;
                $examRegistration->canRegister = false;
                $examRegistration->blockReasons = ["Registration closed"];
            }
            else if($examRegistration->examRegistrationPaymentProperties->paymentOption ==  ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD &&  ($examRegistration->examRegistrationType == 'REGULAR' || $examRegistration->examRegistrationType == 'SUPPLEMENTARY' ) && ( $examRegistration->isApplied || $examRegistration->isRegistered ) && !$examRegistration->isChallanExperied){
                $examRegistration->canRegister = false;
            }
            else if($examRegistration->examRegistrationPaymentProperties->paymentOption !=  ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD &&  ($examRegistration->examRegistrationType == 'REGULAR' || $examRegistration->examRegistrationType == 'SUPPLEMENTARY' ) && ( $examRegistration->isApplied || $examRegistration->isRegistered )){
                $examRegistration->canRegister = false;
            }
            $examRegistration->paymentOption =   $examRegistration->examRegistrationPaymentProperties->paymentOption;
            if($examRegistration->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SEMESTER_WISE'){
                $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
                $attendanceTermWiseReportRequest->studentId = $examRegistration->studentId;
                $attendanceTermWiseReportRequest->termId = $examRegistration->academicTermId;
                $examRegistration->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
                if($examRegistration->examRegistrationProperties->minimumAttendancePercentage > $examRegistration->attendanceDetails->attendancePercentage){
                    $examRegistration->canRegister = false;
                    $examRegistration->blockReasons = ['Attendance Shortage'];
                }
            }
            if($examRegistration->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SUBJECT_WISE'){
                if(count($examRegistration->subjects) == $examRegistration->blockedSubjectCount){
                    $examRegistration->canRegister = false;
                    $examRegistration->blockReasons = ['Attendance Shortage'];
                }
            }
            if($examRegistration->examRegistrationProperties->enableHallTicketExamStudent && $enableHallticketStudentSide){
                $examRegistration->isShowHallTicket = $examRegistration->isRegistered ? true : false;
            }
        }
        $studentExamRegistrationDetails = new \stdClass;
        $studentExamRegistrationDetails->enableHallticketStudentSide = $enableHallticketStudentSide;
        $studentExamRegistrationDetails->showExamRegReceipt = $showExamRegReceipt;
        $studentExamRegistrationDetails->showAppliedSubjectsInExamReg = $showAppliedSubjectsInExamReg;
        $studentExamRegistrationDetails->examRegistrations = $examRegistrations;
        $studentExamRegistrationDetails->isShowApplicationForm = $isShowApplicationForm;
        return $studentExamRegistrationDetails;
    }
     /**
     * Search stduent Hornours Minor Exam Registration
     * @param $request
     * @return studentDetails
     */
    public function searchStudentCurrentHornoursMinorExamRegistrationFeeDetails($request){
        $studentDetails = $this->getStudentRegularMinorHonourExamRegistrationSubjectFeeDetails($request);
        if( $studentDetails->isMoocSubject != 1){
            $studentDetails->isRegularSubject = 1;
        }
        // $studentDetails->canApplyExamByMoocType = true;
        // $isNotEligileExamRegistation = false;
        // $isNotEligileExamRegistationReason = "";
        // Rules For Honour And Minor Exam Registration
        // if($studentDetails->examRegistrationProperties->isMinorCourse == '1'){
        //     // this case rule for Minor Syllabus type
        //     $studentDetails->registeredMoocExams = 0;
        //     $studentDetails->registeredTotalExams = 0;
        //     $examRegistrationReq = new \stdClass;
        //     $examRegistrationReq->studentId = $studentDetails->studentId;
        //     $examRegistrationReq->isHonourExamOnly = false;
        //     $examRegistrationReq->isMinorExamOnly = true;
        //     $studentDetailsMinorExam = reset($this->getStudentRegisteredExamRegistrationWithResultDetails($examRegistrationReq));
        //     if(($studentDetailsMinorExam)){
        //         foreach($studentDetailsMinorExam->academicTerms as $academicTerm){
        //             foreach($academicTerm->subjects as $subject){
        //                 if(!empty($subject->assessmentRegistrationProperties)){
        //                     $studentDetails->registeredTotalExams++;
        //                     $studentDetails->registeredMoocExams = $subject->assessmentRegistrationProperties->syllabusSubType == "MOOC" ? $studentDetails->registeredMoocExams + 1 : $studentDetails->registeredMoocExams + 0;
        //                     if($subject->subjectMarkDetails){
        //                         if($subject->assessmentRegistrationProperties->syllabusSubType != "MOOC" && $subject->subjectFailedStatus != 'PASSED'){
        //                             $isNotEligileExamRegistation = true;
        //                             $isNotEligileExamRegistationReason = "Not eligible : failed in pervious minor";
        //                         }
        //                     }
        //                 }
        //             }
        //         }
        //         // if($studentDetailsMinorExam->courseFailedStatus == 'FAILED'){
        //         //     $isNotEligileExamRegistation = true;
        //         //     $isNotEligileExamRegistationReason = "Not eligible : failed in academics";
        //         // }
                
        //     }
        // }
        // if($studentDetails->examRegistrationProperties->isHonorCourse == '1'){
        //     // this case rule for Honor Syllabus type
        //     $studentDetails->registeredMoocExams = 0;
        //     $studentDetails->registeredTotalExams = 0;
        //     $examRegistrationReq = new \stdClass;
        //     $examRegistrationReq->studentId = $studentDetails->studentId;
        //     $examRegistrationReq->isHonourExamOnly = true;
        //     $examRegistrationReq->isMinorExamOnly = false;
        //     $studentDetailsHonourExam = reset($this->getStudentRegisteredExamRegistrationWithResultDetails($examRegistrationReq));
        //     if(($studentDetailsHonourExam)){
        //         foreach($studentDetailsHonourExam->academicTerms as $academicTerm){
        //             foreach($academicTerm->subjects as $subject){
        //                 if(!empty($subject->assessmentRegistrationProperties)){
        //                     $studentDetails->registeredTotalExams++;
        //                     $studentDetails->registeredMoocExams = $subject->assessmentRegistrationProperties->syllabusSubType == "MOOC" ? $studentDetails->registeredMoocExams + 1 : $studentDetails->registeredMoocExams + 0;
        //                     if($subject->subjectMarkDetails){
        //                         if($subject->assessmentRegistrationProperties->syllabusSubType != "MOOC" && $subject->subjectFailedStatus != 'PASSED'){
        //                             $isNotEligileExamRegistation = true;
        //                             $isNotEligileExamRegistationReason = "Not eligible : failed in pervious honour";
        //                         }
        //                     }
        //                 }
        //             }
        //         }
        //         if($studentDetailsHonourExam->courseFailedStatus == 'FAILED'){
        //             $isNotEligileExamRegistation = true;
        //             $isNotEligileExamRegistationReason = "Not eligible : failed in academics";
        //         }
                
        //     }
        //     // this case disabled, this case check only first honor exam
        //     // $cgpaValue = CommonService::getInstance()->getSettings('EXAM_REGISTRATION','CGPA_REQUIRED_FOR_HONOUR_EXAM');
        //     // if($studentDetailsHonourExam->courseMarkDetails->cgpa <  $cgpaValue){
        //     //     $isNotEligileExamRegistation = true;
        //     //     $isNotEligileExamRegistationReason = "Not eligible : not met CGPA requirements";
        //     // }
        // }
        // For college the minor honour Exams should be upto 5 subjects 
        // The limit of subject set corresponding curriculum after that depolyment the limit 5 change to limit from UI
        // if( $studentDetails->registeredTotalExams >= 5){
        //     throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,"Not eligible : exceed subject limit");
        // }
        
        // if($isNotEligileExamRegistation){
        //     throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,$isNotEligileExamRegistationReason);
        // }
        // For college the MOOC Exams should be upto 2 subjects 
        // The limit of subject set (MAX mooc can choose) corresponding curriculum after that depolyment, change the limit 2 to corresponding curriculum
        // if($studentDetails->registeredMoocExams >= 2){
        //     $studentDetails->canApplyExamByMoocType = false;
        // }
        return($studentDetails);
    }
         /**
     * Search stduent Regular Minor Honor Exam Registration
     * @param $request
     * @return examRegistration
     */
    public function getStudentRegularMinorHonourExamRegistrationSubjectFeeDetails($request){
        $searchRequest = new \stdClass;
        $searchRequest->studentId = $request->studentId;
        $studentCommonFeesIdsArray = [];
        $studentCommonFineIdsArray = [];
        $searchRequest->academicPaperSubjectId = $request->academicPaperSubjectId;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->registrationStatus = $request->registrationStatus;
        $searchRequest->notConsiderEmptyValidation =  $request->notConsiderEmptyValidation;
        $searchRequest->considerRegisteredAndApplied =  $request->considerRegisteredAndApplied;
        $studentDetails = reset($this->getStudentExamRegistrationFeeDetails($searchRequest));
        if($request->considerRegisteredAndApplied){
            $registeredSearchRequest = new \stdClass;
            $registeredSearchRequest->studentId = $request->studentId;
            $registeredSearchRequest->examRegistrationId = $request->examRegistrationId;
            $registeredSearchRequest->registrationStatus =  "REGISTERED_AND_APPLIED";
            $registeredSearchRequest->notConsiderEmptyValidation = true;
            $registerdStudentDetails = reset($this->getStudentExamRegistrationFeeDetails($registeredSearchRequest));
        }
        if($studentDetails->blockReasons && !$request->notConsiderValidation) {
            $blockReasonMsg = "Registration Blocked ";
            foreach($studentDetails->blockReasons as $reason){
                $blockReasonMsg .= "<br> * Due to ".$reason->name .". ";
                $blockReasonMsg .= $reason->contactPersonName ? "Please contact ".$reason->contactPersonName :"";
                $blockReasonMsg .= $reason->contactPersonDecription ? " ".$reason->contactPersonDecription :"";
            }
            throw new ExamControllerException (ExamControllerException::REGISTRATION_BLOCKING,$blockReasonMsg);
        }
        foreach($studentDetails->examRegistrationProperties->paymentMethods as $paymentMethod){
            if($paymentMethod == ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::COLLEGE_CHALLAN_METHOD;
                $currentPaymentMethod->name = "College Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::BANK_CHALLAN_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::BANK_CHALLAN_METHOD;
                $currentPaymentMethod->name = "Bank Challan Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
            if($paymentMethod == ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD){
                $currentPaymentMethod = new \Stdclass;
                $currentPaymentMethod->id = ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD;
                $currentPaymentMethod->name = "Online Payment Method";
                $studentDetails->paymentMethods[] = $currentPaymentMethod;
            }
        }
        
        $showGenderWiseAttendance = false;
        if( empty($request->notConsiderValidation) ){
            $showGenderWiseAttendance = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, "EXAM_REGISTRATION_GENDER_WISE_ATTENDANCE_CHECK");
            if($showGenderWiseAttendance){
                if(empty($studentDetails->examRegistrationProperties->genderWiseMinimumAttendance)){
                    throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Gender wise attendance rule not added. Please contact exam controller.");
                }
                if(empty($studentDetails->studentGender) || (strtoupper($studentDetails->studentGender) != 'MALE' && strtoupper($studentDetails->studentGender) != 'FEMALE') ){
                    throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Gender details not added. Please contact exam controller.");
                }
                $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance = (array) $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance;
            }
        }
        if ($request->isStudentSideRequest){
            $enableSubjectWiseCondonation = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_CONTROLLER, "ENABLE_SUBJECT_WISE_CONDONATION");
            $studentDetails->considerSubjectWiseCondonation = $enableSubjectWiseCondonation;
        }
        if($studentDetails->considerSubjectWiseCondonation){
            if( $studentDetails->examRegistrationProperties->workFlowId ){
                $condonationStatus = ProfessionalCommonExamService::getInstance()->getStatusOfWorkflowRequest($studentDetails->studentId, $studentDetails->academicTermId,$studentDetails->examRegistrationProperties->workFlowId);
                if( $condonationStatus  == "APPROVED" ){
                    $condationSubjectRequest = new \stdClass();
                    $condationSubjectRequest->studentId = $studentDetails->studentId; 
                    $condationSubjectRequest->termId = $studentDetails->academicTermId; 
                    $condationSubjectRequest->gender = $studentDetails->studentGender; 
                    $condationSubjectRequest->isExamRegistrationApplyRequest = 1; 
                    $condationSubjectRequest->workFlowId = $studentDetails->examRegistrationProperties->workFlowId;
                    $condationSubjectRequest = (array) $condationSubjectRequest;
                    $condonationApprovedSubjectList = ProfessionalCommonExamService::getInstance()->checkStudentIsEligibleForCondonation($condationSubjectRequest);
                }
                else{
                    $condationSubjectRequest = new \stdClass();
                    $condationSubjectRequest->studentId = $studentDetails->studentId; 
                    $condationSubjectRequest->termId = $studentDetails->academicTermId; 
                    $condationSubjectRequest->gender = $studentDetails->studentGender; 
                    $condationSubjectRequest->isExamRegistrationApplyRequest = 1; 
                    $condationSubjectRequest->workFlowId = $studentDetails->examRegistrationProperties->workFlowId;
                    $condationSubjectRequest = (array) $condationSubjectRequest;
                    $condonationEligibleSubjectList = ProfessionalCommonExamService::getInstance()->checkStudentIsEligibleForCondonation($condationSubjectRequest);
                }
            }
        }
        $studentDetails->totalFeeAmount = 0;
         // ------------Studdent common Fees & Fines --------------- 
        if(count($studentDetails->batchFeeFine) > 1){
            $studentDetails->currentBatchCommonFeeFine = ExamRegistrationFeeCommonService::getInstance()->getCurrentFeeTemplateForStudent($studentDetails);
        }
        else{
            $studentDetails->currentBatchCommonFeeFine = reset($studentDetails->batchFeeFine);
        }
        // ------------Remove Attendance Shortage Subjects Student Side--------------- 
        $studentDetails->canApplyExamByRegularType = true;
        $studentDetails->eligibleSubjectForCondonation = [];
        if($studentDetails->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SUBJECT_WISE'){
            $studentDetails->registeredSubjects = [];
            foreach($studentDetails->subjects as $key=> $subject){ 
                $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
                $attendanceTermWiseReportRequest->studentId = $studentDetails->studentId;
                $attendanceTermWiseReportRequest->termId = $studentDetails->academicTermId;
                $attendanceTermWiseReportRequest->paperSubjectId = $subject->academicPaperSubjectId;
                $attendanceTermWiseReportRequest->attendanceClosingDate = $studentDetails->batchProperties->attendanceClosingDate;
                if ( $subject->isMoocSubject == 1){
                    $studentDetails->isMoocSubject = 1;
                    $studentDetails->registeredSubjects[] = $subject;
                    continue;
                }
                else{
                    $studentDetails->isRegularSubject = 1;
                }
                $subject->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
                if($showGenderWiseAttendance){
                    $subject->properties->minimumAttendancePercentage = $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance[strtoupper($studentDetails->studentGender)];
                }
                $subject->isShortageAttendance  = ($subject->properties->minimumAttendancePercentage > $subject->attendanceDetails->attendancePercentage) ? true : false;
                if( $studentDetails->considerSubjectWiseCondonation && $condonationStatus  == "APPROVED" ){
                    if ( in_array($subject->academicPaperSubjectId, $condonationApprovedSubjectList) ){
                        $subject->isShortageAttendance = false;
                    }
                }
                else if ( $studentDetails->considerSubjectWiseCondonation  ){
                    if ( in_array($subject->academicPaperSubjectId, $condonationEligibleSubjectList) ){
                        $studentDetails->eligibleSubjectForCondonation[] = json_decode(json_encode($studentDetails->subjects[$key]));
                    }
                }
                if($subject->isShortageAttendance && !$request->notConsiderValidation){
                    unset($studentDetails->subjects[$key]);
                    continue;
                    // $studentDetails->canApplyExamByRegularType = false;
                    // $studentDetails->blockReasons = ['Attendance Shortage'];
                }
                $studentDetails->registeredSubjects[] = $subject;
            }
            $studentDetails->subjects = $studentDetails->registeredSubjects;
        }
        // ------------studdent common Fees --------------- 
        $studentDetails->commonFees = [];   
        $studentDetails->totalCommonFees = 0;  
        $feeRequest = new \stdClass;
        $feeRequest->examType = 'REGULAR';
        $allCommonFees = CommonExamService::getInstance()->getAllFeesTypes($feeRequest);
        $studentCommonFees = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFees,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRegistrationType;
        }));
        $studentCommonFeesIdsArray = array_keys((array)$studentCommonFees->feeType);
        $studentCommonFees->feeType = (array)$studentCommonFees->feeType;
        $subjectLimitFees = [];
        $subjectLimitCounts = [];
        if( $studentDetails->isRegularSubject == 1 ){
            foreach($allCommonFees as $commonFee){
                if ( in_array ( $commonFee->id, $studentCommonFeesIdsArray ) ) {
                    if($studentCommonFees->feeType[$commonFee->id]->value){
                        if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject != '1'){
                            $currentFee = new \stdclass;
                            $currentFee->feeName = $commonFee->name;
                            $currentFee->isSubjectFeeLimit = $commonFee->isSubject_fee_limit;
                            $currentFee->value = $studentCommonFees->feeType[$commonFee->id]->value;
                            $currentFee->currentValue = $studentCommonFees->feeType[$commonFee->id]->value;
                            $currentFee->maxValue = $currentFee->isSubjectFeeLimit ? $studentCommonFees->feeType[$commonFee->id]->maxValue : 0;
                            $studentDetails->totalCommonFees += $currentFee->value;
                            $studentDetails->commonFees[] = $currentFee;
                        } 
                        else if($commonFee->isCommon && $commonFee->considerFeeSelectionSubject == '1'){
                            if($commonFee->feeSelectionSubjectLimit && $studentCommonFees->feeType[$commonFee->id]->value){
                                $subjectLimitFees[$commonFee->feeSelectionSubjectLimit] =  $studentCommonFees->feeType[$commonFee->id]->value;
                                $subjectLimitCounts[$commonFee->feeSelectionSubjectLimit] = $commonFee->feeSelectionSubjectLimit;
                            }
                        } 
                    }
                }
            }
        }
        if(!empty($subjectLimitFees)){
            $subjectCount = count($studentDetails->subjects);
            sort($subjectLimitCounts);
            $index = array_search($subjectCount, $subjectLimitCounts);
            $resultIndex = ($index !== false && $subjectLimitCounts[$index] == $subjectCount) ? $subjectLimitCounts[$index] : (empty($subjectLimitCounts) ? null : max(array_filter($subjectLimitCounts, function($value) use ($subjectCount) {
                return $value <= $subjectCount;
            })));
            if(!empty($subjectLimitFees[$resultIndex])){
                $currentFee = new \stdclass;
                $currentFee->feeName = "Total Subject Fee";
                $currentFee->isSubjectFeeLimit = 0;
                $currentFee->value = $subjectLimitFees[$resultIndex];
                $studentDetails->totalCommonFees += $currentFee->value;
                $studentDetails->commonFees[] = $currentFee;
            }
        }
        // ------------studdent common Fines ---------------    
        $studentDetails->commonFines = []; 
        $studentDetails->totalCommonFines = 0;
        $allCommonFines = CommonExamService::getInstance()->getAllFineTypes();
        $studentCommonFines = reset(array_filter($studentDetails->currentBatchCommonFeeFine->batchCommonFines,function($value)use($studentDetails){
            return $value->examRegistrationType == $studentDetails->examRegistrationType;
        }));
        $studentCommonFineIdsArray = array_keys((array)$studentCommonFines->fineType);
        $studentCommonFines->fineType = (array)$studentCommonFines->fineType;
        $today = date("Y-m-d H:i");
        if ( $request->considerChallanVerifyDate ) {
            $today = $studentDetails->examRegistrationPaymentProperties->challanAppliedDate? $studentDetails->examRegistrationPaymentProperties->challanAppliedDate :date("Y-m-d H:i");
        }
        if($request->considerRegisteredAndApplied && !empty($registerdStudentDetails)){
            $today = $registerdStudentDetails->studentEntryCreatedDate? $registerdStudentDetails->studentEntryCreatedDate :date("Y-m-d H:i");
        }
        // $maxEndDate = $studentDetails->examRegistrationProperties->registrationWithoutFineEndDate;
        foreach($allCommonFines as $commonFine){
            if ( in_array ( $commonFine->id, $studentCommonFineIdsArray ) ) {
                $maxEndDate = $maxEndDate ?? $studentCommonFines->fineType[$commonFine->id]->endDate;
                $minStartDate = $minStartDate ?? $studentCommonFines->fineType[$commonFine->id]->startDate;
                if((strtotime($today) >= strtotime($studentCommonFines->fineType[$commonFine->id]->startDate)) && ($today <= $studentCommonFines->fineType[$commonFine->id]->endDate )){
                    $currentFine = new \stdclass;
                    $currentFine->fineName = $commonFine->name;
                    $currentFine->value = $studentCommonFines->fineType[$commonFine->id]->value;
                    if( $studentDetails->isRegularSubject == 1 ){
                        $studentDetails->totalCommonFines += $currentFine->value;
                        $studentDetails->commonFines[] = $currentFine;
                    }
                    if(strtotime($studentCommonFines->fineType[$commonFine->id]->endDate) >= strtotime($maxEndDate)){
                        $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                    }
                    if(strtotime($studentCommonFines->fineType[$commonFine->id]->startDate) <= strtotime($minStartDate)){
                        $minStartDate = $studentCommonFines->fineType[$commonFine->id]->startDate;
                    }
                    // if($studentCommonFines->fineType[$commonFine->id]->endDate >= $maxEndDate){
                    //     $maxEndDate = $studentCommonFines->fineType[$commonFine->id]->endDate;
                    // }
                } 
            }
        }
        // ------------Studdent Subject Fees --------------- 
        $studentDetails->totalSubjectFees = 0;
        $feeAddedSubjectIds = [];
        foreach($studentDetails->subjects as $subject){
            $subject->currentSubjectFeeProperties = reset(array_filter($subject->subjectFeeProperties,function($value)use($studentDetails){
                return $value->examRegistrationType == $studentDetails->examRegistrationType;
            }));
            $subject->currentSubjectFeeProperties->feeType = (array)$subject->currentSubjectFeeProperties->feeType;
            $subject->subjectFeeTemplateIdsArray = array_keys($subject->currentSubjectFeeProperties->feeType);
            $subject->currentFeeTypeTemplateId = ExamRegistrationFeeCommonService::getInstance()->getCurrentSubjectFeeTemplateForStudent($subject,$studentDetails);
            $subject->value =  $subject->currentFeeTypeTemplateId ? $subject->currentSubjectFeeProperties->feeType[$subject->currentFeeTypeTemplateId]->value : 0;
            if (  $subject->isMoocSubject == 1){
                $subject->value = 0;
            }
            $studentDetails->totalSubjectFees += $subject->value;
            $feeAddedSubjectIds[$subject->id] = $subject->id;
        }
        $studentDetails->totalSubjectFeesNotApplied = $studentDetails->totalSubjectFees;
        if($request->considerRegisteredAndApplied){
            foreach($registerdStudentDetails->subjects as $subject){
                if( !in_array($subject->id, $feeAddedSubjectIds)){
                    $subject->currentSubjectFeeProperties = reset(array_filter($subject->subjectFeeProperties,function($value)use($registerdStudentDetails){
                        return $value->examRegistrationType == $registerdStudentDetails->examRegistrationType;
                    }));
                    $subject->currentSubjectFeeProperties->feeType = (array)$subject->currentSubjectFeeProperties->feeType;
                    $subject->subjectFeeTemplateIdsArray = array_keys($subject->currentSubjectFeeProperties->feeType);
                    $subject->currentFeeTypeTemplateId = ExamRegistrationFeeCommonService::getInstance()->getCurrentSubjectFeeTemplateForStudent($subject,$studentDetails);
                    $subject->value =  $subject->currentFeeTypeTemplateId ? $subject->currentSubjectFeeProperties->feeType[$subject->currentFeeTypeTemplateId]->value : 0;
                    if (  $subject->isMoocSubject == 1){
                        $subject->value = 0;
                    }
                    $studentDetails->totalSubjectFees += $subject->value;
                }
                
            }
        }
        $studentDetails->totalFeeAmount = $studentDetails->totalCommonFines + $studentDetails->totalCommonFees + $studentDetails->totalSubjectFees;
        if($request->considerRegisteredAndApplied && !empty($registerdStudentDetails)){
            $studentDetails->commonFines = [];
            $studentDetails->commonFees = [];
            $studentDetails->totalSubjectFees = $studentDetails->totalSubjectFeesNotApplied;
        }
        if (strtotime($minStartDate) > strtotime(date("Y-m-d H:i")) && !$request->notConsiderValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration not started");
        }
        elseif ( strtotime($maxEndDate)  < strtotime(date("Y-m-d H:i")) && !$request->notConsiderValidation) {
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Registration closed");
        }
        elseif($studentDetails->examRegistrationProperties->criteriaDuringMinimumAttendance == 'SEMESTER_WISE'){
            $attendanceTermWiseReportRequest = new AttendanceTermWiseReport();
            $attendanceTermWiseReportRequest->studentId = $studentDetails->studentId;
            $attendanceTermWiseReportRequest->termId = $studentDetails->academicTermId;
            $attendanceTermWiseReportRequest->attendanceClosingDate = $studentDetails->batchProperties->attendanceClosingDate;
            $studentDetails->attendanceDetails = reset(AttendanceService::getInstance()->getTermWiseStudentAttendanceConfirmedReport($attendanceTermWiseReportRequest));
            if($showGenderWiseAttendance){
                $studentDetails->examRegistrationProperties->minimumAttendancePercentage = $studentDetails->examRegistrationProperties->genderWiseMinimumAttendance[strtoupper($studentDetails->studentGender)];
            }
            $studentDetails->isShortageAttendance  = $studentDetails->examRegistrationProperties->minimumAttendancePercentage > $studentDetails->attendanceDetails->attendancePercentage ? true : false;
            if($studentDetails->isShortageAttendance && !$request->notConsiderValidation){
                $studentDetails->canApplyExamByRegularType = false;
                $studentDetails->blockReasons = ['Attendance Shortage'];
                // throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Attendance Shortage");
            }
        }
        elseif(empty($studentDetails->subjects) && empty($studentDetails->eligibleSubjectForCondonation)  && !$request->notConsiderValidation){
            throw new ExamControllerException (ExamControllerException::INVALID_PARAMETERS,"Couldnot Register Exam");
        }
        return($studentDetails); 
    }
    
    /**
     * Save Mooc Exam Registration Certificate Status
     * @param Object $request
     * @author Krishnajith V
     */
    public function saveMoocExamRegistrationCertificateStatus($request){
        $request = $this->realEscapeObject($request);
        if ($request->assessmentId && $request->studentId && $request->certificateStatus) {
            try {
                $certificateStatus = "'".$request->certificateStatus."'";
                $sql = "UPDATE ec_student_assessment_registration SET properties = JSON_SET(properties, '$.moocCertificateStatus',$certificateStatus) WHERE am_assessment_id = '$request->assessmentId' AND student_id = '$request->studentId'";
                $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ExamControllerException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     * get All Registered Student Exam Registration Details With Result
     * @param $request
     * @return studentDetails
     */
    public function getStudentRegisteredExamRegistrationWithResultDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            $whereQuery = "";
            $sortBy = " ORDER BY eer.created_date DESC ";
            if($request->isHonourExamOnly){
                $whereQuery .= " AND eer.properties ->> '$.isHonorCourse' = '1' ";
            }
            if($request->isMinorExamOnly){
                $whereQuery .= " AND eer.properties ->> '$.isMinorCourse' = '1' ";
            }
            if(!empty($request->studentId)){
                $studentIdString = is_array($request->studentId) ? "'" . implode("','",$request->studentId) . "'" : "'".$request->studentId."'";
                $whereQuery .= " AND spa.student_id IN ( $studentIdString )";
            }
            $mapperForRegistrationDetails = StudentExamRegistrationServiceMapper::SEARCH_EXAM_REGISTRATION_WITH_RESULT ;
            $query = "SELECT 
                        s.studentID as studentId,
                        s.studentName as studentName,
                        spa.properties->>'$.registerNumber' AS registerNo,
                        eer.id as examRegistrationId,
                        eer.name as examRegistrationName,
                        eer.type as examRegistrationType,
                        eer.properties as examRegistrationProperties,
                        ecmdcourse.failed_status as courseFailedStatus,
                        ecmdcourse.mark_details as courseMarkDetails,
                        act.id as academicTermId,
                        act.name as academicTermName,
                        act.properties->>'$.orderNo' AS academicTermOrderNo,
                        esmd.mark_details as semesterMarkDetails,
                        esar.properties as assessmentRegistrationProperties,
                        caps.id as academicPaperSubjectId,
                        sub.code as subjectCode,
                        sub.name as subjectName,
                        ecsmd.failed_status as subjectFailedStatus,
                        ecsmd.mark_details as subjectMarkDetails
                    FROM studentaccount s 
                    INNER JOIN student_program_account spa ON
                        spa.student_id = s.studentID 
                    INNER JOIN group_members gm ON
                        CAST(gm.members->>'$.studentId' AS CHAR) = spa.id AND
                        gm.academic_status IN ('ACTIVE') 
                    INNER JOIN `groups` sg ON     
                        sg.id = gm.groups_id AND
                        sg.`type` = 'SUBJECT'    
                    INNER JOIN groups_relations gr ON 
                        gr.child_groups_id = sg.id
                    INNER JOIN `groups` bg ON 
                        bg.id = gr.parent_groups_id AND
                        bg.type = 'BATCH'
                    INNER JOIN cm_academic_paper_subjects caps ON
                        caps.id = sg.paperSubjectId 
                    INNER JOIN v4_ams_subject sub ON
                        sub.id = caps.ams_subject_id
                    INNER JOIN ec_exam_registration_subject eers ON
                        eers.cm_academic_paper_subjects_id = caps.id 
                    INNER JOIN ec_exam_registration_batch eerb ON     
                        eerb.id = eers.ec_exam_registration_batch_id AND
                        eerb.groups_id = bg.id 
                    INNER JOIN ec_exam_registration eer ON 
                        eer.id = eerb.ec_exam_registration_id 
                    INNER JOIN  academic_term act ON 
                        act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR) AND 
                        act.type = 'SEMESTER'
                    LEFT JOIN ec_student_assessment_registration esar ON 
                        esar.am_assessment_id = eers.am_assessment_id AND
                        esar.student_id = s.studentID AND
                        esar.properties ->> '$.registrationStatus' IN ('REGISTERED')
                    LEFT JOIN ec_consolidated_subject_mark_details ecsmd ON
                        ecsmd.cm_academic_paper_subjects_id = caps.id AND
                        ecsmd.student_id = s.studentID 
                    LEFT JOIN ec_semester_mark_details esmd ON
                        esmd.groups_id = eerb.groups_id AND 
                        esmd.academic_term_id = act.id AND 
                        esmd.student_id = s.studentID 
                    LEFT JOIN  ec_course_mark_details ecmdcourse ON
                        ecmdcourse.groups_id = eerb.groups_id AND 
                        ecmdcourse.student_id = s.studentID
                    WHERE 1 = 1 ";
            $studentDetails = $this->executeQueryForList($query.$whereQuery.$sortBy.$limitQuery,$this->mapper[$mapperForRegistrationDetails]);
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        return $studentDetails;
    }
      /**
     * Get Block Unblock Student Details
     * @param Object $request
     */
    public function getBlockedUnblockedSubjectDetails($request){
        $request = $this->realEscapeObject($request);
        try {
            $sql = "SELECT 
                        eers.cm_academic_paper_subjects_id as academicPaperSubjectsId, 
                        blockStd.id as blockStudentTableId,
                        embus.id as unBlockStudentTableId
                        FROM
                            ec_exam_registration eer
                        INNER JOIN ec_exam_registration_batch eerb ON
                            eerb.ec_exam_registration_id = eer.id 
                        INNER JOIN ec_exam_registration_subject eers ON
                            eers.ec_exam_registration_batch_id = eerb.id
                        LEFT JOIN ec_malpractice_block_unblock_students blockStd ON 
                            blockStd.type = 'BLOCK' AND blockStd.cm_academic_paper_subjects_id = eers.cm_academic_paper_subjects_id
                        LEFT JOIN ec_malpractice_block_unblock_students embus ON 
                            embus.student_id = blockStd.student_id AND embus.am_assessment_id = eers.am_assessment_id AND embus.ec_exam_registration_id = eer.id AND embus.type = 'UN_BLOCK'
                    WHERE 
                        blockStd.student_id = '$request->studentId' AND eer.id = '$request->examRegistrationId";
            $blockedUnblockedSubjectDetails = (array)$this->executeQueryForList($sql);
            $blockedUnblockedSubject = [];
            foreach($blockedUnblockedSubjectDetails as $subject){
                $blockedUnblockedSubject[$subject->academicPaperSubjectsId] = $subject;
            }
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $blockedUnblockedSubject;
    }
    /**
     * Check And Update Student Payment Status
     * @param Object $request
     */
    public function checkAndUpdateAllStudentPaymentStatus($request){
        $request = $this->realEscapeObject($request);
        try {
            $searchRequest = new \stdClass;
            $searchRequest->examRegistrationId = $request->examRegistrationId;
            $searchRequest->academicTermId = $request->academicTermId;
            $searchRequest->departmentId = $request->departmentId;
            $searchRequest->groupId = $request->groupId;
            $searchRequest->registerNo = $request->registerNo;
            $studentList = $this->getOnlineAppliedStudentDetails($searchRequest);
            if(empty($studentList)){
                throw new ExamControllerException(ExamControllerException::NO_DETAILS_FOUND,"Empty applicable student(s) "); 
            }
            foreach ($studentList as $student) {
                $searchRequest->studentId = $student->studentId;
                $searchRequest->examRegistrationId = $student->examRegistrationId;
                foreach ($student->onlinePayments as $transactionDetail) {
                    try {
                        $txnId = $transactionDetail->txnID;
                        $studentOnlinePaymentRequest = new StudentOnlinePaymentRequest();
                        $studentOnlinePaymentRequest->studentId = $student->studentId;
                        $studentOnlinePaymentRequest->module = "STUDENT_FEES";
                        $studentOnlinePaymentRequest->category = "EXAM_REGISTRATION";
                        $studentOnlinePaymentRequest->linwaysTransactionId = $txnId;
                        $studentOnlinePaymentRequest->examRegId = $student->examRegistrationId;
                        $studentOnlinePaymentRequest->isBrowserRedirected = 0;
                        $studentOnlinePaymentRequest->amount = $transactionDetail->amount;
                        $paymentStatusResponse = StudentPaymentService::getInstance()->getOnlinePaymentTransactionStatus($studentOnlinePaymentRequest);
                        //set enquiry response
                        $decryptedPaymentResponse = $paymentStatusResponse;
                        $status = $decryptedPaymentResponse['status'];
                        // Payment gateway transaction id
                        $paymentGatewayTxnId = $decryptedPaymentResponse['paymentGatewayTxnId'];
                        // Linways transaction id
                        $clientTxnId = $decryptedPaymentResponse['clientTxnId'];
                        $enquiryLinwaysTxnId = $decryptedPaymentResponse['enquiryLinwaysTxnId'];
                        $error = $decryptedPaymentResponse['error'];
                        if ($status == PaymentGateway::PAYMENT_SUCCESS) {
                            $saveOnlinePaymentStatus = new \stdClass;
                            $saveOnlinePaymentStatus->id = $transactionDetail->id;
                            $saveOnlinePaymentStatus->studentId =   $student->studentId;
                            $saveOnlinePaymentStatus->txnID = $clientTxnId;
                            $saveOnlinePaymentStatus->status = "SUCCESS";
                            $saveOnlinePaymentStatus->amount = $transactionDetail->amount;
                            $saveOnlinePaymentStatus->transactionDate = date("Y-m-d H:i:s"); 
                            $saveOnlinePaymentStatus->type = "STUDENT_EXAM_REGISTRATION";
                            $saveOnlinePaymentStatus->paymentGateWayTransactionId = $paymentGatewayTxnId;
                            $saveOnlinePaymentStatus->properties = json_decode($transactionDetail->properties);
                            $this->saveStudentRegistrationOnlinePaymentStatus($saveOnlinePaymentStatus);
                            $saveExamRegistrationTotalFee = new StudentExamRegistrationDetails();
                            $saveExamRegistrationTotalFee->studentId =  $student->studentId;
                            $saveExamRegistrationTotalFee->examRegistrationId = $student->examRegistrationId;
                            $saveExamRegistrationTotalFee->totalFee = $transactionDetail->amount;
                            $saveExamRegistrationTotalFee->properties = null;
                            $examRegistrationTotalFeeProperties = new \stdClass;
                            $examRegistrationTotalFeeProperties->paymentOption =  ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD;
                            $examRegistrationTotalFeeProperties->onlinePaymentStatus = StudentExamRegistrationOnlinePaymentStatus::SUCCESS;
                            $examRegistrationTotalFeeProperties->onlinePaymentTransactionDate =  date("Y-m-d H:i:s");
                            $examRegistrationTotalFeeProperties->clientTxnId = $clientTxnId; 
                            $examRegistrationTotalFeeProperties->paymentGatewayTxnId = $paymentGatewayTxnId;
                            $saveExamRegistrationTotalFee->properties = $examRegistrationTotalFeeProperties;
                            $saveExamRegistrationTotalFee->createdBy =  $student->studentId;
                            $saveExamRegistrationTotalFee->updatedBy =  $student->studentId;
                            $this->saveStudentExamRegistrationDetails($saveExamRegistrationTotalFee);
                            foreach($student->subjects as $subject){
                                $studentRegistration = new StudentRegistration();
                                $studentRegistration->id = $subject->studentAssessmentId;
                                $studentRegistration->assessmentId = $subject->assessmentId;
                                $studentRegistration->studentId = $student->studentId;
                                $studentRegistration->examRegistrationType = $subject->registrationType;
                                $studentAssessmentProperties = json_decode($subject->studentAssessmentProperties);
                                $studentRegistration->createdBy = $student->studentId;
                                $studentRegistration->updatedBy = $student->studentId;
                                
                                $studentAssessmentProperties->feeStatus = StudentExamRegistrationPaymentStatus::PAID;
                                $studentAssessmentProperties->registrationStatus = StudentExamRegistrationStatus::REGISTERED;
                                $studentAssessmentProperties->paymentOption =  ExamPaymentMethodConstants::ONLINE_PAYMENT_METHOD;
                                $studentAssessmentProperties->registeredDate = date("Y-m-d");
                                $studentAssessmentProperties->dateOfPay = date("Y-m-d");
                                $studentRegistration->properties = $studentAssessmentProperties;
                                $this->saveStudentRegistration($studentRegistration);
                            }
                        }
                    }catch (\Exception $e) {
                        continue;
                    }
                }
            }
           
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get Online Applied Student Details 
     * @param Object $request
     */
    public function getOnlineAppliedStudentDetails($request){
        $request = $this->realEscapeObject($request);
        try {
            $whereQuery = "";
            if(!empty($request->registerNo)){
                $whereQuery .= " AND spa.properties->>'$.registerNumber' = '$request->registerNo'";
            }
            if(!empty($request->groupId)){
                $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if(!empty($request->academicTermId)){
                $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
                $whereQuery .= " AND eerb.properties ->> '$.academicTermId' IN ( $academicTermIdString )";
            }
            if(!empty($request->departmentId)){
                $departmentIdString = is_array($request->departmentId) ? "'" . implode("','",$request->departmentId) . "'" : "'".$request->departmentId."'";
                $whereQuery .= " AND g.properties ->> '$.departmentId' IN ( $departmentIdString )";
            }
            if(!empty($request->examRegistrationId)){
                $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
                $whereQuery .= " AND eerb.ec_exam_registration_id IN ( $examRegistrationIdString )";
            }
            $sql = "SELECT DISTINCT 
                    esar.student_id AS studentId,
                    eserd.ec_exam_registration_id AS examRegId,
                    esar.am_assessment_id AS assessmentId,
                    esar.id AS studentAssessmentId,
                    esar.properties AS studentAssessmentProperties,
                    esar.ec_exam_registration_type  AS registrationType,
                    eop.id as onlinePaymentTableId,
                    eop.txnID as txnID,
                    eop.status as onlinePaymentStatus,
                    eop.amount as amount,
                    eop.transactionDate as transactionDate,
                    eop.type as paymentType,
                    eop.payment_gateway_txn_id as paymentGatewayTxnId,
                    eerb.ec_exam_registration_id as examRegistrationId,
                    eop.properties as properties
                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 academic_term act ON 
                    act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
                INNER JOIN `groups` g ON
                    g.id = eerb.groups_id
                    AND g.`type` = 'BATCH'
                INNER JOIN ec_student_exam_registration_details eserd ON 
                    eserd.student_id = esar.student_id AND 
                    eserd.ec_exam_registration_id = eerb.ec_exam_registration_id
                INNER JOIN student_program_account spa ON 
                    spa.student_id  = esar.student_id
                INNER JOIN ec_online_payment eop ON
                    eop.studentID = esar.student_id AND eop.properties->>'$.examRegistrationId' = eerb.ec_exam_registration_id
                WHERE     
                    esar.properties->>'$.paymentOption' = 'ONLINE_PAYMENT_METHOD' AND 
                    esar.properties->>'$.feeStatus' = 'PENDING' AND 
                    esar.properties->>'$.registrationStatus' = 'APPLIED' AND 
                    esar.ec_exam_registration_type IN ('REGULAR', 'SUPPLEMENTARY') ";
            $studentData = (array)$this->executeQueryForList($sql.$whereQuery);
            $studentList = [];
            foreach($studentData as $student){
                $studentList[$student->studentId.$student->examRegistrationId]->studentId = $student->studentId;
                $studentList[$student->studentId.$student->examRegistrationId]->examRegistrationId = $student->examRegistrationId;
                $studentList[$student->studentId.$student->examRegistrationId]->onlinePayments[$student->onlinePaymentTableId]->id = $student->onlinePaymentTableId;
                $studentList[$student->studentId.$student->examRegistrationId]->onlinePayments[$student->onlinePaymentTableId]->txnID = $student->txnID;
                $studentList[$student->studentId.$student->examRegistrationId]->onlinePayments[$student->onlinePaymentTableId]->status = $student->onlinePaymentStatus;
                $studentList[$student->studentId.$student->examRegistrationId]->onlinePayments[$student->onlinePaymentTableId]->amount = $student->amount;
                $studentList[$student->studentId.$student->examRegistrationId]->onlinePayments[$student->onlinePaymentTableId]->transactionDate = $student->transactionDate;
                $studentList[$student->studentId.$student->examRegistrationId]->onlinePayments[$student->onlinePaymentTableId]->type = $student->paymentType;
                $studentList[$student->studentId.$student->examRegistrationId]->onlinePayments[$student->onlinePaymentTableId]->paymentGatewayTxnId = $student->paymentGatewayTxnId;
                $studentList[$student->studentId.$student->examRegistrationId]->onlinePayments[$student->onlinePaymentTableId]->examRegistrationId = $student->examRegistrationId;
                $studentList[$student->studentId.$student->examRegistrationId]->onlinePayments[$student->onlinePaymentTableId]->properties = json_decode($student->properties);
                $studentList[$student->studentId.$student->examRegistrationId]->subjects[$student->assessmentId]->studentId = $student->studentId;
                $studentList[$student->studentId.$student->examRegistrationId]->subjects[$student->assessmentId]->assessmentId = $student->assessmentId;
                $studentList[$student->studentId.$student->examRegistrationId]->subjects[$student->assessmentId]->studentAssessmentId = $student->studentAssessmentId;
                $studentList[$student->studentId.$student->examRegistrationId]->subjects[$student->assessmentId]->registrationType = $student->registrationType;
                $studentList[$student->studentId.$student->examRegistrationId]->subjects[$student->assessmentId]->studentAssessmentProperties = json_decode($student->studentAssessmentProperties);
                $studentList[$student->studentId.$student->examRegistrationId]->subjects[$student->assessmentId]->studentId = $student->studentId;
                $studentList[$student->studentId.$student->examRegistrationId]->subjects[$student->assessmentId]->studentId = $student->studentId;
            }
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $studentList;
    }
     /**
     * get Student Details For Exam Registration 
     * @param $request
     * @return $students
     */
    public function getStudentExamRegistrationDetails($request){
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $students = [];
        if(!empty($request->studentId)) {
            $whereQuery .= " AND sa.studentID = '$request->studentId";
        }
        if(!empty($request->groupId)){
            $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
            $whereQuery .= " AND g.id IN ( $groupIdString )";
        }
        $groupBy = "  GROUP BY sa.studentID , eer.id ";
        $query = "SELECT DISTINCT
            sa.studentID as studentId,
            eer.id AS examRegistrationId,
            eer.name AS examRegistrationName,
            eer.type AS examType,
            eerb.properties AS examRegistrationProperties,
            eerb.properties AS batchProperties,
            eerb.properties AS batchProperties,
            eerb.properties ->>'$.isResultPublished' as isBatchResultPublished,
            esbrm.ec_block_student_reason_id as blockStudentReasonId,
            ebsr.name as blockReasonName,
            cpsa.staffName as contactPersonName,
            ebsr.properties ->> '$.description' AS contactPersonDecription,
            esad.properties->>'$.withHeldStatus' as withHeldStatus,
            eserd.properties ->>'$.isResultWithHeld' AS isResultWithHeld
        FROM
            `groups` g
        INNER JOIN ec_exam_registration_batch eerb ON
            eerb.groups_id = g.id
        INNER JOIN program p ON
            p.id = g.properties ->> '$.programId'
        INNER JOIN ec_exam_registration eer ON
            eer.id = eerb.ec_exam_registration_id
        INNER JOIN student_program_account spa ON spa.current_program_id  = p.id
            INNER JOIN studentaccount sa ON
                sa.studentID = spa.student_id
        INNER JOIN ec_student_exam_registration_details eserd ON
            eserd.student_id = sa.studentID AND 
            eserd.ec_exam_registration_id = eer.id 
        INNER JOIN ec_internal_marks eim ON eim.groups_id = g.id 
            AND eim.academic_term_id = eerb.academicTermId 
            AND eim.student_id = sa.studentID 
        LEFT JOIN ec_student_block_reason_mapping esbrm ON
            esbrm.student_id = sa.studentID AND esbrm.exam_registration_id = eer.id AND
            esbrm.blocking_type = 'RESULT_BLOCKING'
        LEFT JOIN ec_block_student_reason ebsr ON 
            ebsr.id = esbrm.ec_block_student_reason_id AND
            ebsr.type = 'SEMESTER_WISE'
        LEFT JOIN staffaccounts cpsa ON 
            cpsa.staffID = ebsr.contact_person_id 
        LEFT JOIN ec_student_additional_details esad ON 
            esad.student_id = sa.studentID AND
            esad.program_id = p.id AND
            esad.type = 'FINAL_MARK_CARD' 
        WHERE
            eer.trashed IS NULL ";
        try {
            $studentExamRegistrationDetails = $this->executeQueryForList($query.$whereQuery.$groupBy);
            foreach( $studentExamRegistrationDetails as $stdentExams){
                $stdentExams->examRegistrationProperties = json_decode($stdentExams->examRegistrationProperties);
                $stdentExams->batchProperties = json_decode($stdentExams->batchProperties);
                $stdentExams->isResultBlocked = !empty($stdentExams->blockStudentReasonId) ? true : false;
                $stdentExams->isResultWithHeld = $stdentExams->isResultWithHeld ? true : false;
                $students[$stdentExams->studentId]->id = $stdentExams->studentId;
                $students[$stdentExams->studentId]->withHeldStatus = $stdentExams->withHeldStatus ? true : false;
                $students[$stdentExams->studentId]->exams[$stdentExams->examRegistrationId] = $stdentExams;
            }
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student.");
        }
        return $students;
    }
    /**
     * Get Student Exam Application Form
     * @param $request
     */
    public function  getStudentExamApplicationForm($request){
        $examType = 'EC_EXAM_APPLICATION_FORM_TEMPLATE';
        $applicationFormTemplate = StudentMarkListService::getInstance()->getUniversityMarkListTemplate($examType);
        $searchExamRuleRequest = new SearchRuleRequest;
        $searchExamRuleRequest->name = 'EXAM_REGISTRATION_CREATION_RULE';
        $ruleObj = reset(RuleService::getInstance()->searchRule($searchExamRuleRequest));
        $searchRequest = new \stdClass();
        $searchRequest->studentId = $request->studentId;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->registrationStatus = StudentExamRegistrationStatus::REGISTERED;
        $studentDetails = reset($this->getStudentExamRegistrationFeeDetails($searchRequest));
        $studentDetails->birthday = $studentDetails->birthday ?  date("d-m-Y", strtotime( $studentDetails->birthday)) : "";
        $studentDetails->dateofPay = "";
        $studentDetails->paymentMethod = "Back end Method";
        $studentDetails->registrationType = reset($studentDetails->subjects)->studentAssessmentRegistrationProperties->registrationType;
        if($studentDetails->examRegistrationPaymentProperties->paymentOption =="ONLINE_PAYMENT_METHOD"){
            $studentDetails->paymentMethod = "Online Method";
            $studentDetails->linwaysTxnId = $studentDetails->examRegistrationPaymentProperties->clientTxnId;
            $studentDetails->transactionDate =  date("d-m-Y h:i A", strtotime( $studentDetails->examRegistrationPaymentProperties->onlinePaymentTransactionDate));
        }
        else if ($studentDetails->examRegistrationPaymentProperties->paymentOption =="COLLEGE_CHALLAN_METHOD"){
            $studentDetails->paymentMethod = "College Challan";
            $studentDetails->transactionDate = $studentDetails->examRegistrationPaymentProperties->challanVerifyDate ? date("d-m-Y h:i A", strtotime( $studentDetails->examRegistrationPaymentProperties->challanVerifyDate)) : "";
        }
        $studentDetails->today =  date("d-m-Y");
        $studentDetails->examMonthName = ExamRegistrationService::getInstance()->getMonthName($studentDetails->examRegistrationProperties->examMonth);
        $studentDetails->examYear = $studentDetails->examRegistrationProperties->examYear;
        $studentDetails->isAppliedSubjectsOnly = $request->isAppliedSubjectsOnly == '1' ? true : false;
        //get reservation of student
        $studentDetails->reservationDetails = $studentDetails->reservationID ? ReservationStudentsService::getInstance()->getReservationById($studentDetails->reservationID):"";
        if($ruleObj->rule->feeConcessionReservationCodes && $studentDetails->reservationDetails->reservationCode){
            $ruleObj->rule->feeConcessionReservationCodes = json_decode($ruleObj->rule->feeConcessionReservationCodes);
            if(in_array($studentDetails->reservationDetails->reservationCode,$ruleObj->rule->feeConcessionReservationCodes)){
                $studentDetails->eligibleForFeeConcession = true;
            }
        }
        //Get student Applied fee details --CURRENTLY HANDLED FOR REGULAR OTHERS NOT TETSTED
        $feeRequest = new \stdClass;
        $feeRequest->examRegistrationId = $request->examRegistrationId;
        $feeRequest->examRegistrationType = $studentDetails->registrationType;
        $feeRequest->studentId = $request->studentId;
        $feeRequest->isStudentSideRequest = 1;
        $feeRequest->removeSubjectFeeForNotApplied = true;
        $feeRequest->registrationStatus =  "REGISTERED_AND_APPLIED";
        $feeRequest->notConsiderEmptyValidation = true;
        $feeRequest->considerRegisteredAndApplied =   true;
        $feeRequest->notConsiderValidation = true;
        $feeRequest->hideAlreadyExistCheck = true;
        $feeRequest->considerAppliedSubjectsFeesOnly = true;
        $studentDetails->appliedFeeDetails = $this->getStudentExamRegistrationSubjectFeeDetails($feeRequest);
        $reguestForBatchStudents = new \stdClass();
        $reguestForBatchStudents->studentId = $studentDetails->studentId;
        $reguestForBatchStudents->groupId = $studentDetails->groupId;
        $studentAdditionalDetails = reset(CommonExamService::getInstance()->getStudentsDetailsByBatchProgram($reguestForBatchStudents));
        $studentDetails->religionCasteCombination = $studentAdditionalDetails->religionCasteCombination;
        $studentDetails->studentImage  = StudentService::getInstance()->getStudentProfilePic($studentDetails->studentId)->docpath;
        $studentDetails->studentSignature  = StudentService::getInstance()->getStudentSignPic($studentDetails->studentId)->docpath;
            if($studentDetails->challanNo){
                $barcodeObj = new TCPDFBarcode( $studentDetails->registrationType.$studentDetails->challanNo , 'C128');
                $studentDetails->barcode = $barcodeObj->getBarcodeHTML($w = 1, $h = 40, $color = 'black');
            }
            $studentDetails->registerNo = (!$studentDetails->registerNo || $studentDetails->registerNo === "null") ? "" : $studentDetails->registerNo;
            $collegeData = CommonExamService::getInstance()->getCollegeDetails();
            $templateName = "ExamApplicationFormTemplate1";
            if($applicationFormTemplate == 'Template_19'){
                $templateName = "ExamApplicationFormTemplate19";
            }
            else if($applicationFormTemplate == 'Template_3'){
                $templateName = "ExamApplicationFormTemplate3";
            }
            else if($applicationFormTemplate == 'Template_2'){
                $templateName = "ExamApplicationFormTemplate2";
            }
            else if($applicationFormTemplate == 'Template_4'){
                $templateName = "ExamApplicationFormTemplate4";
            }
            else if($applicationFormTemplate == 'Template_5'){
                $templateName = "ExamApplicationFormTemplate5";
            }
            else if($applicationFormTemplate == 'Template_24'){
                $templateName = "ExamApplicationFormTemplate24";
            }
            $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/ExamApplicationForm/$templateName.twig"), [ 'data'=>$studentDetails,'college'=>$collegeData ]);
            $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                
                </style>";
            $prtContent .= '</head><title>Exam Application Form </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' => "10mm",
                'margin-right' => "10mm",
                '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;
    }
    /**
     * used to set student additional profile details
     * @param $studentDetails
     * @return $studentDetails
     */
    private function setStudentAdditonalProfileDetails($studentDetails){
        $studentPofileDetails = current(AmStudentService::getInstance()->getStudentDetailsByStudentId($studentDetails->id));
        if($studentPofileDetails){
            $studentDetails->guardianName = $studentPofileDetails->guardianName;
            $studentDetails->guardianName = $studentDetails->guardianName ? $studentDetails->guardianName :$studentPofileDetails->fatherName;
            $studentDetails->guardianName = $studentDetails->guardianName ? $studentDetails->guardianName :$studentPofileDetails->motherName;
            $studentBatch = current(array_filter($studentPofileDetails->batchDetails, function($batch) use ($studentDetails) {
                return $batch->studentProgramId == $studentDetails->studentProgramAccountId;
            }));
            $studentDetails->gender = $studentPofileDetails->gender;
            $studentDetails->admissionNo = $studentPofileDetails->admissionNo;
            $studentDetails->programName = $studentBatch->programName;
            $studentDetails->batchName = $studentBatch->batchName;
        }
        return $studentDetails;
    }
    /**
     * Get Student Exam Registration Fee Details
     * @param $request
     * @return $studentDetails
     */
    public function removeStudentRegistrationStatusFromFailedToUnpaid($request){
        $request = $this->realEscapeObject($request);
        if ($request->examRegistrationId && $request->studentId) {
            try {
                $sql = "UPDATE 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 
                SET esar.properties = JSON_SET(esar.properties, '$.feeStatus','UN_PAID', '$.registrationStatus', 'NOT_REGISTERED') 
                WHERE 
                    esar.properties->>'$.registrationStatus' = 'APPLIED' AND 
                    esar.student_id = '$request->studentId' AND 
                    eerb.ec_exam_registration_id = '$request->examRegistrationId'";
                $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ExamControllerException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     * Remove Student Registration Status From Failed To Unpaid Revaluation
     * @param $request
     * @return $studentDetails
     */
    public function removeStudentRegistrationStatusFromFailedToUnpaidRevaluation($request){
        $request = $this->realEscapeObject($request);
        if ($request->examRegistrationId && $request->studentId) {
            try {
                $sql = "UPDATE 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
                INNER JOIN ec_exam_registration eerRevaluation ON
                    eer.id = eerRevaluation.properties->>'$.parentExamRegistrationId' AND 
                    eerRevaluation.trashed IS NULL
                SET esar.properties = JSON_SET(esar.properties, '$.feeStatus','UN_PAID', '$.registrationStatus', 'NOT_REGISTERED') 
                WHERE 
                    esar.properties->>'$.registrationStatus' = 'APPLIED' AND 
                    esar.student_id = '$request->studentId' AND 
                    eerRevaluation.id = '$request->examRegistrationId' AND
                    esar.ec_exam_registration_type = eerRevaluation.type AND 
                    esar.identifying_context->>'$.examRegistrationId' = eerRevaluation.id ";
                $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ExamControllerException($e->getCode(), $e->getMessage());
            }
        }
    }
    private function setPageSize($width,$hieght){
        $pageSize = new \stdClass;
        $pageSize->width = $width;
        $pageSize->height = $hieght;
        return $pageSize;
    }
    /**
     * Get StudentsIds by Registration 
     ** @param $request
     * @return $studentDetails
     */
    public function getAllStudentIdsByExamRegistration($request){
        try{
            $request = $this->realEscapeObject($request);
            $whereQuery = "";
            $joinQueary = "";
            $sortBy = " ORDER BY spa.properties->>'$.registerNumber' ASC";
            if(!empty($request->examRegistrationId)){
                $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            if($request->examType == ExamRegistrationTypeConstants::SUPPLEMENTARY){
                $joinQueary .= " INNER JOIN ec_semester_mark_details esmdsem ON
                                    esmdsem.groups_id = eerb.groups_id 
                                    AND esmdsem.academic_term_id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
                                INNER JOIN student_program_account spa ON 
                                    spa.student_id =  esmdsem.student_id
                                INNER JOIN studentaccount sa ON
                                    sa.studentID = spa.student_id
                                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 = spa.student_id ";
            }
            else{
                if($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::APPLIED){
                    $joinQueary .= " ";
                }else{
                    $joinQueary .= " INNER JOIN group_members gm ON
                                    gm.groups_id = g.id
                                INNER JOIN student_program_account spa ON 
                                    spa.id  = gm.members->>'$.studentId'
                                INNER JOIN studentaccount sa ON
                                    sa.studentID = spa.student_id
                                INNER JOIN student_program_batch_log spbl ON
                                    spbl.batch_group_id = g.id AND
                                    spbl.term_id = eerb.properties ->> '$.academicTermId' AND
                                    spbl.program_student_id = spa.id 
                                    AND spbl.properties->>'$.academicStatus' IN ('ACTIVE','COMPLETED')
                                INNER JOIN `groups` sg ON
                                    sg.paperSubjectId = caps.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') ";
                }
            }
            if(!empty($request->registrationStatus)){
                if($request->examType == ExamRegistrationTypeConstants::SUPPLEMENTARY && ($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::APPLIED)){
                    $joinQueary .= " INNER JOIN ec_student_assessment_registration esar ON
                            esar.student_id = spa.student_id AND esar.am_assessment_id = eers.am_assessment_id AND esar.ec_exam_registration_type = eer.type 
                            INNER JOIN ec_student_exam_registration_details eserd ON
                            eserd.student_id = esar.student_id AND eserd.ec_exam_registration_id = eer.id";
                    $whereQuery .= $request->registrationStatus == StudentExamRegistrationStatus::REGISTERED ? " AND esar.properties ->> '$.registrationStatus' = 'REGISTERED' AND esar.properties ->> '$.feeStatus' = 'PAID'" : " AND esar.properties ->> '$.registrationStatus' = 'APPLIED'";
                }
                else if($request->examType == ExamRegistrationTypeConstants::REGULAR && ($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::APPLIED)){
                    $joinQueary .= " INNER JOIN ec_student_assessment_registration esar ON
                            esar.am_assessment_id = eers.am_assessment_id AND esar.ec_exam_registration_type = eer.type 
                            INNER JOIN ec_student_exam_registration_details eserd ON
                            eserd.student_id = esar.student_id AND eserd.ec_exam_registration_id = eer.id";
                    $whereQuery .= $request->registrationStatus == StudentExamRegistrationStatus::REGISTERED ? " AND esar.properties ->> '$.registrationStatus' = 'REGISTERED' AND esar.properties ->> '$.feeStatus' = 'PAID'" : " AND esar.properties ->> '$.registrationStatus' = 'APPLIED'";
                }
                else{
                    $joinQueary .= " LEFT JOIN ec_student_assessment_registration esar ON
                        esar.student_id = sa.studentID AND  esar.am_assessment_id = eers.am_assessment_id AND esar.properties ->> '$.registrationStatus' IN ('REGISTERED','APPLIED') AND esar.ec_exam_registration_type = eer.type ";
                    $whereQuery .= " AND esar.id IS NULL";
                }
            }
            if($request->examType == ExamRegistrationTypeConstants::REGULAR && ($request->registrationStatus == StudentExamRegistrationStatus::REGISTERED || $request->registrationStatus == StudentExamRegistrationStatus::APPLIED)){
                $joinQueary .= " INNER JOIN student_program_account spa ON 
                                spa.student_id  = eserd.student_id AND spa.current_batch_id = g.id";
            }
            if(!empty($request->groupId)){
                $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if(!empty($request->academicTermId)){
                $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
                $whereQuery .= " AND eerb.properties ->> '$.academicTermId' IN ( $academicTermIdString )";
            }
            if(!empty($request->departmentId)){
                $departmentIdString = is_array($request->departmentId) ? "'" . implode("','",$request->departmentId) . "'" : "'".$request->departmentId."'";
                $whereQuery .= " AND g.properties ->> '$.departmentId' IN ( $departmentIdString )";
            }
            $query = "SELECT DISTINCT
                spa.student_id as studentId
            FROM
                ec_exam_registration eer
            INNER JOIN ec_exam_registration_batch eerb ON
                eerb.ec_exam_registration_id = eer.id 
            INNER JOIN `groups` g ON
                g.id = eerb.groups_id
                AND g.`type` = 'BATCH' 
            INNER JOIN ec_exam_registration_subject eers ON
                eers.ec_exam_registration_batch_id = eerb.id
            INNER JOIN cm_academic_paper_subjects caps ON
                caps.id = eers.cm_academic_paper_subjects_id
            $joinQueary 
            WHERE
                eer.trashed IS NULL ";
            $studentDetails = $this->executeQueryForList($query.$whereQuery.$sortBy);
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        return $studentDetails;
    }
    /**
     * Get Student Exam Registration For Hall Ticket
     * @param $request
     * @return $studentExamRegistrationDetails
     */
    public function getExamRegistrationForHallTicket($request){
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        if(!empty($request->studentId)) {
            $whereQuery .= " AND spa.student_id = '$request->studentId";
        }
        if(!empty($request->examType)){
            $examTypeString = is_array($request->examType) ? "'" . implode("','",$request->examType) . "'" : "'".$request->examType."'";
            $whereQuery .= " AND eer.type IN ( $examTypeString )";
        }
        $groupBy = " GROUP BY eer.id";
        $query = "SELECT eer.id, eer.name FROM ec_exam_registration eer 
            INNER JOIN ec_exam_registration_batch eerb ON 
                eerb.ec_exam_registration_id = eer.id 
            INNER JOIN ec_exam_registration_subject eers ON 
                eers.ec_exam_registration_batch_id = eerb.id 
            INNER JOIN ec_student_assessment_registration esar ON 
                esar.am_assessment_id = eers.am_assessment_id 
            INNER JOIN student_program_account spa ON 
                spa.student_id = esar.student_id 
            WHERE 
                esar.properties ->>'$.registrationStatus'='REGISTERED' AND 
                eer.properties->>'$.enableHallTicketExamStudent' = 1";
        try {
            $studentExamRegistrationDetails = $this->executeQueryForList($query.$whereQuery.$groupBy);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student.");
        }
        return $studentExamRegistrationDetails;
    }
    /**
     * @author Sibin
     * get student exam room details
     */
    public function getStudentRoomDetails($request)
    {
        $request = $this->realEscapeObject($request);
        $identifier = $request->identifier;
        $entryType = $request->entryType;
        $userType = $request->userType;
        $identifierType = $request->identifierType;
        $groupBy = "";
        if($request->groupByRooms){
            $groupBy = " GROUP BY properties->>'$.roomNo'";
        }
        $sql = "SELECT properties->>'$.roomNo' AS roomNo,userId FROM subjectWiseSubmissions WHERE identifierType ='$identifierType' AND userType ='$userType' AND entryType ='$entryType' and identifier ='$identifier$groupBy";
        try {
           return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return false;
    }
      /**
     * get Registered Student Exam Registration Details
     * @param $request
     * @return examRegistration
     */
    public function getRegisteredStudentExamRegistrationDetails($request){
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        if($request->mappingType == "EXAM_REGISTRATION"){
            $mapperForRegistrationDetails = StudentExamRegistrationServiceMapper::SEARCH_EXAM_REGISTRATION_FEE_DETAILS ;
        }
        else{
            $mapperForRegistrationDetails = StudentExamRegistrationServiceMapper::SEARCH_STUDENT_EXAM_REGISTRATION_FEE_DETAILS;
        }
        $sortBy = " ORDER BY eer.created_date DESC";
        if( $request->orderBySemester ){
            $sortBy = " ORDER BY eerb.academicTermId ASC, eer.properties ->> '$.examYear' ASC ,eer.properties ->> '$.examMonth' + 0 ASC";
        }
        if(($request->isEnableMinorHonorExamRegistration) ){
            if(($request->isMinorHonorExamRegistrationOnly)){
                $whereQuery .= " AND  ( (eer.properties ->> '$.isHonorCourse' = '1') OR (eer.properties ->> '$.isMinorCourse' = '1'))";
            }
            else{
                $whereQuery .= " AND  ( (eer.properties ->> '$.isHonorCourse' IS NULL OR eer.properties ->> '$.isHonorCourse' != '1') AND (eer.properties ->> '$.isMinorCourse' IS NULL OR eer.properties ->> '$.isMinorCourse' != '1'))";
            }
        }
        if(($request->isMinorExamOnly) ){
            $whereQuery .= " AND (eer.properties ->> '$.isMinorCourse' = '1') ";
        }
        if(($request->isHonourExamOnly) ){
            $whereQuery .= " AND (eer.properties ->> '$.isHonorCourse' = '1') ";
        }
        if(!empty($request->studentId)) {
            $whereQuery .= " AND spa.student_id = '$request->studentId";
        }
        if(!empty($request->academicTermId)){
            $academicTermIdString = is_array($request->academicTermId) ? "'" . implode("','",$request->academicTermId) . "'" : "'".$request->academicTermId."'";
            $whereQuery .= " AND  CAST(eerb.properties ->> '$.academicTermId'AS CHAR) IN ( $academicTermIdString )";
        }
        if(!empty($request->groupId)){
            $groupIdString = is_array($request->groupId) ? "'" . implode("','",$request->groupId) . "'" : "'".$request->groupId."'";
            $whereQuery .= " AND  g.id IN ( $groupIdString )";
        }
        if(!empty($request->examType)){
            $examTypeString = is_array($request->examType) ? "'" . implode("','",$request->examType) . "'" : "'".$request->examType."'";
            $whereQuery .= " AND eer.type IN ( $examTypeString )";
        }
        if(($request->isNotConsiderSpecialExam)){
            $whereQuery .= " AND (eer.properties ->> '$.isSpecialExam' != '1' OR eer.properties ->> '$.isSpecialExam' IS NULL )";
            
        }
        if(!empty($request->examRegistrationId)){
            $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
            $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
        }
        if(!empty($request->academicPaperSubjectId)){
            $academicPaperSubjectIdString = is_array($request->academicPaperSubjectId) ? "'" . implode("','",$request->academicPaperSubjectId) . "'" : "'".$request->academicPaperSubjectId."'";
            $whereQuery .= " AND caps.id IN ( $academicPaperSubjectIdString )";
        }
        $query = "SELECT DISTINCT
            sa.studentID as studentId,
            sa.studentName,
            sa.admissionNo,
            spa.id as studentProgramAccountId,
            spa.properties->>'$.registerNumber' AS registerNo,
            spa.properties->>'$.rollNumber' AS rollNo,
            eer.id as examRegistrationId,
            eer.name as examRegistrationName,
            eer.properties->>'$.description' as examRegistrationDescription,
            eer.type as examRegistrationType,
            eer.properties as examRegistrationProperties,
            eerb.groups_id as groupId,
            eerb.properties ->> '$.academicTermId' as academicTermId,
            eerb.properties AS batchProperties,
            eerb.fees_properties as batchFeeProperties,
            act.name AS academicTermName,
            g.name AS groupName,
            p.name AS programName,
            eers.fees_properties as subjectFeeProperties,
            eers.properties as subjectProperties,
            eers.am_assessment_id as assessmentId,
            oe.id as oeExamId,
            caps.id AS academicPaperSubjectId,
            caps.properties ->> '$.isExternal' as isExternal,
            caps.properties ->> '$.isMoocSubject' as isMoocSubject,
            caps.properties ->> '$.isInternal' as isInternal,
            caps.properties ->> '$.internalMaxMark' as internalMaxMark, 
            caps.properties ->> '$.classType' as classType, 
            COALESCE(cap.properties ->> '$.order', 0) * 100 + COALESCE(caps.properties ->> '$.order', 0) as subjectPriority,
            esar.id AS studentAssessmentRegistrationId,
            esar.properties as studentAssessmentRegistrationProperties,
            esar.properties->> '$.registrationType' as assessmentRegistrationType,
            esar.properties->> '$.moocCertificateStatus' as moocCertificateStatus,
            s.code AS subjectCode,
            caps.properties ->> '$.syllabusName' AS syllabusName,
            s.name AS subjectName,
            cst.name as subjectTypeName,
            slot.id AS slotId,
            slot.name AS slotName,
            ct.course_Type as courseType,
            deg.name as degreeName,
            eserd.total_fee AS examRegistrationPaidAmount,
            eserd.balance_amount_details AS balanceAmountDetails,
            eserd.created_date as studentEntryCreatedDate,
            eserd.properties AS examRegistrationPaymentProperties,
            eserd.id AS examRegistrationPaymentUniqueNo,
            eserd.properties ->> '$.challanNo' as challanNo
        FROM
            ec_exam_registration eer
        INNER JOIN ec_exam_registration_batch eerb ON
            eerb.ec_exam_registration_id = eer.id 
        INNER JOIN academic_term act ON 
            act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
        INNER JOIN `groups` g ON
            g.id = eerb.groups_id
            AND g.`type` = 'BATCH'
        INNER JOIN program p ON 
            p.id = g.properties->>'$.programId'
        INNER JOIN course_type ct ON ct.courseTypeID = p.course_type_id
        INNER JOIN ec_exam_registration_subject eers ON
            eers.ec_exam_registration_batch_id = eerb.id
        INNER JOIN cm_academic_paper_subjects caps ON
            caps.id = eers.cm_academic_paper_subjects_id
        INNER JOIN cm_academic_paper cap ON 
            caps.cm_academic_paper_id = cap.id
        INNER JOIN oe_exams oe ON
            oe.assessment_id = eers.am_assessment_id AND oe.is_deleted = 0
        INNER JOIN v4_ams_subject s ON
            s.id = caps.ams_subject_id
        INNER JOIN degree deg ON
            deg.id = p.degree_id
        INNER JOIN ec_student_assessment_registration esar ON
            esar.am_assessment_id = eers.am_assessment_id AND esar.ec_exam_registration_type = eer.type
            AND esar.properties ->> '$.registrationStatus' = 'REGISTERED'
        INNER JOIN student_program_account spa ON 
            spa.student_id = esar.student_id
        INNER JOIN studentaccount sa ON
            sa.studentID = spa.student_id
        LEFT JOIN cm_subject_types cst ON
            cst.id = caps.subject_type_id
        LEFT JOIN cm_common_list_object slot ON slot.id =  caps.slot_id
        LEFT JOIN ec_student_exam_registration_details eserd ON
            eserd.student_id = sa.studentID AND 
            eserd.ec_exam_registration_id = eer.id 
        WHERE
            eer.trashed IS NULL
            AND eer.properties->>'$.publish' = '1' ";
        try {
            $studentExamRegistrationFeeDetails = $this->executeQueryForList($query.$whereQuery.$sortBy, $this->mapper[$mapperForRegistrationDetails]);
        } catch (\Exception $e) {
            throw new ExamControllerException(ExamControllerException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student.");
        }
        if( $request->considerEmptyReturn ){
            return $studentExamRegistrationFeeDetails;
        }elseif (empty($studentExamRegistrationFeeDetails) && !$request->notConsiderEmptyValidation) {
            throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Exam Registration not declared, Please try again.");
        }
        return $studentExamRegistrationFeeDetails;
    }
     /**
     * get Registered Student Revaluation Details
     * @param $request
     * @return studentDetails
     */
    public function getRegisteredStudentRevaluationDetails($request){
        try{
            $request = $this->realEscapeObject($request);
            $whereQuery = "";
            $limitQuery = "";
            $mapperForRevaluationDetails = StudentExamRegistrationServiceMapper::SEARCH_STUDENT_REVALUATION_DETAILS;
            $sortBy = " ORDER BY eer.created_date DESC, spa.properties->>'$.registerNumber' ASC";
            if(!empty($request->examRegistrationId)){
                $examRegistrationIdString = is_array($request->examRegistrationId) ? "'" . implode("','",$request->examRegistrationId) . "'" : "'".$request->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            $query = "SELECT 
                    DISTINCT sa.studentID as studentId,
                    sa.studentName,
                    sa.studentEmail,
                    sa.studentPhone,
                    sa.studentBirthday as studentBirthday,
                    sa.reservID,
                    spa.properties->>'$.registerNumber' AS registerNo,
                    spa.properties->>'$.rollNumber' AS rollNo,
                    eer.id AS examRevaluationId,
                    eer.name AS examRevaluationName,
                    eer.properties AS examRevaluationProperties,
                    eer.type AS examRevaluationType,
                    eerParent.name AS parentExamRegistrationName,
                    eerParent.type AS parentExamRegistrationType,
                    eerParent.properties AS parentExamRegistrationProperties,
                    eerb.properties AS examRevaluationBatchProperties,
                    act.name AS academicTermName,
                    g.id AS groupId,
                    g.name AS groupName,
                    eersParent.am_assessment_id as assessmentId,
                    esarParent.falseNo AS falseNumber,
                    caps.id AS academicPaperSubjectId,
                    IF(caps.properties ->> '$.classType' = 'PRACTICAL',1,0) AS isPractical,
                    esar.id AS studentAssessmentRegistrationId,
                    s.code AS subjectCode,
                    caps.properties ->> '$.syllabusName' AS syllabusName,
                    s.name AS subjectName,
                    esar.properties as studentAssessmentRegistrationProperties,
                    esar.revaluationType as studentRevaluationType,
                    esar.properties ->> '$.registrationStatus' as studentRegistrationStatus
                FROM
                    ec_exam_registration eer
                INNER JOIN ec_exam_registration_batch eerb ON
                    eerb.ec_exam_registration_id = eer.id 
                INNER JOIN ec_exam_registration eerParent ON
                    eerParent.id = eer.properties->>'$.parentExamRegistrationId' AND 
                    eerParent.trashed IS NULL
                INNER JOIN ec_exam_registration_batch eerbParent ON
                    eerbParent.ec_exam_registration_id = eerParent.id  AND 
                    eerb.groups_id = eerbParent.groups_id
                INNER JOIN ec_exam_registration_subject eersParent ON     
                    eersParent.ec_exam_registration_batch_id = eerbParent.id 
                INNER JOIN academic_term act ON 
                    act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
                INNER JOIN cm_academic_paper_subjects caps ON
                    caps.id = eersParent.cm_academic_paper_subjects_id AND caps.properties->>'$.isExternal' = '1'
                INNER JOIN v4_ams_subject s ON
                    s.id = caps.ams_subject_id
                INNER JOIN `groups` g ON
                    g.id = eerb.groups_id
                    AND g.`type` = 'BATCH'
                INNER JOIN ec_student_assessment_registration esar ON 
                    esar.am_assessment_id = eersParent.am_assessment_id AND 
                    esar.ec_exam_registration_type = eer.type AND 
                    esar.identifying_context->>'$.examRegistrationId' = eer.id AND
                    esar.properties ->> '$.registrationStatus' IN ( 'REGISTERED')
                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 studentaccount sa ON
                    sa.studentID = esar.student_id
                INNER JOIN ec_student_assessment_registration esarParent ON 
                    esarParent.student_id = sa.studentID AND
                    esarParent.am_assessment_id = eersParent.am_assessment_id AND
                    esarParent.ec_exam_registration_type = eerParent.type
                WHERE eer.type = 'REVALUATION' AND eer.trashed IS NULL AND eer.properties->>'$.publish' = 1 ";
            $studentDetails = $this->executeQueryForList($query.$whereQuery.$sortBy.$limitQuery, $this->mapper[$mapperForRevaluationDetails]);
        }
        catch(\Exception $e) {
            throw new ExamControllerException ($e->getCode(),$e->getMessage());
        }
        return $studentDetails;
    }
}