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 / 19
CRAP
0.00% covered (danger)
0.00%
0 / 624
GradeSchemeService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 19
13110.00
0.00% covered (danger)
0.00%
0 / 624
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 4
 saveGradeScheme
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 25
 validateSaveGradeSchemeRequest
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 4
 insertGradeScheme
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 19
 updateGradeScheme
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 22
 deleteGradeScheme
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 24
 restoreGradeScheme
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 24
 searchGradeScheme
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 51
 getGradeSchemeDetails
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 35
 getAllGradeScemesByCurriculum
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 29
 getAllExamRegistrationGradeSchemes
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 32
 getAllSubjectGradeSchemes
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 37
 getAllCGPAGradeSchemes
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getAllSubjectGradeSchemesByRequest
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 33
 getSubjectPassCriteriaByAcademicPaperSubject
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 64
 getAllSemesterSubjectCurriculumGrades
0.00% covered (danger)
0.00%
0 / 1
240.00
0.00% covered (danger)
0.00%
0 / 79
 getGradeSchemesByRequest
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 37
 getSubjectPassCriteriaByRequest
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 70
 getAllSemGradeSchemesByRequest
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 21
<?php
namespace com\linways\ec\core\service;
use com\linways\ec\core\logging\Events;
use com\linways\core\ams\professional\logging\AMSLogger;
use com\linways\base\util\SecurityUtils;
use com\linways\base\util\MakeSingletonTrait;
use com\linways\ec\core\exception\ECCoreException;
use com\linways\ec\core\request\SearchGradeSchemeRequest;
use com\linways\ec\core\mapper\GradeSchemeServiceMapper;
use com\linways\ec\core\constant\FilterModeConstants;
use com\linways\ec\core\constant\StatusConstants;
use com\linways\ec\core\service\GradeService;
use com\linways\ec\core\dto\GradeScheme;
use com\linways\cbe\core\logging\entities\GradeSchemeEntity;
use com\linways\ec\core\exception\ExamControllerException;
use com\linways\core\ams\professional\dto\ExamType;
use com\linways\core\ams\professional\service\CurriculumManageService;
use com\linways\core\ams\professional\dto\GradeSchemaBasedOnType;
class GradeSchemeService extends BaseService
{
    use MakeSingletonTrait;
    private function __construct()
    {
        $this->mapper = GradeSchemeServiceMapper::getInstance()->getMapper();
        $this->logger = AMSLogger::getLogger('exam-controller-log');
    }
    /**
     * Save gradeScheme
     * @param GradeScheme $gradeScheme
     * @return GradeScheme $gradeScheme
     */
    public function saveGradeScheme(GradeScheme $gradeScheme)
    {
        $gradeScheme = $this->realEscapeObject($gradeScheme);
        $gradeScheme->createdBy = $GLOBALS['userId'] ?? $gradeScheme->createdBy;
        $gradeScheme->updatedBy = $GLOBALS['userId'] ?? $gradeScheme->updatedBy;
        try {
            $this->validateSaveGradeSchemeRequest($gradeScheme);
            if (!empty($gradeScheme->id)) {
                $gradeScheme->id = $this->updateGradeScheme($gradeScheme);
            } else {
                $gradeScheme->id = $this->insertGradeScheme($gradeScheme);
            }
            if (!empty($gradeScheme->grades)) {
                GradeService::getInstance()->saveGrades($gradeScheme->grades);
            }
        } catch (\Exception $e) {
            if ($e->getCode() !== ECCoreException::INVALID_PARAMETERS && $e->getCode() !== ECCoreException::EMPTY_PARAMETERS && $e->getCode() !== ECCoreException::DUPLICATE_ENTRY) {
                throw new ECCoreException(ECCoreException::ERROR_SAVING_GRADE_SCHEME, "Failed to save grade scheme! Please try again");
            } else if ($e->getCode() === ECCoreException::DUPLICATE_ENTRY) {
                throw new ECCoreException(ECCoreException::DUPLICATE_ENTRY, "Cannot create grade scheme." . $gradeScheme->name . " already exists!");
            } else {
                throw new ECCoreException($e->getCode(), $e->getMessage());
            }
        }
        return $gradeScheme;
    }
    /**
     * Validate GradeScheme Request Before Saving
     * @param GradeScheme $gradeScheme
     * @return NULL
     */
    private function validateSaveGradeSchemeRequest($gradeScheme)
    {
        if (empty($gradeScheme->name))
            throw new ECCoreException(ECCoreException::EMPTY_PARAMETERS, "Grade scheme name is empty! Please enter a name for grade scheme");
    }
    /**
     * Insert gradeScheme
     * @param GradeScheme $gradeScheme
     * @return String $id
     */
    private function insertGradeScheme(GradeScheme $gradeScheme)
    {
        $properties = !empty($gradeScheme->properties) ? "'" . json_encode($gradeScheme->properties) . "'" : "JSON_OBJECT";
        $id = SecurityUtils::getRandomString();
        $query = "INSERT INTO grade_scheme
            (id,name,properties,created_by,updated_by)
            VALUES
            ('$id','$gradeScheme->name','$gradeScheme->type',$properties,'$gradeScheme->createdBy','$gradeScheme->updatedBy')";
        try {
            $this->executeQuery($query);
            AMSLogger::log_info($this->logger,Events::GRADE_SCHEME_CREATION, [
                "grade_scheme" => new GradeSchemeEntity(["id" => $id]),
                "status" => StatusConstants::SUCCESS,
                "updated_by" => $updatedBy,
            ]);
            return $id;
        } catch (\Exception $e) {
            throw new ECCoreException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Update GradeScheme
     * @param GradeScheme $gradeScheme
     * @return NULL
     */
    private function updateGradeScheme(GradeScheme $gradeScheme)
    {
        $properties = !empty($gradeScheme->properties) ? "'" . json_encode($gradeScheme->properties) . "'" : "JSON_OBJECT";
        $query = "UPDATE
                    grade_scheme
                SET
                    name = '$gradeScheme->name',
                    properties = $properties,
                    updated_by = '$gradeScheme->updatedBy'
                WHERE
                    id = '$gradeScheme->id'";
        try {
            $this->executeQuery($query);
            AMSLogger::log_info($this->logger,Events::GRADE_SCHEME_UPDATING, [
                "grade_scheme" => new GradeSchemeEntity(["id" => $id]),
                "status" => StatusConstants::SUCCESS,
                "updated_by" => $updatedBy,
            ]);
            return $gradeScheme->id;
        } catch (\Exception $e) {
            throw new ECCoreException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Delete GradeScheme (Soft Delete)
     * @param String $id
     * @return NULL
     */
    public function deleteGradeScheme($id)
    {
        $id = $this->realEscapeString($id);
        $updatedBy = $GLOBALS['userId'];
        if (empty($id)) {
            throw new ECCoreException(ECCoreException::EMPTY_PARAMETERS, "No grade scheme selected! Please select a gradeScheme to delete");
        }
        //TODO: Do validation before deleting
        $query = "UPDATE
                    grade_scheme
                SET
                    trashed = UTC_TIMESTAMP(),
                    updated_by = '$updatedBy'
                WHERE
                    id = '$id'";
        try {
            $this->executeQuery($query);
            AMSLogger::log_info($this->logger,Events::GRADE_SCHEME_DELETION, [
                "grade_scheme" => new GradeSchemeEntity(["id" => $id]),
                "status" => StatusConstants::SUCCESS,
                "updated_by" => $updatedBy,
            ]);
        } catch (\Exception $e) {
            throw new ECCoreException(ECCoreException::ERROR_DELETING_GRADE_SCHEME, "Error deleting grade scheme! Please try again");
        }
    }
    /**
     * Restore GradeScheme
     * @param String $id
     * @return NULL
     */
    public function restoreGradeScheme($id)
    {
        $id = $this->realEscapeString($id);
        $updatedBy = $GLOBALS['userId'];
        if (empty($id)) {
            throw new ECCoreException(ECCoreException::EMPTY_PARAMETERS, "No grade scheme selected! Please select a gradeScheme to restore");
        }
        $query = "UPDATE
                    grade_scheme
                SET
                    trashed = NULL,
                    updated_by = '$updatedBy'
                WHERE
                    id = '$id'";
        try {
            $this->executeQuery($query);
            AMSLogger::log_info($this->logger,Events::GRADE_SCHEME_RESTORED, [
                "grade_scheme" => new GradeSchemeEntity(["id" => $id]),
                "status" => StatusConstants::SUCCESS,
                "updated_by" => $updatedBy,
            ]);
        } catch (\Exception $e) {
            throw new ECCoreException(ECCoreException::ERROR_RESTORING_GRADE_SCHEME, "Error restoring grade scheme! Please try again");
        }
    }
    /**
     * Search GradeScheme Details
     * @param SearchGradeSchemeRequest $request
     * @return GradeScheme
     */
    public function searchGradeScheme(SearchGradeSchemeRequest $request)
    {
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        $columnQuery = "";
        $joinQuery = "";
        $gradeSchemeServiceMapper = GradeSchemeServiceMapper::SEARCH_GRADE_SCHEME;
        if ($request->trashed === StatusConstants::ACTIVE) {
            $whereQuery .= " AND gs.trashed IS NULL ";
        }
        if ($request->trashed === StatusConstants::TRASHED) {
            $whereQuery .= " AND gs.trashed IS NOT NULL ";
        }
        if (!empty($request->id)) {
            $whereQuery .= " AND gs.id='$request->id";
        }
        if (!empty($request->name)) {
            $whereQuery .= " AND  gs.name LIKE '%$request->name%' ";
        }
        if ($request->includeGrade) {
            $gradeSchemeServiceMapper = GradeSchemeServiceMapper::SEARCH_GRADE_SCHEME_WITH_GRADE;
            $joinQuery = " INNER JOIN grade g ON g.grade_scheme_id = gs.id ";
            $columnQuery = " , g.id AS gradeId,g.range_from ,g.range_to, g.name AS gradeName, g.properties AS gradeProperties, NULL AS gradeTrashed ";
        }
        if ($request->startIndex !== "" && $request->endIndex !== "") {
            $limitQuery .= " LIMIT $request->startIndex,$request->endIndex";
        }
        $query = "SELECT
            gs.id,
            gs.name,
            gs.properties,
            gs.trashed,
            gs.created_by,
            gs.created_date,
            gs.updated_by,
            gs.updated_date
            $columnQuery
        FROM
            grade_scheme gs
            $joinQuery
        WHERE
            1 = 1
            $whereQuery
            $limitQuery";
        try {
            $gradeSchemes = $this->executeQueryForList($query, $this->mapper[$gradeSchemeServiceMapper]);
        } catch (\Exception $e) {
            throw new ECCoreException(ECCoreException::ERROR_FETCHING_GRADE_SCHEME, "Cannot fetch grade scheme details! Please try again");
        }
        return $gradeSchemes;
    }
    /**
     * get Grade Scheme by id
     * @param String $id
     * @param Boolean $request
     * @return GradeScheme
     */
    public function getGradeSchemeDetails($id, $includeGrade = false)
    {
        $id = $this->realEscapeString($id);
        $request = $this->realEscapeObject($request);
        $columnQuery = "";
        $joinQuery = "";
        $gradeSchemeServiceMapper = GradeSchemeServiceMapper::SEARCH_GRADE_SCHEME;
        if (empty($id))
            throw new ProfessionalException(ProfessionalException::EMPTY_PARAMETERS, "Grade scheme is invalid! Please enter a valid program");
        if ($includeGrade) {
            $gradeSchemeServiceMapper = GradeSchemeServiceMapper::SEARCH_GRADE_SCHEME_WITH_GRADE;
            $joinQuery = " INNER JOIN grade g ON g.grade_scheme_id = gs.id ";
            $columnQuery = " , g.id AS gradeId,g.range_from ,g.range_to, g.name AS gradeName, g.properties AS gradeProperties, NULL AS gradeTrashed ";
        }
        $query = "SELECT
            gs.id,
            gs.name,
            gs.properties,
            gs.trashed,
            gs.created_by,
            gs.created_date,
            gs.updated_by,
            gs.updated_date
            $columnQuery
        FROM
            grade_scheme gs
            $joinQuery
        WHERE
            gs.id = '$id'";
        try {
            $gradeScheme = $this->executeQueryForObject($query, $this->mapper[$gradeSchemeServiceMapper]);
        } catch (\Exception $e) {
            throw new ECCoreException(ECCoreException::ERROR_FETCHING_GRADE_SCHEME, "Cannot fetch grade scheme details! Please try again");
        }
        return $gradeScheme;
    }
    /**
     * get Grade Scheme by Curriculum
     * @param String $searchRequest
     * @return gradeSchemrs
     */
    public function getAllGradeScemesByCurriculum($searchRequest)
    {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try {
            $params = new \stdClass();
            $searchRequest->startYear = $searchRequest->admissionYear;
            if(!empty($searchRequest->examRegistrationId) && empty($searchRequest->groupId)){
                $examBatches = ExamRegistrationBatchService::getInstance()->searchExamRegistrationBatchDetails($searchRequest);
                $searchRequest->groupId = array_unique(array_column($examBatches,'id'));
            }
            if(!empty($searchRequest->groupId)){
                $params->groupIds = json_encode((array)$searchRequest->groupId);
            }
         
            $params->type = "CURRICULUM";
           
            $params->orderBy = $searchRequest->orderBy;
            $req = new GradeSchemaBasedOnType($params);
            
            $gradeSchemes = CurriculumManageService::getInstance()->getPossibleSchemaDetails($req);
            $gradeObj = new \stdClass();
            array_walk($gradeSchemes, function ($schema, $key) use ($gradeObj) {
                array_walk($schema->grades, function ($grade, $gradeKey) use ($gradeObj) {
                    $grade->properties = json_encode($grade->properties);
                    $grade->name = $grade->letterGrade;
                    $grade->class = $grade->className;
                    $gradeObj->gradeArray[$grade->id] = $grade;
                });
            });
            $gradeArray = $gradeObj->gradeArray;
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $gradeArray;
    }
    public function getAllExamRegistrationGradeSchemes($searchRequest)
    {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try {
               
            $params = new \stdClass();
            $searchRequest->startYear = $searchRequest->admissionYear;
            if(!empty($searchRequest->examRegistrationId) && empty($searchRequest->groupId)){
                $examBatches = ExamRegistrationBatchService::getInstance()->searchExamRegistrationBatchDetails($searchRequest);
                $searchRequest->groupId = array_unique(array_column($examBatches,'id'));
            }
            if(!empty($searchRequest->groupId)){
                $params->groupIds = json_encode((array)$searchRequest->groupId);
            }
            if (!empty($searchRequest->academicTermId)){
                $params->termIds = json_encode((array)$searchRequest->academicTermId);
            }
            
            $params->type = "SYLLABUS_ACADEMIC_TERM";
           
            $params->orderBy = $searchRequest->orderBy;
            $req = new GradeSchemaBasedOnType($params);
            
            $gradeSchemes = CurriculumManageService::getInstance()->getPossibleSchemaDetails($req);
            $gradeObj = new \stdClass();
            array_walk($gradeSchemes, function ($schema, $key) use ($gradeObj) {
                array_walk($schema->grades, function ($grade, $gradeKey) use ($gradeObj) {
                    $grade->properties = json_encode($grade->properties);
                    $grade->class = $grade->className;
                    $grade->name = $grade->letterGrade;
                    $gradeObj->gradeArray[$grade->id] = $grade;
                });
            });
            $gradeArray = $gradeObj->gradeArray;
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $gradeArray;
    }
    public function getAllSubjectGradeSchemes($searchRequest)
    {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try {
    
            $params = new \stdClass();
            $searchRequest->startYear = $searchRequest->admissionYear;
            if(!empty($searchRequest->examRegistrationId) && empty($searchRequest->groupId)){
                $examBatches = ExamRegistrationBatchService::getInstance()->searchExamRegistrationBatchDetails($searchRequest);
                $searchRequest->groupId = array_unique(array_column($examBatches,'id'));
            }
            if(!empty($searchRequest->groupId)){
                $params->groupIds = json_encode((array)$searchRequest->groupId);
            }
            if (!empty($searchRequest->academicTermId)){
                $params->termIds = json_encode((array)$searchRequest->academicTermId);
            }
            
            $params->type = "ACADEMIC_PAPER_SUBJECT";
            if (!empty($searchRequest->academicPaperSubjectId)) {
                $params->ids = json_encode((array)$searchRequest->academicPaperSubjectId);
            }
            
            $params->orderBy = $searchRequest->orderBy;
            $req = new GradeSchemaBasedOnType($params);
            
            $gradeSchemes = CurriculumManageService::getInstance()->getPossibleSchemaDetails($req);
            $gradeObj = new \stdClass();
            array_walk($gradeSchemes, function ($schema, $key) use ($gradeObj) {
                array_walk($schema->grades, function ($grade, $gradeKey) use ($gradeObj) {
                    $grade->properties = json_encode($grade->properties);
                    $grade->class = $grade->className;
                    $grade->name = $grade->letterGrade;
                    $grade->range_to = $grade->rangeTo;
                    $grade->range_from = $grade->rangeFrom;
                    $gradeObj->gradeArray[$grade->id] = $grade;
                });
            });
            $gradeArray = $gradeObj->gradeArray;
        } catch (\Exception $e) {
            throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $gradeArray;
    }
    public function getAllCGPAGradeSchemes($searchRequest)
    {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try {
            $params = new \stdClass();
            $params->groupIds = json_encode((array)$searchRequest->groupId);
            $params->type = "CURRICULUM";
            $params->orderBy = $searchRequest->orderBy;
            $req = new GradeSchemaBasedOnType($params);
            
            $gradeSchemes = reset(CurriculumManageService::getInstance()->getPossibleSchemaDetails($req))->grades;
        } catch (\Exception $e) {
            return false;
            // throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $gradeSchemes;
    }
    /**
     * Search GradeScheme Details by request
     * @param SearchGradeSchemeRequest $request
     * @return gradeSchemes
     */
    public function getAllSubjectGradeSchemesByRequest($searchRequest)
    {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try {
            $params = new \stdClass();
            $searchRequest->startYear = $searchRequest->admissionYear;
            if(!empty($searchRequest->examRegistrationId) && empty($searchRequest->groupId)){
                $examBatches = ExamRegistrationBatchService::getInstance()->searchExamRegistrationBatchDetails($searchRequest);
                $searchRequest->groupId = array_unique(array_column($examBatches,'id'));
            }
            if(!empty($searchRequest->groupId)){
                $params->groupIds = json_encode((array)$searchRequest->groupId);
            }
            if (!empty($searchRequest->academicTermId)){
                $params->termIds = json_encode((array)$searchRequest->academicTermId);
            }
            if ( $searchRequest->requestType == "CURRICULAM" ){
                $params->type = "CURRICULUM";
            } else if ($searchRequest->requestType == "SEMESTER") {
                $params->type = "SYLLABUS_ACADEMIC_TERM";
            } else {
                $params->type = "ACADEMIC_PAPER_SUBJECT";
                if (!empty($searchRequest->academicPaperSubjectId)) {
                    $params->ids = json_encode((array)$searchRequest->academicPaperSubjectId);
                }
            }
            $params->orderBy = $searchRequest->orderBy;
            $req = new GradeSchemaBasedOnType($params);
            
            $gradeSchemes = CurriculumManageService::getInstance()->getPossibleSchemaDetails($req);
        } catch (\Exception $e) {
            return false;
            // throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $gradeSchemes;
    }
    /**
     * Get subject pass criteria by academic paper subject
     * @param $academicPaperSubjectId, $schemeType
     * @return passPercentCriteria
     */
    public function getSubjectPassCriteriaByAcademicPaperSubject($academicPaperSubjectId, $schemeType = null)
    {
        $academicPaperSubjectId = $this->realEscapeString($academicPaperSubjectId);
        $schemeType = $this->realEscapeString($schemeType);
        try {
            $query = "SELECT 
                vm.properties AS internalPercentage,
                vm1.properties AS externalPercentage,
                vm2.properties AS subjectPercentage
            FROM 
                cm_academic_paper_subjects caps 
            LEFT JOIN valuation_method vm ON 
                caps.id = vm.identifying_context->>'$.academicPaperSubjectId' 
                AND  vm.`type` = 'ACADEMIC_PAPER_SUBJECT' 
                AND vm.identifying_context->>'$.passCriteriaType' = 'INTERNAL'
            LEFT JOIN valuation_method vm1 ON 
                caps.id = vm1.identifying_context->>'$.academicPaperSubjectId' 
                AND  vm1.`type` = 'ACADEMIC_PAPER_SUBJECT' 
                AND vm1.identifying_context->>'$.passCriteriaType' = 'EXTERNAL' 
            LEFT JOIN valuation_method vm2 ON 
                caps.id = vm2.identifying_context->>'$.academicPaperSubjectId' 
                AND  vm2.`type` = 'ACADEMIC_PAPER_SUBJECT' 
                AND vm2.identifying_context->>'$.passCriteriaType' = 'AGGREGATE'
            WHERE     
                caps.id = '$academicPaperSubjectId'";
            $passCriteria =  $this->executeQueryForObject($query);
            $internalCriteria =  json_decode($passCriteria->internalPercentage);
            $externalCriteria =  json_decode($passCriteria->externalPercentage);
            $subjectCriteria =  json_decode($passCriteria->subjectPercentage);
            $response = new \stdClass;
            $passPercentCriteria = new \stdClass;
            array_walk($internalCriteria->passCriterias, function ($criteria, $key) use ($response) {
                $response->internalCriteria[$criteria->type] = $criteria->value;
            });
            array_walk($externalCriteria->passCriterias, function ($criteria, $key) use ($response) {
                $response->externalCriteria[$criteria->type] = $criteria->value;
            });
            array_walk($subjectCriteria->passCriterias, function ($criteria, $key) use ($response) {
                $response->subjectCriteria[$criteria->type] = $criteria->value;
            });
            if ($schemeType) {
                if ($response->internalCriteria[$schemeType]) {
                    $passPercentCriteria->internalPassCriteria = (float) $response->internalCriteria[$schemeType];
                }
                if ($response->externalCriteria[$schemeType]) {
                    $passPercentCriteria->externalPassCriteria = (float) $response->externalCriteria[$schemeType];
                }
                if ($response->subjectCriteria[$schemeType]) {
                    $passPercentCriteria->overallPassCriteria = (float) $response->subjectCriteria[$schemeType];
                }
            } else {
                $schemeTypes = ["PERCENTAGE"];
                array_walk($schemeTypes, function ($schemeType, $key) use ($response, $passPercentCriteria) {
                    if ($response->internalCriteria[$schemeType]) {
                        $passPercentCriteria->internalPassCriteria = (float) $response->internalCriteria[$schemeType];
                    }
                    if ($response->externalCriteria[$schemeType]) {
                        $passPercentCriteria->externalPassCriteria = (float) $response->externalCriteria[$schemeType];
                    }
                    if ($response->subjectCriteria[$schemeType]) {
                        $passPercentCriteria->overallPassCriteria = (float) $response->subjectCriteria[$schemeType];
                    }
                });
            }
        } catch (\Exception $e) {
            return false;
            // throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $passPercentCriteria;
    }
    /**
     * Search Grades Details  Subject Semester Curriculum
     * @param SearchGradeSchemeRequest $request
     * @return gradeSchemes
     */
    public function getAllSemesterSubjectCurriculumGrades($searchRequest)
    {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try {
            $whereQuery = "";
            $innerJoinQuerry = "";
            $gradeJoiningCondition = "";
            if (!empty($searchRequest->courseTypeId)) {
                $whereQuery .= " AND g.properties ->> '$.courseTypeId' = '$searchRequest->courseTypeId'";
            }
            if (!empty($searchRequest->admissionYear)) {
                $whereQuery .= " AND g.properties ->> '$.startYear' = '$searchRequest->admissionYear'";
            }
            if (!empty($searchRequest->groupId)) {
                $groupIdString = is_array($searchRequest->groupId) ? "'" . implode("','", $searchRequest->groupId) . "'" : "'" . $searchRequest->groupId . "'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if (!empty($searchRequest->academicTermId && $searchRequest->requestType != "CURRICULAM")) {
                $whereQuery .= " AND eerb.properties->>'$.academicTermId' = $searchRequest->academicTermId";
            }
            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->academicPaperSubjectId) && !$searchRequest->requestType) {
                $whereQuery .= " AND aps.id = '$searchRequest->academicPaperSubjectId'";
            }
            if ($searchRequest->requestType == "CURRICULAM") {
                $innerJoinQuerry .= "";
                $gradeJoiningCondition = " gs.id = CAST(cc.properties->>'$.gradeSchemeId' AS CHAR)";
            } else if ($searchRequest->requestType == "SEMESTER") {
                $innerJoinQuerry .= " INNER JOIN cm_curriculum_syllabus_relation ccsr ON
                        ccsr.cm_curriculum_id = cc.id
                    INNER JOIN cm_syllabus_academic_term_settings csats ON
                        csats.cm_syllabus_id = ccsr.cm_syllabus_id AND csats.academic_term_id = eerb.properties->>'$.academicTermId'
                    INNER JOIN valuation_method vm ON
                        CAST(vm.identifying_context->>'$.syllabusAcademicTermSettingsId' AS CHAR) = csats.id AND vm.type='SYLLABUS_ACADEMIC_TERM'";
                $gradeJoiningCondition = " gs.id = CAST(vm.properties->>'$.gradeSchemeId' AS CHAR)";
            } else {
                $innerJoinQuerry .= " INNER JOIN ec_exam_registration_subject eers ON
                        eers.ec_exam_registration_batch_id = eerb.id
                    INNER JOIN cm_academic_paper_subjects aps ON
                        aps.id = eers.cm_academic_paper_subjects_id";
                $gradeJoiningCondition = " gs.id = CAST(aps.properties->>'$.gradeSchemeId' AS CHAR)";
            }
            $groupBy = " ";
            if ($searchRequest->orderBy == "ASC") {
                $orderBy = " ORDER BY gr.range_to ASC";
            } else {
                $orderBy = " ORDER BY gr.range_to DESC";
            }
            $query = "SELECT DISTINCT
                gr.id  AS gradeId,
                gr.name AS gradeName,
                gr.range_from,
                gr.range_to,
                gr.properties->>'$.class' AS class,
                gr.properties->>'$.failStatus' AS failStatus,
                gr.properties->>'$.gradePoint' AS gradePoint,
                gr.properties
            FROM
                `groups` g
            INNER JOIN ec_exam_registration_batch eerb ON
                eerb.groups_id = g.id
            INNER JOIN ec_exam_registration eer ON
                eer.id = eerb.ec_exam_registration_id 
            INNER JOIN cm_curriculum cc ON
                cc.id = CAST(g.properties->>'$.curriculumId' AS CHAR)
            $innerJoinQuerry
            INNER JOIN grade_scheme gs ON
                $gradeJoiningCondition
            INNER JOIN grade gr ON
                gr.grade_scheme_id = gs.id
            WHERE 1=1 AND eer.trashed IS NULL ";
            $grades =  $this->executeQueryForList($query . $whereQuery . $groupBy . $orderBy);
        } catch (\Exception $e) {
            return false;
            // throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $grades;
    }
    /**
     * Search GradeScheme Details by request
     * @param SearchGradeSchemeRequest $request
     * @return gradeSchemes
     */
    public function getGradeSchemesByRequest($searchRequest)
    {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try {
            $params = new \stdClass();
            $searchRequest->startYear = $searchRequest->admissionYear;
            if(!empty($searchRequest->examRegistrationId) && empty($searchRequest->groupId)){
                $examBatches = ExamRegistrationBatchService::getInstance()->searchExamRegistrationBatchDetails($searchRequest);
                $searchRequest->groupId = array_unique(array_column($examBatches,'id'));
            }
            if(!empty($searchRequest->groupId)){
                $params->groupIds = json_encode((array)$searchRequest->groupId);
            }
            if (!empty($searchRequest->academicTermId)){
                $params->termIds = json_encode((array)$searchRequest->academicTermId);
            }
            if ( $searchRequest->requestType == "CURRICULAM" ){
                $params->type = "CURRICULUM";
            } else if ($searchRequest->requestType == "SEMESTER") {
                $params->type = "SYLLABUS_ACADEMIC_TERM";
            } else {
                $params->type = "ACADEMIC_PAPER_SUBJECT";
                if (!empty($searchRequest->academicPaperSubjectId)) {
                    $params->ids = json_encode((array)$searchRequest->academicPaperSubjectId);
                }
            }
            $params->orderBy = $searchRequest->orderBy;
            $req = new GradeSchemaBasedOnType($params);
            $gradeArray = [];
            $gradeSchemes = CurriculumManageService::getInstance()->getPossibleSchemaDetails($req);
            foreach( $gradeSchemes AS $grade){
                $gradeArray[$grade->id] = $grade;
            }
        } catch (\Exception $e) {
            return false;
            // throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $gradeArray;
    }
    /**
     * Get subject pass criteria by academic paper subject
     * @param $academicPaperSubjectId, $schemeType
     * @return passPercentCriteria
     */
    public function getSubjectPassCriteriaByRequest($searchRequest, $schemeType = null)
    {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $academicPaperSubjectIdString = is_array($searchRequest->academicPaperSubjectId) ? "'" . implode("','", $searchRequest->academicPaperSubjectId) . "'" : "'" . $searchRequest->academicPaperSubjectId . "'";
        
        $schemeType = $this->realEscapeString($schemeType);
        try {
            $query = "SELECT 
                caps.id,
                vm.properties AS internalPercentage,
                vm1.properties AS externalPercentage,
                vm2.properties AS subjectPercentage
            FROM 
                cm_academic_paper_subjects caps 
            LEFT JOIN valuation_method vm ON 
                caps.id = vm.identifying_context->>'$.academicPaperSubjectId' 
                AND  vm.`type` = 'ACADEMIC_PAPER_SUBJECT' 
                AND vm.identifying_context->>'$.passCriteriaType' = 'INTERNAL'
            LEFT JOIN valuation_method vm1 ON 
                caps.id = vm1.identifying_context->>'$.academicPaperSubjectId' 
                AND  vm1.`type` = 'ACADEMIC_PAPER_SUBJECT' 
                AND vm1.identifying_context->>'$.passCriteriaType' = 'EXTERNAL' 
            LEFT JOIN valuation_method vm2 ON 
                caps.id = vm2.identifying_context->>'$.academicPaperSubjectId' 
                AND  vm2.`type` = 'ACADEMIC_PAPER_SUBJECT' 
                AND vm2.identifying_context->>'$.passCriteriaType' = 'AGGREGATE'
            WHERE     
                caps.id IN ( $academicPaperSubjectIdString )";
            $passCriterias =  $this->executeQueryForList($query);
            $passCriteriasArray = [];
            foreach( $passCriterias as $passCriteria) {
                $internalCriteria =  json_decode($passCriteria->internalPercentage);
                $externalCriteria =  json_decode($passCriteria->externalPercentage);
                $subjectCriteria =  json_decode($passCriteria->subjectPercentage);
                $response = new \stdClass;
                $passPercentCriteria = new \stdClass;
                array_walk($internalCriteria->passCriterias, function ($criteria, $key) use ($response) {
                    $response->internalCriteria[$criteria->type] = $criteria->value;
                });
                array_walk($externalCriteria->passCriterias, function ($criteria, $key) use ($response) {
                    $response->externalCriteria[$criteria->type] = $criteria->value;
                });
                array_walk($subjectCriteria->passCriterias, function ($criteria, $key) use ($response) {
                    $response->subjectCriteria[$criteria->type] = $criteria->value;
                });
                if ($schemeType) {
                    if ($response->internalCriteria[$schemeType]) {
                        $passPercentCriteria->internalPassCriteria = (float) $response->internalCriteria[$schemeType];
                    }
                    if ($response->externalCriteria[$schemeType]) {
                        $passPercentCriteria->externalPassCriteria = (float) $response->externalCriteria[$schemeType];
                    }
                    if ($response->subjectCriteria[$schemeType]) {
                        $passPercentCriteria->overallPassCriteria = (float) $response->subjectCriteria[$schemeType];
                    }
                } else {
                    $schemeTypes = ["PERCENTAGE"];
                    array_walk($schemeTypes, function ($schemeType, $key) use ($response, $passPercentCriteria) {
                        if ($response->internalCriteria[$schemeType]) {
                            $passPercentCriteria->internalPassCriteria = (float) $response->internalCriteria[$schemeType];
                        }
                        if ($response->externalCriteria[$schemeType]) {
                            $passPercentCriteria->externalPassCriteria = (float) $response->externalCriteria[$schemeType];
                        }
                        if ($response->subjectCriteria[$schemeType]) {
                            $passPercentCriteria->overallPassCriteria = (float) $response->subjectCriteria[$schemeType];
                        }
                    });
                }
                $passCriteriasArray[$passCriteria->id]= $passPercentCriteria;
            }
        } catch (\Exception $e) {
            return false;
            // throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $passCriteriasArray;
    }
    public function getAllSemGradeSchemesByRequest($searchRequest)
    {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try {
            $params = new \stdClass();
            $gradeArray = [];
            foreach( $searchRequest->semGradeBatchArray AS $groupId => $batchArray ){
                $params->groupIds = json_encode((array)$groupId);
                $params->termIds = json_encode(array_values($batchArray->semesterId));
                $params->type = "SYLLABUS_ACADEMIC_TERM";
                $params->orderBy = $searchRequest->orderBy;
                $req = new GradeSchemaBasedOnType($params);
                $gradeSchemes = CurriculumManageService::getInstance()->getPossibleSchemaDetails($req);
                foreach( $gradeSchemes AS $grade){
                    $gradeArray[$grade->id] = $grade;
                }
            }
        } catch (\Exception $e) {
            return false;
            // throw new ExamControllerException($e->getCode(), $e->getMessage());
        }
        return $gradeArray;
    }
}