Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 20 |
CRAP | |
0.00% |
0 / 1067 |
| CommonExamService | |
0.00% |
0 / 1 |
|
0.00% |
0 / 20 |
46440.00 | |
0.00% |
0 / 1067 |
| __construct | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 3 |
|||
| __clone | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 2 |
|||
| getInstance | |
0.00% |
0 / 1 |
6.00 | |
0.00% |
0 / 5 |
|||
| checkIfExamControllerIsEnabled | |
0.00% |
0 / 1 |
12.00 | |
0.00% |
0 / 7 |
|||
| updateAcademicPaperMaximumMarkToContollerSide | |
0.00% |
0 / 1 |
42.00 | |
0.00% |
0 / 31 |
|||
| getV4StudentDetailsByFalseNumber | |
0.00% |
0 / 1 |
72.00 | |
0.00% |
0 / 40 |
|||
| getV4DigitalValuationStaffPermission | |
0.00% |
0 / 1 |
506.00 | |
0.00% |
0 / 89 |
|||
| checkStudentIsEligibleForCondonation | |
0.00% |
0 / 1 |
462.00 | |
0.00% |
0 / 55 |
|||
| getExamRegistrationDetailsByRequest | |
0.00% |
0 / 1 |
72.00 | |
0.00% |
0 / 54 |
|||
| getStatusOfWorkflowRequest | |
0.00% |
0 / 1 |
12.00 | |
0.00% |
0 / 16 |
|||
| getAllWorkflows | |
0.00% |
0 / 1 |
6.00 | |
0.00% |
0 / 10 |
|||
| getConsolidatedStudentData | |
0.00% |
0 / 1 |
1980.00 | |
0.00% |
0 / 285 |
|||
| getStudentExamRegistrationDetails | |
0.00% |
0 / 1 |
90.00 | |
0.00% |
0 / 69 |
|||
| checkStudentSemesterWiseAttendanceCriteriaForExamRegistration | |
0.00% |
0 / 1 |
702.00 | |
0.00% |
0 / 64 |
|||
| checkHaveMinimumAttendance | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 4 |
|||
| isEligibleForCondonation | |
0.00% |
0 / 1 |
12.00 | |
0.00% |
0 / 7 |
|||
| getGroupedHeaderDetails | |
0.00% |
0 / 1 |
2256.00 | |
0.00% |
0 / 245 |
|||
| fetchExamRegisteredStudentsForTermPromotion | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 23 |
|||
| getSubCourseRelationByPaperIds | |
0.00% |
0 / 1 |
30.00 | |
0.00% |
0 / 37 |
|||
| chekActiveMandatoryOnlineExam | |
0.00% |
0 / 1 |
6.00 | |
0.00% |
0 / 21 |
|||
| <?php | |
| namespace com\linways\core\ams\professional\service\examcontroller; | |
| use com\linways\core\ams\professional\exception\ProfessionalException; | |
| use com\linways\core\ams\professional\service\BaseService; | |
| use com\linways\core\ams\professional\toggles\PermissionToggle; | |
| use com\linways\core\ams\professional\service\AssessmentService; | |
| use com\linways\core\ams\professional\dto\SettingsConstents; | |
| use com\linways\core\ams\professional\constant\ExamType; | |
| use com\linways\core\ams\professional\service\CommonService; | |
| use com\linways\core\ams\professional\service\AttendanceService; | |
| use com\linways\core\ams\professional\service\v4Attendance\V4AttendanceService; | |
| use com\linways\core\ams\professional\util\CommonUtil; | |
| use com\linways\core\ams\professional\mapper\examcontroller\ConsolidatedMarkReportServiceMapper; | |
| class CommonExamService extends BaseService | |
| { | |
| // /Condition 1 - Presence of a static member variable | |
| private static $_instance = null; | |
| private $mapper = []; | |
| // /Condition 2 - Locked down the constructor | |
| private function __construct() | |
| { | |
| $this->mapper = ConsolidatedMarkReportServiceMapper::getInstance()->getMapper(); | |
| } | |
| // Prevent any oustide instantiation of this class | |
| // /Condition 3 - Prevent any object or instance of that class to be cloned | |
| private function __clone() | |
| { | |
| } | |
| // Prevent any copy of this object | |
| // /Condition 4 - Have a single globally accessible static method | |
| public static function getInstance() | |
| { | |
| if (!is_object(self::$_instance)) // or if( is_null(self::$_instance) ) or if( self::$_instance == null ) | |
| self::$_instance = new self (); | |
| return self::$_instance; | |
| } | |
| /** | |
| * @return Boolean|null | |
| * @throws ProfessionalException | |
| * @author Krishnajith V | |
| */ | |
| public function checkIfExamControllerIsEnabled() { | |
| try { | |
| $isExamControllerToggleEnabled = PermissionToggle::isEnabled("EXAMCONTROLLER") ? true : false; | |
| }catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| return $isExamControllerToggleEnabled; | |
| } | |
| /** | |
| * update Academic Paper Maximum Mark To Contoller Side | |
| * @throws ProfessionalException | |
| * @author Krishnajith V | |
| */ | |
| public function updateAcademicPaperMaximumMarkToContollerSide($request) { | |
| try { | |
| if($this->checkIfExamControllerIsEnabled()){ | |
| $academicPaperId = $this->realEscapeString($request->academicPaperId); | |
| $externalMaxMark = $this->realEscapeString($request->externalMaxMark); | |
| $assessmentIdQuery = " SELECT distinct | |
| eers.am_assessment_id as assessmentId | |
| FROM | |
| ec_exam_registration_subject eers | |
| WHERE | |
| eers.cm_academic_paper_subjects_id = '$academicPaperId' "; | |
| $assessmentIdsObj = $this->executeQueryForList($assessmentIdQuery); | |
| $assessmentIds = $assessmentIdsObj ? $assessmentIdsObj->assessmentId : []; | |
| if($assessmentIds){ | |
| $assessmentIdsWhereCondition = " ostm.am_assessment_id IN ('".implode("','",$assessmentIds)."') "; | |
| $attendedCountQuery = " SELECT | |
| ostm.id | |
| FROM | |
| oe_student_total_mark ostm | |
| WHERE | |
| $assessmentIdsWhereCondition "; | |
| $userAttendedExamsCount = $this->executeQueryForList($attendedCountQuery); | |
| if (count($userAttendedExamsCount) > 0) { | |
| throw new ProfessionalException ( ProfessionalException::USER_ATTENDED, "Exams cannot be edited since in some exams students have been attended"); | |
| } | |
| AssessmentService::getInstance()->updateMaxMarksInExams($assessmentIds,$externalMaxMark); | |
| } | |
| } | |
| }catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| } | |
| /** | |
| * Get studentDetails By false no ,assessmentId | |
| * @param int $request | |
| * @return object|NULL|\com\linways\base\util\$objectList[] | |
| * @throws ProfessionalException | |
| */ | |
| public function getV4StudentDetailsByFalseNumber($request) | |
| { | |
| $request = $this->realEscapeObject($request); | |
| $sqlR = ""; | |
| $sql = ""; | |
| $regularExamId = ""; | |
| if (!$request->examId || !$request->falseNumber) { | |
| return false; | |
| } | |
| try { | |
| //new digital valuation properties | |
| $digitalValuationProperties = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_CONTROLLER, SettingsConstents::DIGITAL_VALUATION_PROPERTIES); | |
| $digitalValuationProperties = $digitalValuationProperties ? json_decode($digitalValuationProperties) : new \stdClass; | |
| if ($request->examType == ExamType::SUPPLY && $digitalValuationProperties->getRegularFalseNumberForSupply) { | |
| //get regular false number for supply | |
| $sqlR = "SELECT | |
| eer2.id as examRegId,eers2.am_assessment_id as regularExamId | |
| FROM | |
| ec_exam_registration_subject eers | |
| 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.`type` ='SUPPLEMENTARY' | |
| INNER JOIN ec_exam_registration_batch eerb2 ON | |
| eerb2.groups_id = eerb.groups_id AND | |
| eerb2.academicTermId = eerb.academicTermId | |
| INNER JOIN ec_exam_registration eer2 ON | |
| eer2.id = eerb2.ec_exam_registration_id AND | |
| eer2.`type` ='REGULAR' | |
| INNER JOIN ec_exam_registration_subject eers2 ON | |
| eers2.ec_exam_registration_batch_id = eerb2.id AND | |
| eers2.cm_academic_paper_subjects_id = eers.cm_academic_paper_subjects_id | |
| WHERE eers.am_assessment_id IN($request->examId)"; | |
| $regularExamId = $this->executeQueryForObject($sqlR)->regularExamId; | |
| } | |
| $examId = $regularExamId ? $regularExamId : $request->examId; | |
| $sql = "SELECT esar.student_id AS userId from ec_student_assessment_registration esar WHERE esar.properties->>'$.falseNo'= '$request->falseNumber' AND esar.am_assessment_id ='$examId'"; | |
| return $this->executeQueryForObject($sql); | |
| } catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| } | |
| /** | |
| * get staff permissions for assigned digital valuation count | |
| * @param string $request | |
| * @throws ProfessionalException | |
| * @return object|NULL|\com\linways\base\util\$objectList[] | |
| */ | |
| public function getV4DigitalValuationStaffPermission($request) | |
| { | |
| $request = $this->realEscapeObject($request); | |
| $sql = ""; | |
| $permissionSql = ""; | |
| $permission = false; | |
| $condition = ""; | |
| $registeredStudents = []; | |
| if(!$request->staffId || !$request->studentId || !$request->examId || !$request->valCount){ | |
| return $permission; | |
| } | |
| try { | |
| if($request->revalId){ | |
| //To be handled at the time of revaluation | |
| // $digitalValuationProperties = $this->getSettings(SettingsConstents::EXAM_CONTROLLER, SettingsConstents::DIGITAL_VALUATION_PROPERTIES); | |
| // $digitalValuationProperties = $digitalValuationProperties ? current(json_decode($digitalValuationProperties)->revaluation) : ""; | |
| // //FOR SCRUTINY | |
| // if($digitalValuationProperties->considerRevaluationType){ | |
| // $request->markEntryType = $request->scrId ? "SCRUTINY":"REVALUATION"; | |
| // $revaluationTypeId = (int)ExamRevaluationService::getInstance()->getRevaluationTypeIdByOeRequest($request)->revaluationTypeId; | |
| // $condition = $revaluationTypeId ? " AND revaluationTypeId IN ($revaluationTypeId)" : ""; | |
| // } | |
| $sql = "SELECT IF (esar.valuation_details IS NULL, JSON_OBJECT(), esar.valuation_details) AS valuationDetails FROM ec_student_assessment_registration esar WHERE am_assessment_id ='$request->examId' and student_id = $request->studentId AND ec_exam_registration_type IN ('REVALUATION') AND esar.revaluationType = $request->revalId"; | |
| $valuationDetail = $this->executeQueryForObject($sql)->valuationDetails; | |
| $valuationDetail = json_decode($valuationDetail); | |
| $currentValuationStaffDetails = reset(array_filter($valuationDetail->assignedValuationStaffs,function($value)use($request){ | |
| return $value->count == $request->valCount; | |
| })); | |
| if(!empty($currentValuationStaffDetails->addiitonalExamniners)){ | |
| if(in_array($request->staffId,$currentValuationStaffDetails->addiitonalExamniners)){ | |
| $registeredStudents[] = $currentValuationStaffDetails; | |
| } | |
| } | |
| } | |
| else if($request->rvwId){ | |
| // check permission for reviewer | |
| $sql = "SELECT IF (esar.valuation_details IS NULL, JSON_OBJECT(), esar.valuation_details) AS valuationDetails FROM ec_student_assessment_registration esar WHERE am_assessment_id ='$request->examId' and student_id = $request->studentId AND ec_exam_registration_type IN ('REGULAR', 'SUPPLEMENTARY')"; | |
| $valuationDetail = $this->executeQueryForObject($sql)->valuationDetails; | |
| $valuationDetail = json_decode($valuationDetail); | |
| // check reviewer staff permission | |
| $digitalValuationTemplateQuery = "SELECT IF (er.rule IS NULL, JSON_OBJECT(), er.rule) AS rule FROM ec_rule er WHERE er.name ='EXAM_VALUATION_PROCEDURE_RULE' "; | |
| $digitalValuationTemplateRule = $this->executeQueryForObject($digitalValuationTemplateQuery)->rule; | |
| $digitalValuationTemplateRule = json_decode($digitalValuationTemplateRule); | |
| if($digitalValuationTemplateRule->templateName == 'TEMPLATE_WITH_DIGITAL_VALUATION' ){ | |
| $subjectValuationDetailsQuery = "SELECT IF (eers.valuation_details IS NULL, JSON_OBJECT(), eers.valuation_details) AS valuationDetails | |
| FROM ec_exam_registration_subject eers | |
| 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 WHERE eer.type IN ('REGULAR', 'SUPPLEMENTARY') AND eers.am_assessment_id = '$request->examId' "; | |
| $subjectValuationDetails = $this->executeQueryForObject($subjectValuationDetailsQuery)->valuationDetails; | |
| $subjectValuationDetails = json_decode($subjectValuationDetails); | |
| // if only one reviewer in current subject then not to be assign revaluver | |
| $firstValuationStaff = reset(array_filter($subjectValuationDetails->valuationStaffs,function($value){ | |
| return $value->count == '1'; | |
| })); | |
| $secondValuationStaff = reset(array_filter($subjectValuationDetails->valuationStaffs,function($value){ | |
| return $value->count == '2'; | |
| })); | |
| if(count($secondValuationStaff->addiitonalExamniners) > 1){ | |
| $currentValuationDate = reset(array_filter($subjectValuationDetails->valuationDates,function($value)use($request){ | |
| return $value->count == '2' && $value->staffId == $request->staffId; | |
| })); | |
| // mapped valuers ids of current reviewer | |
| $viewerIds = $currentValuationDate->viewerIds; | |
| // fetch student assigned valuer details | |
| $currentValuationStaffDetails = reset(array_filter($valuationDetail->assignedValuationStaffs,function($value)use($request){ | |
| return $value->count == '1'; | |
| })); | |
| // check assigned valuer and mapped valuers are same | |
| foreach($viewerIds as $viewerId){ | |
| if(!empty($currentValuationStaffDetails->addiitonalExamniners)){ | |
| if(in_array($viewerId,$currentValuationStaffDetails->addiitonalExamniners)){ | |
| $registeredStudents[] = $currentValuationStaffDetails; | |
| } | |
| } | |
| } | |
| } | |
| else{ | |
| // mapped valuers ids of first valuer | |
| $viewerIds = $firstValuationStaff->addiitonalExamniners; | |
| // fetch student assigned valuer details | |
| $currentValuationStaffDetails = reset(array_filter($valuationDetail->assignedValuationStaffs,function($value)use($request){ | |
| return $value->count == '1'; | |
| })); | |
| // check assigned valuer and mapped valuers are same | |
| foreach($viewerIds as $viewerId){ | |
| if(!empty($currentValuationStaffDetails->addiitonalExamniners)){ | |
| if(in_array($viewerId,$currentValuationStaffDetails->addiitonalExamniners)){ | |
| $registeredStudents[] = $currentValuationStaffDetails; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| else{ | |
| //FOR REGULAR AND SUPPLY | |
| $sql = "SELECT IF (esar.valuation_details IS NULL, JSON_OBJECT(), esar.valuation_details) AS valuationDetails FROM ec_student_assessment_registration esar WHERE am_assessment_id ='$request->examId' and student_id = $request->studentId AND ec_exam_registration_type IN ('REGULAR', 'SUPPLEMENTARY')"; | |
| $valuationDetail = $this->executeQueryForObject($sql)->valuationDetails; | |
| $valuationDetail = json_decode($valuationDetail); | |
| $currentValuationStaffDetails = reset(array_filter($valuationDetail->assignedValuationStaffs,function($value)use($request){ | |
| return $value->count == $request->valCount; | |
| })); | |
| if(!empty($currentValuationStaffDetails->addiitonalExamniners)){ | |
| if(in_array($request->staffId,$currentValuationStaffDetails->addiitonalExamniners)){ | |
| $registeredStudents[] = $currentValuationStaffDetails; | |
| } | |
| } | |
| } | |
| // $result = $permissionSql ? $this->executeQueryForObject($permissionSql)->id :""; | |
| $permission = $registeredStudents ? true : false; | |
| return $permission; | |
| } catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| } | |
| /** | |
| * check student is eligible for condonation | |
| * @param string $studentRequestArray | |
| * @throws ProfessionalException | |
| * @return array | |
| */ | |
| public function checkStudentIsEligibleForCondonation($studentRequestArray) | |
| { | |
| $studentRequestArray = $this->realEscapeArray($studentRequestArray); | |
| $studentObj = (object) $studentRequestArray; | |
| if (!$studentObj->studentId || !$studentObj->termId || !$studentObj->workFlowId) { | |
| return false; | |
| } | |
| try { | |
| $isExamRegistrationApplyRequest = $studentObj->isExamRegistrationApplyRequest; | |
| $examRegistration = $this->getExamRegistrationDetailsByRequest($studentObj); | |
| $examProperties = $examRegistration->properties ? json_decode($examRegistration->properties) : ''; | |
| if( empty($examRegistration ) || empty($examRegistration->subjects)){ | |
| return false; | |
| } | |
| $minimumAttendancePercentage = $examProperties->minimumAttendancePercentage ? $examProperties->minimumAttendancePercentage : 0; | |
| $examProperties->genderWiseMinimumAttendance = (array) $examProperties->genderWiseMinimumAttendance; | |
| $minimumAttendancePercentage = $examProperties->genderWiseMinimumAttendance[strtoupper($studentObj->gender)] ? $examProperties->genderWiseMinimumAttendance[strtoupper($studentObj->gender)] : $minimumAttendancePercentage; | |
| $attendanceProperties = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_CONTROLLER, SettingsConstents::CONDONATION_GENDER_WISE_ATTENDANCE_RANGE); | |
| $attendanceProperties = $attendanceProperties ? json_decode($attendanceProperties) : []; | |
| $attendanceProperties = (array) $attendanceProperties; | |
| $startRange = 0; | |
| $endRange = 0; | |
| $studentObj->attendanceDateTillDate = $examProperties->attendanceClosingDate; | |
| if ( $attendanceProperties[strtoupper($studentObj->gender)] ){ | |
| $startRange = $attendanceProperties[strtoupper($studentObj->gender)]->startRange; | |
| $endRange = $attendanceProperties[strtoupper($studentObj->gender)]->endRange; | |
| } | |
| $studentAttendance = AttendanceService::getInstance()->getSubjectWiseAttendanceDetails($studentObj); | |
| $hasEligible = 0; | |
| $eligiblePapers = []; | |
| foreach ($studentAttendance->data as $subject){ | |
| if( !in_array($subject->academicPaperId, $examRegistration->subjects)){ | |
| continue; | |
| } | |
| if( $startRange && $endRange ){ | |
| if($subject->percentage >= $startRange && $subject->percentage < $endRange){ | |
| $hasEligible = 1; | |
| $eligiblePapers[$subject->academicPaperId] = $subject->academicPaperId; | |
| } | |
| } else{ | |
| if($subject->percentage < $minimumAttendancePercentage){ | |
| $hasEligible = 1; | |
| $eligiblePapers[$subject->academicPaperId] = $subject->academicPaperId; | |
| } | |
| } | |
| } | |
| if( $isExamRegistrationApplyRequest ){ | |
| return $eligiblePapers; | |
| } | |
| else{ | |
| return $hasEligible == 1 ? true : false; | |
| } | |
| } catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| } | |
| /** | |
| * get exam registration details by request | |
| * @param Object $studentRequest | |
| * @throws ProfessionalException | |
| * @return Object | |
| */ | |
| public function getExamRegistrationDetailsByRequest($studentRequest) | |
| { | |
| $studentRequest = $this->realEscapeObject($studentRequest); | |
| $whereCond = ""; | |
| if ( $studentRequest->workFlowId ){ | |
| $whereCond = " AND eer.properties ->> '$.workFlowId' = '$studentRequest->workFlowId' "; | |
| } | |
| if ( $studentRequest->examRegistrationId ){ | |
| $whereCond = " AND eer.id = '$studentRequest->examRegistrationId' "; | |
| } | |
| if ( !$studentRequest->isSemesterWiseAttenanceRequest ){ | |
| $whereCond .= " AND aps.properties ->> '$.isExternal' = 1"; | |
| } | |
| try { | |
| $sql = "SELECT | |
| eer.id, | |
| eer.name, | |
| eers.cm_academic_paper_subjects_id AS paperSubjectId, | |
| eer.properties, | |
| eerb.properties as batchProperties, | |
| aps.properties ->> '$.classType' AS classType | |
| FROM | |
| student_program_account spa | |
| INNER JOIN ec_exam_registration_batch eerb ON | |
| eerb.groups_id = spa.current_batch_id | |
| INNER JOIN ec_exam_registration eer ON | |
| eer.id = eerb.ec_exam_registration_id | |
| INNER JOIN ec_exam_registration_subject eers ON | |
| eers.ec_exam_registration_batch_id = eerb.id | |
| INNER JOIN cm_academic_paper_subjects aps ON | |
| aps.id = eers.cm_academic_paper_subjects_id | |
| WHERE | |
| spa.student_id =$studentRequest->studentId AND eerb.academicTermId ='$studentRequest->termId' AND eer.trashed IS NULL | |
| $whereCond"; | |
| if ( $studentRequest->isSemesterWiseAttenanceRequest ){ | |
| return $this->executeQueryForObject($sql); | |
| } | |
| else{ | |
| $examSubject = $this->executeQueryForList($sql); | |
| } | |
| $examObj = new \stdClass(); | |
| foreach ( $examSubject as $subject ){ | |
| if( $subject->classType == 'PRACTICAL'){ | |
| continue; | |
| } | |
| $examObj->id = $subject->id; | |
| $examObj->name = $subject->name; | |
| $examObj->properties = $subject->properties; | |
| $examObj->subjects[$subject->paperSubjectId] = $subject->paperSubjectId; | |
| } | |
| return $examObj; | |
| } catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| } | |
| public function getStatusOfWorkflowRequest($studentId,$academicTermId,$workFlowId = '') | |
| { | |
| $studentId = $this->realEscapeString($studentId); | |
| $academicTermId = $this->realEscapeString($academicTermId); | |
| $workFlowId = $this->realEscapeString($workFlowId); | |
| $query = "SELECT `status` FROM wm_workflow_requests WHERE `student_id`='$studentId' AND `academic_term_id`='$academicTermId' "; | |
| if($workFlowId) { | |
| $query .= " AND `wm_workflow_id`='$workFlowId'"; | |
| } | |
| $query .= " ORDER BY FIELD(`status`,'APPROVED','REJECTED','PENDING')"; | |
| try{ | |
| $data = $this->executeQueryForObject($query); | |
| return $data->status; | |
| }catch(\Exception $e) { | |
| throw new ProfessionalException($e->getCode(),$e->getMessage()); | |
| } | |
| } | |
| public function getAllWorkflows ($userType = 'STUDENT') | |
| { | |
| $userType = $this->realEscapeString($userType); | |
| $query = "SELECT id,name, name AS text FROM wm_workflow WHERE is_active='1' AND type='$userType'"; | |
| try{ | |
| $workFlows = $this->executeQueryForList($query); | |
| return $workFlows; | |
| }catch(\Exception $e) { | |
| throw new ProfessionalException($e->getCode(),$e->getMessage()); | |
| } | |
| } | |
| /** | |
| * get Consoliidated Student Data For academics Sem term registration | |
| * @param $request | |
| */ | |
| public function getConsolidatedStudentData($request){ | |
| $request = $this->realEscapeObject($request); | |
| try { | |
| // to get student exam registration and block status | |
| $studentExamRegistrationReq = new \stdClass; | |
| $studentExamRegistrationReq->studentId = $request->studentId; | |
| $studentExamRegistrationReq->groupId = $request->groupId; | |
| $studentExamRegistrations = reset($this->getStudentExamRegistrationDetails($studentExamRegistrationReq)); | |
| $notPublishedExamRegIds = []; | |
| foreach($studentExamRegistrations->exams as $key => $examRegistration){ | |
| // this case to check these cases | |
| // 1. result is published | |
| // 2.student wise with held status | |
| // 3.result blocking | |
| if( !($examRegistration->batchProperties->isResultPublished ) || | |
| (($examRegistration->batchProperties->isResultPublished) && (strtotime($examRegistration->batchProperties->publishingStartDate) > strtotime(date("Y-m-d H:i")))) || | |
| ( $examRegistration->isResultBlocked) || | |
| ($examRegistration->isResultWithHeld)) { | |
| $notPublishedExamRegIds[] = $examRegistration->examRegistrationId; | |
| } | |
| } | |
| $consolidatedStudentRequest = new \stdClass; | |
| $consolidatedStudentRequest->studentId = $request->studentId; | |
| $consolidatedStudentRequest->groupId = $request->groupId; | |
| if(empty( $consolidatedStudentRequest->studentId)){ | |
| throw new ProfessionalException(ProfessionalException::EMPTY_PARAMETERS,"Invaild Request."); | |
| } | |
| $whereQuery = ""; | |
| if(!empty($consolidatedStudentRequest->groupId)) { | |
| $groupIdString = is_array($consolidatedStudentRequest->groupId) ? implode("','",$consolidatedStudentRequest->groupId) : $consolidatedStudentRequest->groupId; | |
| $whereQuery .= " AND g.id IN ('$groupIdString') "; | |
| } | |
| if(!empty($consolidatedStudentRequest->studentId)) { | |
| $studentIdString = is_array($consolidatedStudentRequest->studentId) ? implode(",",$consolidatedStudentRequest->studentId) : $consolidatedStudentRequest->studentId; | |
| $whereQuery .= " AND ecsmd.student_id IN ($studentIdString) "; | |
| } | |
| $query = "SELECT DISTINCT | |
| ecsmd.student_id AS studentId, | |
| ecsmd.groups_id AS groupsId, | |
| atm.id AS termId, | |
| ecsmd.cm_academic_paper_subjects_id AS paperSubjetId, | |
| ecsmd.mark_details AS markDetails, | |
| ecsmd.no_of_chances_taken AS noOfChancesTaken, | |
| ecsmd.total_mark AS totalMarkObtained, | |
| ecsmd.class, | |
| ecsmd.grade, | |
| ecsmd.failed_status AS failedStatus, | |
| ecsmd.mark_history AS markHistory, | |
| s.id as subjectId, | |
| s.code AS code, | |
| s.name AS name, | |
| IF(caps.properties ->> '$.classType' = 'THEORY',1,0) AS isTheory, | |
| IF(esar.properties->>'$.syllabusSubType' = 'MOOC',1,0) AS isMoocSubject, | |
| esar.properties->>'$.studentAttendanceStatus' AS studentAttendanceStatus, | |
| sc.subjectcatID AS categoryId, | |
| sc.subjectcatName AS categoryName, | |
| sc.subjectcatPriority AS categoryPriority, | |
| sc.subjectcatCode AS subjectCategoryCode, | |
| sc.parentID AS categoryParentId, | |
| sc.use_bring_value AS useBringValue, | |
| cc.categoryCode, | |
| cs.`type` as syllabusType, | |
| cs.id as syllabusId, | |
| cclo.name as slot | |
| FROM | |
| ec_consolidated_subject_mark_details ecsmd | |
| INNER JOIN student_program_account spa | |
| ON spa.student_id = ecsmd.student_id | |
| INNER JOIN student_program_batch_log spbl | |
| ON spbl.program_student_id = spa.id AND spbl.batch_group_id = ecsmd.groups_id AND spbl.properties->>'$.academicStatus' IN ('ACTIVE','COMPLETED') | |
| INNER JOIN `groups` g ON | |
| g.id = spbl.batch_group_id | |
| INNER JOIN cm_academic_paper_subjects caps ON | |
| caps.id = ecsmd.cm_academic_paper_subjects_id | |
| INNER JOIN cm_academic_paper cap ON | |
| cap.id = caps.cm_academic_paper_id | |
| INNER JOIN cm_syllabus_academic_term_settings csats ON | |
| csats.id = cap.cm_syllabus_academic_term_settings_id | |
| INNER JOIN cm_syllabus cs ON | |
| cs.id = csats.cm_syllabus_id | |
| INNER JOIN academic_term atm ON | |
| atm.id = csats.academic_term_id AND atm.id = spbl.term_id | |
| INNER JOIN v4_ams_subject s ON | |
| s.id = caps.ams_subject_id | |
| INNER JOIN ec_exam_registration_subject eers ON | |
| eers.cm_academic_paper_subjects_id = caps.id | |
| INNER JOIN ec_student_assessment_registration esar ON | |
| esar.student_id = ecsmd.student_id AND | |
| esar.am_assessment_id = eers.am_assessment_id AND | |
| esar.ec_exam_registration_type = 'REGULAR' | |
| LEFT JOIN subject_category sc ON | |
| sc.subjectcatID = caps.properties->>'$.categoryId' | |
| LEFT JOIN categoryCode cc ON | |
| cc.subject_category_id = caps.properties->>'$.subjectTypeId' | |
| AND cc.subject_category_id = sc.subjectcatID | |
| AND cc.course_type_id = CAST(g.properties->>'$.courseTypeId' AS CHAR) | |
| LEFT JOIN cm_common_list_object cclo ON | |
| cap.slot_id = cclo.id AND cclo.type = 'SLOT' | |
| WHERE | |
| 1 = 1 AND ecsmd.is_active = 1 | |
| $whereQuery ORDER BY cclo.name ASC "; | |
| $subjectsMarkDetails = $this->executeQueryForList($query); | |
| array_walk($subjectsMarkDetails,function($subject,$key) use($request){ | |
| $subject->markDetails = json_decode($subject->markDetails); | |
| $subject->markHistory = json_decode($subject->markHistory); | |
| // $subject->markHistory = ""; | |
| }); | |
| // this case to handle publish exam registration cases | |
| foreach($subjectsMarkDetails as $subjectKey => $subject){ | |
| $subject->credit = $subject->markDetails->credit; | |
| $subject->excludeSubjectFromTotal = $subject->markDetails->excludeSubjectFromTotal; | |
| $subject->markHistory = array_filter($subject->markHistory,function($value) use($notPublishedExamRegIds) { | |
| return !(in_array($value->examRegistrationId,$notPublishedExamRegIds)); | |
| }); | |
| foreach($subject->markHistory as $markHistory){ | |
| if($markHistory->hasRevaluationMark && in_array($markHistory->revaluationId,$notPublishedExamRegIds)){ | |
| $markHistory->failedStatus = $markHistory->withoutRevaluationIsFailed == 1 ? "FAILED" : "PASSED"; | |
| $markHistory->isFailed = $markHistory->failedStatus; | |
| $markHistory->grade = $markHistory->withoutRevaluationGrade; | |
| } | |
| } | |
| $supplyHistory = array_search("SUPPLY", array_column( $subject->markHistory, "examMarkType")); | |
| if($supplyHistory || $supplyHistory === 0){ | |
| $subject->supplyAttempted = 1; | |
| } | |
| $regularHistory = array_filter($subject->markHistory,function($value){ | |
| return $value->examMarkType == "REGULAR"; | |
| }); | |
| if(empty($subject->markHistory) || empty($regularHistory)){ | |
| unset($subjectsMarkDetails[$subjectKey]); | |
| } | |
| usort($subject->markHistory, function($a, $b) { | |
| return ($a->examYear."-".date("m", mktime(0, 0, 0, (int)$a->examMonth, 10))."-".$a->examMarkType) < ($b->examYear."-".date("m", mktime(0, 0, 0, (int)$b->examMonth, 10))."-".$b->examMarkType); | |
| }); | |
| $subject->currentMarkHistory = reset($subject->markHistory); | |
| $subject->markDetails = $subject->currentMarkHistory; | |
| $subject->failedStatus = $subject->markDetails->resultStatus; | |
| $subject->grade = $subject->markDetails->grade; | |
| $subject->examMonth = $subject->markDetails->examMonth; | |
| $subject->examYear = $subject->markDetails->examYear; | |
| $subject->monthName = date("F", mktime(0, 0, 0, (int)$subject->examMonth, 10)); | |
| $subject->syllabusType = $subject->syllabusType; | |
| $subject->syllabusId = $subject->syllabusId; | |
| $subject->markDetails->credit = $subject->credit; | |
| $subject->earnedCredit = $subject->failedStatus == 'FAILED' ? 0 : (int)$subject->markDetails->credit; | |
| if ( $subject->markDetails->studentAttendanceStatus == 'FE' && $request->considerFeStudentGradeChange == 1){ | |
| $subject->grade = 'FE'; | |
| $subject->examMonth = ''; | |
| $subject->examYear = ''; | |
| $subject->monthName = ''; | |
| $subject->credit = ''; | |
| } | |
| // if subject exclude from total then the grade become P or F | |
| if( $subject->excludeSubjectFromTotal == 1){ | |
| $subject->grade = $subject->failedStatus == 'PASSED' ? 'P' : 'F'; | |
| } | |
| } | |
| $whereQuery = ""; | |
| if(!empty($consolidatedStudentRequest->groupId)) { | |
| $groupIdString = is_array($consolidatedStudentRequest->groupId) ? implode("','",$consolidatedStudentRequest->groupId) : $consolidatedStudentRequest->groupId; | |
| $whereQuery .= " AND esmd.groups_id IN ('$groupIdString') "; | |
| } | |
| if(!empty($consolidatedStudentRequest->studentId)) { | |
| $studentIdString = is_array($consolidatedStudentRequest->studentId) ? implode(",",$consolidatedStudentRequest->studentId) : $consolidatedStudentRequest->studentId; | |
| $whereQuery .= " AND esmd.student_id IN ($studentIdString) "; | |
| } | |
| $query = "SELECT | |
| esmd.groups_id AS groupsId, | |
| esmd.student_id AS studentId, | |
| esmd.academic_term_id AS termId, | |
| esmd.mark_details AS markDetails, | |
| esmd.mark_history AS markHistory, | |
| esmd.total_supply_attempt_count AS supplyAttemptCount, | |
| esmd.total_mark AS totalMarkObtained, | |
| esmd.sgpa, | |
| esmd.grade, | |
| esmd.failed_status AS failedStatus, | |
| atm.properties->>'$.orderNo' AS termOrder, | |
| atm.name AS termName | |
| FROM | |
| ec_semester_mark_details esmd | |
| INNER JOIN academic_term atm ON | |
| atm.id = esmd.academic_term_id | |
| WHERE | |
| 1 = 1 | |
| $whereQuery"; | |
| $termMarkDetails = $this->executeQueryForList($query); | |
| array_walk($termMarkDetails,function($term,$key)use($subjectsMarkDetails){ | |
| $term->markDetails = json_decode($term->markDetails); | |
| $term->markHistory = json_decode($term->markHistory); | |
| $term->subjects = array_filter( $subjectsMarkDetails, function($subject)use($term){ | |
| return ($term->groupsId == $subject->groupsId && $term->termId == $subject->termId && $term->studentId == $subject->studentId) ? true : false; | |
| }); | |
| // uasort($term->subjects, function($a, $b) { | |
| // return ($a->slot < $b->slot); | |
| // }); | |
| $term->earnedCredit = array_sum(array_column($term->subjects,'earnedCredit')); | |
| }); | |
| // this case to handle publish exam registration | |
| foreach($termMarkDetails as $termKey => $term){ | |
| $term->markHistory = array_filter($term->markHistory,function($value) use($notPublishedExamRegIds) { | |
| return !(in_array($value->examRegistrationId,$notPublishedExamRegIds)); | |
| }); | |
| foreach($term->markHistory as $markHistory){ | |
| if( in_array($markHistory->revaluationId,$notPublishedExamRegIds)){ | |
| $markHistory->failedStatus = $markHistory->withoutRevaluationFailedStatus; | |
| $markHistory->sgpa = $markHistory->withoutRevaluationsgpa; | |
| } | |
| } | |
| $regularTermHistory = array_filter($term->markHistory,function($value){ | |
| return $value->historyType == "REGULAR"; | |
| }); | |
| if(empty($term->markHistory) || empty($regularTermHistory)){ | |
| unset($termMarkDetails[$termKey]); | |
| } | |
| usort($term->markHistory, function($a, $b) { | |
| return ($a->examYear."-".date("m", mktime(0, 0, 0, (int)$a->examMonth, 10))."-".$a->historyType) < ($b->examYear."-".date("m", mktime(0, 0, 0, (int)$b->examMonth, 10))."-".$b->historyType); | |
| }); | |
| $term->currentMarkHistory = reset($term->markHistory); | |
| $term->markDetails = $term->currentMarkHistory; | |
| $term->failedStatus = $term->markDetails->failedStatus; | |
| $term->sgpa = $term->markDetails->sgpa; | |
| } | |
| $whereQuery = ""; | |
| if(!empty($consolidatedStudentRequest->groupId)) { | |
| $groupIdString = is_array($consolidatedStudentRequest->groupId) ? implode("','",$consolidatedStudentRequest->groupId) : $consolidatedStudentRequest->groupId; | |
| $whereQuery .= " AND ecmd.groups_id IN ('$groupIdString') "; | |
| } | |
| if(!empty($consolidatedStudentRequest->studentId)) { | |
| $studentIdString = is_array($consolidatedStudentRequest->studentId) ? implode(",",$consolidatedStudentRequest->studentId) : $consolidatedStudentRequest->studentId; | |
| $whereQuery .= " AND ecmd.student_id IN ($studentIdString) "; | |
| } | |
| $query = "SELECT | |
| ecmd.groups_id AS groupsId, | |
| g.properties->>'$.programId' AS programId, | |
| ecmd.student_id AS studentId, | |
| ecmd.mark_details AS markDetails, | |
| ecmd.no_of_arrears AS arrears, | |
| ecmd.total_supply_attempt_count AS supplyAttemptCount, | |
| ecmd.percentage AS cgpaPercentage, | |
| ecmd.cgpa, | |
| ecmd.grade, | |
| ecmd.failed_status AS failedStatus, | |
| sa.studentName AS name, | |
| sa.myImage, | |
| sa.studentGender AS gender, | |
| sa.studentBirthday AS dob, | |
| g.name AS batchName, | |
| g.properties ->> '$.description' as batchDescription, | |
| g.properties ->> '$.optionName' as batchOptionName, | |
| g.properties ->> '$.startYear' as admissionYear, | |
| spa.properties->>'$.registerNumber' AS regNo, | |
| spa.properties->>'$.rollNumber' AS rollNo, | |
| gm.properties, | |
| g.properties, | |
| p.name AS programName, | |
| d.name AS degreeName, | |
| GROUP_CONCAT(str.name) AS streamName, | |
| GROUP_CONCAT(str.properties->>'$.abbreviation') AS streamDesc, | |
| ct.course_type AS courseType, | |
| ct.courseTypeID AS courseTypeId | |
| FROM | |
| ec_course_mark_details ecmd | |
| INNER JOIN `groups` g ON | |
| g.id = ecmd.groups_id | |
| INNER JOIN studentaccount sa ON | |
| sa.studentID = ecmd.student_id | |
| INNER JOIN student_program_account spa ON | |
| spa.student_id = sa.studentID | |
| INNER JOIN group_members gm ON | |
| gm.groups_id = g.id | |
| AND CAST(gm.members->>'$.studentId' AS CHAR) = spa.id | |
| INNER JOIN program p ON | |
| p.id = CAST(g.properties->>'$.programId' AS CHAR) | |
| INNER JOIN `degree` d ON | |
| d.id = p.degree_id | |
| INNER JOIN course_type ct ON | |
| ct.courseTypeID = p.course_type_id | |
| LEFT JOIN stream str ON | |
| JSON_SEARCH( p.stream_id, 'one', str.id) IS NOT NULL | |
| WHERE | |
| 1 = 1 | |
| $whereQuery | |
| GROUP BY p.id, sa.studentID"; | |
| $courseMarkDetails = $this->executeQueryForList($query); | |
| $programs = []; | |
| array_walk($courseMarkDetails,function($course,$key)use(&$programs,$termMarkDetails){ | |
| $course->markDetails = json_decode($course->markDetails); | |
| $course->cgpaInWords = CommonUtil::convertNumberToWords($course->cgpa); | |
| $course->academicTerms = array_filter( $termMarkDetails, function($term)use($course){ | |
| return ($term->studentId == $course->studentId) ? true : false; | |
| }); | |
| $course->academicTerms = call_user_func_array('array_merge', array_map( | |
| function ($key, $value) {return array($key => $value);}, | |
| array_column($course->academicTerms, "termId"), | |
| $course->academicTerms) | |
| ); | |
| uasort($course->academicTerms, function($a, $b) { | |
| return ($a->termOrder > $b->termOrder); | |
| }); | |
| $course->academicTerms = array_values($course->academicTerms); | |
| $course->earnedCredit = array_sum(array_column($course->academicTerms,'earnedCredit')); | |
| $course->examYear =$course->markDetails->latestExamYear; | |
| $course->examMonth =$course->markDetails->latestExamMonth; | |
| $programs[$course->programId]->students[$course->studentId] = $course; | |
| }); | |
| } catch (\Exception $e) { | |
| throw new ProfessionalException(ProfessionalException::ERROR_FETCHING,"Cannot fetch details! Please try again."); | |
| } | |
| return $programs; | |
| } | |
| /** | |
| * 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 )"; | |
| } | |
| $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 | |
| 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); | |
| 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 ProfessionalException(ProfessionalException::ERROR_FETCHING_EXAM_REGISTRATION,"Cannot fetch Exam Registration of the student."); | |
| } | |
| return $students; | |
| } | |
| /** | |
| * Checks the student's semester-wise attendance criteria for exam registration. | |
| * | |
| * @param mixed $studentObj The student object containing student details. | |
| * @return mixed Returns the eligibility status for exam registration or the workflow ID for condonation approval. | |
| * @throws ProfessionalException If an error occurs during the process. | |
| */ | |
| public function checkStudentSemesterWiseAttendanceCriteriaForExamRegistration($studentObj) | |
| { | |
| if(is_array($studentObj)){ | |
| $studentObj = (object)$studentObj; | |
| } | |
| $studentObj = $this->realEscapeObject($studentObj); | |
| if (!$studentObj->studentId || !$studentObj->termId || (!$studentObj->workFlowId && !$studentObj->examRegistrationId)) { | |
| return false; | |
| } | |
| $studentId = $studentObj->studentId; | |
| $studentObj->studentGender = $studentObj->gender ? $studentObj->gender : $studentObj->studentGender; | |
| $response = new \stdClass(); | |
| $response->enableDayWiseAttendanceChecking = false; | |
| $response->eligibleToApplyByDayWiseAttendance = true; | |
| $condonationStatus = ""; | |
| try { | |
| if($studentId){ | |
| $minAttendanceForExamRegRule = json_decode(CommonService::getInstance()->getSettings(SettingsConstents::EXAM_CONTROLLER, SettingsConstents::SEMESTER_EXAM_SETTINGS)); | |
| $minAttendanceForExamReg = $minAttendanceForExamRegRule->minAttendanceForExamReg; | |
| $maxAttendanceAllowance = $minAttendanceForExamRegRule->maxAttendanceAllowance; | |
| if($minAttendanceForExamReg->enableDayWiseAttendanceChecking){ | |
| $response->enableDayWiseAttendanceChecking = true; | |
| $response->eligibleToApplyByDayWiseAttendance = false; | |
| $response->isCondonationApproved = false; | |
| $studentObj->isSemesterWiseAttenanceRequest = true; | |
| $examRegistration = $this->getExamRegistrationDetailsByRequest($studentObj); | |
| $examProperties = $examRegistration->properties ? json_decode($examRegistration->properties) : ''; | |
| $batchProperties = $examRegistration->batchProperties ? json_decode($examRegistration->batchProperties) : ''; | |
| if( empty($examRegistration )){ | |
| return false; | |
| } | |
| // get day wise attendance | |
| $studentObj->attendanceClosingDate = $batchProperties->attendanceClosingDate; | |
| $dayWiseAttendance = V4AttendanceService::getInstance()->calculateDayWiseAttendancePercentage($studentObj); | |
| $minimumAttendancePercentage = $examProperties->minimumAttendancePercentage ? $examProperties->minimumAttendancePercentage : 0; | |
| $examProperties->genderWiseMinimumAttendance = (array) $examProperties->genderWiseMinimumAttendance; | |
| if($studentObj->studentGender){ | |
| $minimumAttendancePercentage = $examProperties->genderWiseMinimumAttendance[strtoupper($studentObj->studentGender)] ? $examProperties->genderWiseMinimumAttendance[strtoupper($studentObj->studentGender)] : $minimumAttendancePercentage; | |
| $response->minimumAttendancePercentage = $minimumAttendancePercentage; | |
| $response->haveMinAttendance = $this->checkHaveMinimumAttendance($dayWiseAttendance->attendancePercentage,$minimumAttendancePercentage); | |
| $response->eligibleToApplyByDayWiseAttendance = $response->haveMinAttendance ? true : $response->eligibleToApplyByDayWiseAttendance; | |
| $dayWiseAttendance->maxAttendanceAllowance = $maxAttendanceAllowance; | |
| $response->eligibleForCondonation = $response->eligibleToApplyByDayWiseAttendance ? false : $this->isEligibleForCondonation($dayWiseAttendance,$minimumAttendancePercentage); | |
| if($response->eligibleForCondonation){ | |
| if($examProperties->workFlowId){ | |
| $response->workflowId = $examProperties->workFlowId; | |
| $response->eligibleForCondonation = $examProperties->workFlowId ? $response->eligibleForCondonation : false; | |
| $condonationStatus = $examProperties->workFlowId ? $this->getStatusOfWorkflowRequest($studentObj->studentId, $studentObj->termId,$examProperties->workFlowId) : ''; | |
| } | |
| $response->isCondonationApproved = ($condonationStatus == "APPROVED") ? true : false; | |
| $response->eligibleToApplyByDayWiseAttendance = $response->isCondonationApproved ? true : $response->eligibleToApplyByDayWiseAttendance; | |
| } | |
| } | |
| } | |
| } | |
| if ( $studentObj->fromWorkFlowModule ){ | |
| $isEligible = $response->eligibleForCondonation ? "1" : "0"; | |
| return $isEligible; | |
| } | |
| else{ | |
| return $response; | |
| } | |
| } catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| } | |
| /** | |
| * Checks if the attendance percentage is greater than or equal to the minimum attendance required. | |
| * | |
| * @param float $attPercent The attendance percentage. | |
| * @param float $minAttend The minimum attendance required. | |
| * @return bool Returns true if the attendance percentage is greater than or equal to the minimum attendance required, false otherwise. | |
| */ | |
| private function checkHaveMinimumAttendance($attPercent, $minAttend) | |
| { | |
| $haveMinAttendance = (float) $attPercent >= (float) $minAttend; | |
| return $haveMinAttendance; | |
| } | |
| /** | |
| * Checks if the student is eligible for condonation based on the attendance percentage. | |
| * | |
| * @param mixed $dayWiseAttendance The day-wise attendance details. | |
| * @param float $minAttend The minimum attendance required. | |
| * @return bool Returns true if the student is eligible for condonation, false otherwise. | |
| */ | |
| private function isEligibleForCondonation($dayWiseAttendance,$minAttend){ | |
| // value can be made dynamic later as of now it is 10 | |
| $maxAttendanceAllowance = $dayWiseAttendance->maxAttendanceAllowance ? $dayWiseAttendance->maxAttendanceAllowance : 10; | |
| $totalAttandaceDays = $dayWiseAttendance->totalWorkingDates; | |
| $totalPresentDays = $dayWiseAttendance->totalDaysPresent + $maxAttendanceAllowance; | |
| $attendancePercentage = $totalAttandaceDays ? ($totalPresentDays / $totalAttandaceDays) * 100 : 0; | |
| $haveMinAttendance = $this->checkHaveMinimumAttendance($attendancePercentage,$minAttend); | |
| return $haveMinAttendance; | |
| } | |
| /** | |
| * get Header Details | |
| * @param $request | |
| * @return $header | |
| */ | |
| public function getGroupedHeaderDetails($request){ | |
| $whereQuery = ""; | |
| $examRegWhereQuery = ""; | |
| if(!empty($request->batchId)) { | |
| $whereQuery .= " AND g.id = '$request->batchId' "; | |
| $examRegWhereQuery .= " AND eerb.groups_id = '$request->batchId' "; | |
| } | |
| if(!empty($request->termId)) { | |
| $whereQuery .= " AND csats.academic_term_id = '$request->termId' "; | |
| $examRegWhereQuery .= " AND eerb.properties->>'$.academicTermId' = '$request->termId' "; | |
| } | |
| if(!empty($request->examRegId)) { | |
| $examRegWhereQuery .= " AND ec.id = '$request->examRegId' "; | |
| } | |
| try { | |
| // for mormal curriculum | |
| $sql = "SELECT DISTINCT | |
| cc.properties->'$.noOfMaximumSyllabusOfTypeCanStudy.MINOR' as minorChoosed , | |
| cs.type, | |
| UPPER(concat(IFNULL(vas.name,''),' ( ' ,IFNULL(vas.code,''),' )')) as subjectName, | |
| vas.id as subjectId, | |
| cap.id, | |
| cap.properties->>'$.noOfSubjectThatAStudentCanChoose' as paperCount, | |
| cap.name as paperName, | |
| count(DISTINCT caps.id) as paperSubjectCount, | |
| GROUP_CONCAT(caps.id) as paperSubjectIds, | |
| case when cap.properties->>'$.noOfSubjectThatAStudentCanChoose' <> count(caps.id) THEN 1 | |
| else 0 | |
| end as isgrouped | |
| FROM `groups` g | |
| INNER JOIN `cm_syllabus_academic_term_settings` csats ON csats.cm_syllabus_id IN ( | |
| SELECT csr.cm_syllabus_id FROM cm_curriculum_syllabus_relation csr | |
| WHERE csr.cm_curriculum_id = g.cm_curriculum_id UNION | |
| SELECT vesfbg.cm_syllabus_id FROM v4_extra_syllabus_for_batch_groups vesfbg | |
| WHERE vesfbg.batch_groups_id = g.id | |
| ) | |
| INNER JOIN `cm_academic_paper` cap ON cap.cm_syllabus_academic_term_settings_id = csats.id | |
| INNER JOIN `cm_academic_paper_subjects` caps ON caps.cm_academic_paper_id = cap.id | |
| INNER JOIN `v4_ams_subject` vas ON vas.id = caps.ams_subject_id | |
| INNER JOIN cm_syllabus cs ON cs.id = csats.cm_syllabus_id | |
| INNER JOIN cm_curriculum_syllabus_relation ccsr ON ccsr.cm_syllabus_id = cs.id | |
| INNER JOIN cm_curriculum cc ON cc.id = ccsr.cm_curriculum_id | |
| WHERE 1= 1 AND cc.id = g.cm_curriculum_id | |
| $whereQuery | |
| AND ( | |
| cc.properties->'$.noOfMaximumSyllabusOfTypeCanStudy.MINOR' IS NULL OR | |
| cc.properties->'$.noOfMaximumSyllabusOfTypeCanStudy.MINOR' = '' OR | |
| cs.type <> 'MINOR' | |
| ) | |
| GROUP BY cap.id ORDER BY ccsr.orderNo ASC, cap.properties ->> '$.order' ASC, caps.properties ->> '$.order' ASC "; | |
| $acdemicPaperDetails = $this->executeQueryForList($sql); | |
| // FETCHING THE SUBJECT DETAILS | |
| $sqlData = "SELECT | |
| UPPER(concat(IFNULL(vas.name,''),' ( ' ,IFNULL(vas.code,''),' )')) as subjectName, | |
| caps.id, | |
| vas.id as subjectId | |
| FROM `groups` g | |
| INNER JOIN `cm_syllabus_academic_term_settings` csats ON csats.cm_syllabus_id IN ( | |
| SELECT csr.cm_syllabus_id FROM cm_curriculum_syllabus_relation csr | |
| WHERE csr.cm_curriculum_id = g.cm_curriculum_id UNION | |
| SELECT vesfbg.cm_syllabus_id FROM v4_extra_syllabus_for_batch_groups vesfbg | |
| WHERE vesfbg.batch_groups_id = g.id | |
| ) | |
| INNER JOIN `cm_academic_paper` cap ON cap.cm_syllabus_academic_term_settings_id = csats.id | |
| INNER JOIN `cm_academic_paper_subjects` caps ON caps.cm_academic_paper_id = cap.id | |
| INNER JOIN `v4_ams_subject` vas ON vas.id = caps.ams_subject_id"; | |
| $sqlData .= " WHERE 1 = 1 $whereQuery AND cap.properties->>'$.noOfSubjectThatAStudentCanChoose' > 1 ORDER BY cap.name, vas.name"; | |
| $subjectDetails = $this->executeQueryForList($sqlData); | |
| $subjectMap = []; | |
| foreach ($subjectDetails as $subject) { | |
| $subjectMap[$subject->id] = new \stdClass(); | |
| $subjectMap[$subject->id]->subjectId = $subject->subjectId; | |
| $subjectMap[$subject->id]->subjectName = $subject->subjectName; | |
| } | |
| //For MINOR SELECTED CURRICULUM | |
| $query = "SELECT | |
| cc.id as curriculumId, | |
| cc.properties->>'$.noOfMaximumSyllabusOfTypeCanStudy.MINOR' as minorChoosed , | |
| cs.id as syllabusId, | |
| cs.type, | |
| UPPER(concat(IFNULL(vas.name,''),' ( ' ,IFNULL(vas.code,''),' )')) as subjectName, | |
| vas.id as subjectId, | |
| cap.id as paperId, | |
| cap.properties->>'$.noOfSubjectThatAStudentCanChoose' as paperCount, | |
| cap.name as paperName, | |
| -- count(caps.id) as paperSubjectCount, | |
| -- GROUP_CONCAT(caps.id) as paperSubjectIds, | |
| caps.id as paperSubjectIds | |
| -- case when cap.properties->>'$.noOfSubjectThatAStudentCanChoose' <> count(caps.id) THEN 1 | |
| -- else 1 | |
| -- end as isgrouped | |
| FROM `groups` g | |
| INNER JOIN `cm_syllabus_academic_term_settings` csats ON csats.cm_syllabus_id IN ( | |
| SELECT csr.cm_syllabus_id FROM cm_curriculum_syllabus_relation csr | |
| WHERE csr.cm_curriculum_id = g.cm_curriculum_id | |
| -- UNION | |
| -- SELECT vesfbg.cm_syllabus_id FROM v4_extra_syllabus_for_batch_groups vesfbg | |
| -- WHERE vesfbg.batch_groups_id = g.id | |
| ) | |
| INNER JOIN `cm_academic_paper` cap ON cap.cm_syllabus_academic_term_settings_id = csats.id | |
| INNER JOIN `cm_academic_paper_subjects` caps ON caps.cm_academic_paper_id = cap.id | |
| INNER JOIN `v4_ams_subject` vas ON vas.id = caps.ams_subject_id | |
| INNER JOIN cm_syllabus cs ON cs.id = csats.cm_syllabus_id | |
| INNER JOIN cm_curriculum_syllabus_relation ccsr ON ccsr.cm_syllabus_id = cs.id | |
| INNER JOIN cm_curriculum cc ON cc.id = ccsr.cm_curriculum_id | |
| WHERE 1= 1 AND cc.id = g.cm_curriculum_id | |
| $whereQuery | |
| AND | |
| (cc.properties->'$.noOfMaximumSyllabusOfTypeCanStudy.MINOR' IS NOT NULL OR | |
| cc.properties->'$.noOfMaximumSyllabusOfTypeCanStudy.MINOR' <> '') | |
| AND cs.type = 'MINOR' | |
| -- AND cc.id = '3cc5026e350d11eeb' | |
| -- AND g.id = 'aGiTFFjtWkgBbqfRz' | |
| -- AND csats.academic_term_id = 3 | |
| -- GROUP BY cap.id | |
| ORDER BY ccsr.orderNo ASC, cap.properties ->> '$.order' ASC, caps.properties ->> '$.order' ASC "; | |
| $examRegisteredPaperQuery = " SELECT eers.cm_academic_paper_subjects_id as paperSubjectId from ec_exam_registration ec | |
| INNER JOIN ec_exam_registration_batch eerb ON eerb.ec_exam_registration_id = ec.id | |
| INNER JOIN ec_exam_registration_subject eers ON eers.ec_exam_registration_batch_id = eerb.id | |
| WHERE 1 =1 $examRegWhereQuery "; | |
| // $academicPaperMinors = $this->executeQueryForList($query); | |
| $result = $this->executeQueryForList($query, $this->mapper[ConsolidatedMarkReportServiceMapper::HEADER_LOOPING_MINOR]); | |
| $selectedPapers = []; | |
| $remainingSyllabus = $result[0]->syllabusDetails; | |
| $limit = $result[0]->minorChoosed; | |
| while (count($selectedPapers) < $limit && !empty($remainingSyllabus)) { | |
| $highestPaper = null; | |
| $highestIndex = null; | |
| // Loop through syllabusDetails to find the highest paperCount | |
| foreach ($remainingSyllabus as $index => $syllabus) { | |
| if (!empty($syllabus->paperDetails)) { | |
| // Sort the paperDetails array by paperCount in descending order | |
| usort($syllabus->paperDetails, function ($a, $b) { | |
| return $b->paperCount <=> $a->paperCount; | |
| }); | |
| // Check the highest paper from this syllabus | |
| $currentHighestPaper = $syllabus->paperDetails[0]; | |
| if ($highestPaper === null || $currentHighestPaper->paperCount > $highestPaper->paperCount) { | |
| $highestPaper = $currentHighestPaper; | |
| $highestIndex = $index; | |
| } | |
| } | |
| } | |
| if ($highestPaper) { | |
| $selectedPapers[] = $highestPaper; | |
| // Remove the selected paper from the syllabus's paperDetails | |
| array_shift($remainingSyllabus[$highestIndex]->paperDetails); | |
| // If the syllabus has no more papers, remove it from consideration | |
| if (empty($remainingSyllabus[$highestIndex]->paperDetails)) { | |
| unset($remainingSyllabus[$highestIndex]); | |
| } | |
| } | |
| } | |
| foreach ($result[0]->syllabusDetails as $syllabus) { | |
| foreach ($syllabus->paperDetails as $paper) { | |
| foreach ($paper->paperSubjectDetails as $subjectDetail) { | |
| $paperSubjectIds[] = $subjectDetail->paperSubjectIds; | |
| } | |
| } | |
| } | |
| foreach ($selectedPapers as $paper) { | |
| foreach ($paper->paperSubjectDetails as $subjectDetail) { | |
| $paperSubjectIds[] = $subjectDetail->paperSubjectIds; | |
| } | |
| } | |
| $paperSubjectIds = array_unique($paperSubjectIds); | |
| $examRegisteredPaperDetails = array_column( $this->executeQueryForList($examRegisteredPaperQuery),'paperSubjectId'); | |
| $paperSubjectIds = array_intersect($examRegisteredPaperDetails, $paperSubjectIds); | |
| $paperDetails = []; | |
| foreach ($acdemicPaperDetails as $key => $paper) { | |
| $count = ($paper->paperCount === "" || $paper->paperCount == 1) ? 1 : $paper->paperCount ; | |
| // Add copies of the object up to the specified count | |
| for ($i = 0; $i < $count; $i++) { | |
| $newItem = new \stdClass(); | |
| $newItem = clone $paper; | |
| $newItem->paperSubjectIds = explode(",", $paper->paperSubjectIds); | |
| $newItem->index = $i; | |
| $newItem->id = $paper->id .'' . $i; | |
| if($count > 1 && $paper->paperSubjectCount === $count){ | |
| $newItem->subjectName = isset($subjectMap[$newItem->paperSubjectIds[$i]]) ? $subjectMap[$newItem->paperSubjectIds[$i]]->subjectName : $newItem->subjectName; | |
| $newItem->subjectId = isset($subjectMap[$newItem->paperSubjectIds[$i]]) ? $subjectMap[$newItem->paperSubjectIds[$i]]->subjectId : $newItem->subjectId; | |
| $newItem->paperSubjectIds = isset($subjectMap[$newItem->paperSubjectIds[$i]]) ? [$newItem->paperSubjectIds[$i]] : $newItem->paperSubjectIds; | |
| } | |
| if(!empty(array_intersect($newItem->paperSubjectIds, $examRegisteredPaperDetails))){ | |
| $paperDetails[] = $newItem; | |
| } | |
| } | |
| } | |
| // FILTERING THE PAPERDETAILS WITH EXAM REGISTERD ONLY PAPER SUBJECTS | |
| // Filter the paperDetails array | |
| $filteredPaperDetails = array_filter($paperDetails, function ($paper) use ($examRegisteredPaperDetails) { | |
| if (isset($paper->paperSubjectIds)) { | |
| // Filter the paperSubjectIds | |
| $paper->paperSubjectIds = array_values(array_filter($paper->paperSubjectIds, function ($id) use ($examRegisteredPaperDetails) { | |
| return in_array($id, $examRegisteredPaperDetails); | |
| })); | |
| // If paperSubjectIds is empty, remove this object | |
| if (empty($paper->paperSubjectIds)) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| }); | |
| // Reindex the filtered array | |
| $paperDetails = array_values($filteredPaperDetails); | |
| $paperDetailsMinor = []; | |
| // foreach ($academicPaperMinors as $key => $paper) { | |
| // $count = ($paper->minorChoosed === "" || $paper->minorChoosed == 1) ? 1 : $paper->minorChoosed ; | |
| // // Add copies of the object up to the specified count | |
| // for ($i = 0; $i < $count; $i++) { | |
| // $newItem = new \stdClass(); | |
| // $newItem = clone $paper; | |
| // $newItem->paperSubjectIds = explode(",", $paper->paperSubjectIds); | |
| // $newItem->index = $i; | |
| // $newItem->id = $paper->id .'' . $i; | |
| // if(!empty(array_intersect($newItem->paperSubjectIds, $examRegisteredPaperDetails))){ | |
| // $paperDetailsMinor[] = $newItem; | |
| // } | |
| // } | |
| // } | |
| $idx = 1; | |
| foreach ($selectedPapers as $key => $paper) { | |
| $count = $paper->paperCount; | |
| // Add copies of the object up to the specified count | |
| for ($i = 0; $i < $count; $i++) { | |
| $newItem = new \stdClass(); | |
| $newItem = clone $paper; | |
| $newItem->paperName = 'MINOR'.' '.($idx); | |
| $newItem->isgrouped = 1; | |
| $newItem->paperSubjectIds = $paperSubjectIds; | |
| $newItem->index = $i; | |
| $newItem->id = $paper->id .'' . $i . $idx; | |
| if(!empty(array_intersect($newItem->paperSubjectIds, $examRegisteredPaperDetails))){ | |
| $paperDetailsMinor[] = $newItem; | |
| } | |
| $idx++; | |
| } | |
| } | |
| $paper = new \stdClass(); | |
| $mergedData = array_merge($paperDetails,$paperDetailsMinor); | |
| if( $request->hasSubCourse ){ | |
| $request->distinctPaperIds = array_unique(array_reduce($mergedData, function ($carry, $item) { | |
| return array_merge($carry, $item->paperSubjectIds); | |
| }, [])); | |
| $distinctPapersWithClassType = $this->getSubCourseRelationByPaperIds($request); | |
| foreach ($mergedData as $groupKey => $group) { | |
| foreach($group->paperSubjectIds as $paperKey => $singlePaperId){ | |
| if (strpos($distinctPapersWithClassType[$singlePaperId]->classType, "THEORY") !== false && $distinctPapersWithClassType[$singlePaperId]->parentSubjectId) { | |
| $found = 0; | |
| foreach ($mergedData as $groupKey2 => $group2) { | |
| if($found == 1){ | |
| break; | |
| } | |
| foreach($group2->paperSubjectIds as $paperKey2 => $singlePaperId2){ | |
| if ($singlePaperId2 != $singlePaperId && $distinctPapersWithClassType[$singlePaperId2]->parentSubjectId == $distinctPapersWithClassType[$singlePaperId]->parentSubjectId && strpos($distinctPapersWithClassType[$singlePaperId]->classType, "THEORY") == false) { | |
| unset($mergedData[$groupKey2]->paperSubjectIds[$paperKey2]); | |
| $mergedData[$groupKey]->paperSubjectIds[$paperKey] = $distinctPapersWithClassType[$singlePaperId]->parentSubjectId; | |
| $mergedData[$groupKey]->hasSubCourses = 1; | |
| $mergedData[$groupKey]->subCourses[$distinctPapersWithClassType[$singlePaperId]->parentSubjectId] = $distinctPapersWithClassType[$singlePaperId]; | |
| $found = 1; | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| $paper->subCourses = $distinctPapersWithClassType; | |
| foreach ($mergedData as $groupKey => $group) { | |
| if (empty($group->paperSubjectIds)) { | |
| unset($mergedData[$groupKey]); | |
| } | |
| } | |
| } | |
| $paper->paperDetails = $mergedData; | |
| // $paper->paperDetailsMinor = $paperDetailsMinor; | |
| return $paper; | |
| } catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| } | |
| /** | |
| * Fetch the details of students those who have registered for exam. | |
| * | |
| * @param string $batchId | |
| * @param string $currentTermId | |
| * @return array Returns array of student program accountIds of students those who have registered for exam. | |
| */ | |
| public function fetchExamRegisteredStudentsForTermPromotion($batchId,$currentTermId){ | |
| $sql = "SELECT DISTINCT | |
| spa.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_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 cm_academic_paper_subjects caps ON | |
| caps.id = eers.cm_academic_paper_subjects_id | |
| INNER JOIN v4_ams_subject vas ON | |
| vas.id = caps.ams_subject_id | |
| INNER JOIN studentaccount s ON | |
| s.studentID = esar.student_id | |
| INNER JOIN student_program_account spa ON | |
| spa.student_id = s.studentID | |
| WHERE eerb.groups_id = '".$batchId."' AND esar.properties->>'$.registrationStatus' = 'REGISTERED' AND eerb.academicTermId = '$currentTermId' | |
| GROUP BY spa.id"; | |
| $studentList = $this->executeQueryForList($sql); | |
| return $studentList; | |
| } | |
| /** | |
| * Retrieves the sub-course relation by student based on the search request. | |
| * | |
| * @param object $searchRequest The search request object containing the criteria for the query. | |
| */ | |
| public function getSubCourseRelationByPaperIds($searchRequest) { | |
| $searchRequest = $this->realEscapeObject($searchRequest); | |
| $whereQuery = ""; | |
| $whereQuery = ""; | |
| if(!empty($searchRequest->distinctPaperIds)){ | |
| $paperSubjectIdString = is_array($searchRequest->distinctPaperIds) ? "'" . implode("','",$searchRequest->distinctPaperIds) . "'" : "'".$searchRequest->distinctPaperIds."'"; | |
| $whereQuery .= " AND caps.id IN ( $paperSubjectIdString )"; | |
| } | |
| try { | |
| $query = "SELECT | |
| vsrm.parent_subject_id AS parentSubjectId, | |
| vsrm.child_subject_id AS childSubjectId, | |
| caps.properties->>'$.classType' as classType, | |
| caps.id as paperSubjectId, | |
| vas.code AS parentCode, | |
| vas.name AS parentName | |
| FROM | |
| cm_academic_paper_subjects caps | |
| INNER JOIN v4_subject_relation_mapping vsrm ON | |
| vsrm.child_subject_id = caps.ams_subject_id | |
| INNER JOIN v4_ams_subject vas ON | |
| vas.id = vsrm.parent_subject_id | |
| WHERE | |
| 1=1 "; | |
| $subjectList = $this->executeQueryForList($query. $whereQuery); | |
| $subCourseSubjects = []; | |
| foreach ($subjectList as $subject) { | |
| $subCourseSubjects[$subject->paperSubjectId]->childSubjectId = $subject->childSubjectId; | |
| $subCourseSubjects[$subject->paperSubjectId]->parentSubjectId = $subject->parentSubjectId; | |
| $subCourseSubjects[$subject->paperSubjectId]->parentCode = $subject->parentCode; | |
| $subCourseSubjects[$subject->paperSubjectId]->parentName = $subject->parentName; | |
| $subCourseSubjects[$subject->paperSubjectId]->classType = $subject->classType; | |
| } | |
| } catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| return $subCourseSubjects; | |
| } | |
| /** | |
| * Check if the student has any active mandatory online exams | |
| * | |
| * This function verifies if a student has any currently active online exams that are mandatory | |
| * by checking if the current time falls within 15 minutes before the start time and the end time | |
| * of any registered exams for the student. | |
| * | |
| * @param string|int $studentId The ID of the student to check | |
| * @return object|null Returns student ID if active exams exist, null otherwise | |
| * @throws ProfessionalException If an error occurs during the database query | |
| * @author CommonExamService | |
| */ | |
| public function chekActiveMandatoryOnlineExam($studentId) { | |
| $studentId = $this->realEscapeString($studentId); | |
| try { | |
| $query = "SELECT esar.student_id as studentId | |
| FROM oe_exams oe | |
| INNER JOIN ec_exam_registration_subject eers ON eers.am_assessment_id = oe.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_student_assessment_registration esar ON esar.am_assessment_id = eers.am_assessment_id AND esar.ec_exam_registration_type = eer.type | |
| WHERE NOW() BETWEEN DATE_SUB(oe.exam_start_time, INTERVAL 15 MINUTE) AND oe.exam_end_time | |
| AND esar.properties ->> '$.registrationStatus' = 'REGISTERED' | |
| AND oe.type = 'EXAM_CONTROLLER' | |
| AND oe.identifying_context->>'$.type' = 'ONLINE_EXAM' | |
| AND oe.is_archived = 0 | |
| AND esar.student_id = '$studentId' | |
| AND eer.trashed IS NULL"; | |
| $onlineExamDetails = $this->executeQueryForObject($query); | |
| return $onlineExamDetails; | |
| } catch (\Exception $e) { | |
| throw new ProfessionalException($e->getCode(), $e->getMessage()); | |
| } | |
| } | |
| } |