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()); | |
} | |
} | |
} |