Skip to content

Instantly share code, notes, and snippets.

@makoru-hikage
Last active March 8, 2017 07:51
Show Gist options
  • Save makoru-hikage/032f177897374c882b2c2d93cc33886f to your computer and use it in GitHub Desktop.
Save makoru-hikage/032f177897374c882b2c2d93cc33886f to your computer and use it in GitHub Desktop.
Checks if a student is eligible to take a course.
<?php
/**
* CourseEnrollmentEligibility
*/
class CourseEnrollmentEligibility extends ModelService {
/**
* student
* @var \DeltaX\Models\Student
*/
protected $student;
/**
* curriculumItem
* @var \DeltaX\Models\Curriculum
*/
protected $curriculumItem;
/**
* yearStanding
* @var int
*/
protected $yearStanding;
/**
* term
* @var int
*/
protected $term;
/**
* setStudent
* @param string $code
* @return self
*/
public function setTerm(string $code) {
$term = $this->repoInvoker->find('school_calendar', $code);
if (empty($student)){
throw new InvalidTermException;
}
$this->term = $term;
return $this;
}
/**
* setStudent
* @param string $studentNumber
* @return self
*/
public function setStudent(string $studentNumber) {
$student = $this->repoInvoker->find('student', $studentNumber);
if (empty($student)){
throw new InvalidStudentNumberException;
}
$this->student = $student;
return $this;
}
public function setCurriculumItem(string $code){
$degree_id = $this->student->degree_id;
$this->curriculumItem = $this->repoInvoker->entity('curricula', function() use ($code){
return $entity->with('curriculum_term', 'course')
->whereHas('course', function($entity) use ($code){
$entity->where('code', $code);
}));
})->where([['degree_id', $degree_id]])
->get()
->first();
return $this;
}
/**
* determineYearStandingPrerequisite
* @return self
*/
protected function determineYearStandingPrerequisite() {
$yearLevel = $this->repoInvoker->entity('term_attendance')
->where([['student_id', $this->student->id]])
->max('year_level');
$yearLevel = $this->curriculumItem->curriculum_term->year_level;
if ($this->yearStanding > $yearLevel) {
return [
'available' => false,
'message' => 'Year level is not enough'
'year_standing' => $yearLevel,
'required' => $requiredYearLevel
];
}
return $this;
}
protected function determinePastEnrollment(){
$prerequisiteItems = $this->determinePrerequisites();
$pastEnrollment = $this->repoInvoker->entity('curricula', function($entity) use ($prerequisiteItems){
return $entity
->select([
'curricula.id'
'courses.code AS course_code',
'curricula.is_major',
'courses.name',
'courses.credits_in_lecture',
'courses.credits_in_lab',
'curricula.lec_contact_hrs',
'curricula.lab_contact_hrs',
'curriculum_terms.year_level',
'courses.code AS dependent_course',
'enrolled_courses.final_grade',
'remarks.remark',
])->join('courses', 'curricula.course_id', '=', 'courses.id')
->leftJoin('enrolled_courses', 'enrolled_courses.curriculum_id', '=', 'curricula.id')
->join('remarks', 'enrolled_courses.remark_id', '=', 'remarks.id')
->leftJoin('term_attendance', 'enrolled_courses.term_attendance_id', '=', 'term_attendance.id')
->leftJoin('school_calendar', 'term_attendance.school_calendar_id', '=', 'school_calendar.id')
->whereIn('curricula.id', $prerequisiteItems->pluck('id'));
})->where([
['curricula.id', $this->curriculumItem->id],
['enrolled_courses.student_id', $this->student->id]
], true)
->get();
return $pastEnrollment;
}
protected function determinePrerequisites(){
return $this->repoInvoker->entity('curricula', function($entity){
return $entity
->select([
'prerequisites.id',
'prerequisites.course_id',
'prerequisite_courses.code',
'prerequisite_courses.name',
'prerequisite_courses.credits_in_lecture',
'prerequisite_courses.credits_in_lab',
'prerequisites.is_major',
'prerequisites.is_nth_year_standing',
'prerequisites.lec_contact_hrs',
'prerequisites.lab_contact_hrs'
])->join('courses', 'curricula.course_id', '=', 'courses.id')
->leftJoin('curriculum_prerequisites', 'curriculum_prerequisites.dependent_id', '=', 'curricula.id')
->leftJoin('curricula AS prerequisites', 'curriculum_prerequisites.prerequisite_id', '=', 'prerequisites.id')
->leftJoin('courses AS prerequisite_courses', 'prerequisites.course_id', '=', 'prerequisite_courses.id')
})->where([['curricla.id', $this->curriculumItem->id]])->get();
}
public function checkOpenSessions(){
$openSessions = $this->repoInvoker->entity('course_sessions', function($entity){
return $entity
->select([
'course_sessions.session_alias',
'courses.code'
])
->join('courses', 'course_sessions.course_id', '=', 'courses.id')
->join('school_calendar', 'course_sessions.school_calendar_id', '=', 'courses.id')
})->where([
['course_sessions.course_id', $this->curriculumItem->course_id],
['course_sessions.school_calendar_id', $this->term->id]
])->get();
if(empty($openSessions)){
return [
'available' => false,
'message' => 'No available classes for this term'
];
}
}
/**
* checkEligibility
* @return array
*/
public function checkEligibility() {
//Does the item require class standing?
if ($this->curriculumItem['is_nth_year_standing']) {
$yearStanding = $this->determineYearStandingPrerequisite();
if ( ! $yearStanding['available'] ){
return $yearStanding;
}
}
$openSessions = $this->checkOpenSessions();
//Are there any open sessions?
if ( ! $openSessions['available'] ) {
return $openSessions;
}
$prerequisiteItems = $this->determinePrerequisites();
$pastEnrollment = $this->determinePastEnrollment();
$prerequisiteItemsCount = $prerequisiteItems->groupBy('id')->count();
$pastEnrollmentCount = $prerequisiteItems
->groupBy('id')->whereIn('remark', ['PASSED','F','S','VS','O'])->count();
//Count all the prerequisite items and the ones the student have passed.
$result = [
'prerequisites' => $prerequisiteItems,
'courses_taken' => $pastEnrollment,
'count_of_prerequisite_courses' => $prerequisiteItemsCount,
'count_of_passed_prerequisites' => $pastEnrollmentCount,
'availability' => $pastEnrollmentCount >= $prerequisiteItemsCount
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment