From d2e8369f1339eab322874e8da24aa42fb9fa7daa Mon Sep 17 00:00:00 2001 From: NuwanJ Date: Fri, 18 Oct 2024 13:14:05 +0530 Subject: [PATCH 1/4] Changes to support the requirements --- .../AcademicProgram/AcademicProgram.php | 27 +++++++++-- app/Http/Livewire/Backend/CreateCourses.php | 25 +++++++++- app/Http/Livewire/Backend/EditCourses.php | 48 ++++++++++++++----- ...2024_10_11_124838_alter_column_version.php | 39 +++++++++++++++ .../views/backend/semesters/create.blade.php | 3 +- .../views/backend/semesters/edit.blade.php | 3 +- .../livewire/backend/create-courses.blade.php | 18 +++---- .../livewire/backend/edit-courses.blade.php | 17 ++++--- 8 files changed, 144 insertions(+), 36 deletions(-) create mode 100644 database/migrations/2024_10_11_124838_alter_column_version.php diff --git a/app/Domains/AcademicProgram/AcademicProgram.php b/app/Domains/AcademicProgram/AcademicProgram.php index 248b4ceb..4f72bc67 100644 --- a/app/Domains/AcademicProgram/AcademicProgram.php +++ b/app/Domains/AcademicProgram/AcademicProgram.php @@ -17,13 +17,30 @@ public static function getAcademicPrograms(): array ]; } - public static function getVersions(): array + public static function getVersions($academicProgram = null): array { // TODO integrate with Taxonomies - return [ - 1 => 'Current Curriculum', - 2 => 'Curriculum - Effective from E22' + $academicPrograms = [ + 'undergraduate' => [ + 1 => 'Current Curriculum', + 2 => 'Curriculum - Effective from E22' + ], + 'postgraduate' => [ + 3 => 'Current Curriculum - PG', + ] ]; + + if ($academicProgram == null) { + $allAcademicPrograms = []; + foreach ($academicPrograms as $programs) { + foreach ($programs as $key => $value) $allAcademicPrograms[$key] = $value; + } + return $allAcademicPrograms; + } else if (array_key_exists($academicProgram, $academicPrograms)) { + return $academicPrograms[$academicProgram]; + } else { + return []; + } } public static function getTypes(): array @@ -35,4 +52,4 @@ public static function getTypes(): array 'TE' => 'Technical Elective' ]; } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Backend/CreateCourses.php b/app/Http/Livewire/Backend/CreateCourses.php index f544b1fa..aa59e11b 100644 --- a/app/Http/Livewire/Backend/CreateCourses.php +++ b/app/Http/Livewire/Backend/CreateCourses.php @@ -16,6 +16,8 @@ class CreateCourses extends Component //for selectors public $academicProgramsList = []; public $semestersList = []; + public $curriculumList = []; + //form inputs //1st form step @@ -46,7 +48,7 @@ public function rules() return [ 'academicProgram' => 'required|string', 'semester' => 'required|string', - 'version' => ['required', 'string', Rule::in(array_keys(Course::getVersions()))], + 'version' => ['required', Rule::in(array_keys(Course::getVersions()))], 'type' => ['required', 'string', Rule::in(array_keys(Course::getTypes()))], 'code' => 'required|string|unique:courses,code', 'name' => 'required|string|max:255', @@ -213,6 +215,7 @@ public function submit() public function updatedAcademicProgram() { + $this->updateCurriculumList(); $this->updateSemestersList(); } @@ -221,6 +224,21 @@ public function updatedVersion() $this->updateSemestersList(); } + + public function updateCurriculumList() + { + if ($this->academicProgram) { + $this->curriculumList = Course::getVersions($this->academicProgram); + } else { + $this->curriculumList = []; + } + + if (!array_key_exists($this->version, $this->curriculumList)) { + // Unset if it not belongs to + $this->version = null; + } + } + public function updateSemestersList() { if ($this->academicProgram && $this->version) { @@ -231,6 +249,11 @@ public function updateSemestersList() } else { $this->semestersList = []; } + + if (count($this->semestersList) == 0 || !array_key_exists($this->semester, $this->semestersList)) { + // Unset if it not belongs to + $this->semester = null; + } } diff --git a/app/Http/Livewire/Backend/EditCourses.php b/app/Http/Livewire/Backend/EditCourses.php index 0409f61c..0a4838a7 100644 --- a/app/Http/Livewire/Backend/EditCourses.php +++ b/app/Http/Livewire/Backend/EditCourses.php @@ -17,6 +17,7 @@ class EditCourses extends Component // Selectors public $academicProgramsList = []; public $semestersList = []; + public $curriculumList = []; // Form inputs // 1st form step @@ -50,7 +51,7 @@ public function rules() $validationRules = [ 'academicProgram' => 'required|string', 'semester' => 'required|int', - 'version' => ['required', 'string', Rule::in(array_keys(Course::getVersions()))], + 'version' => ['required', Rule::in(array_keys(Course::getVersions()))], 'type' => ['required', 'string', Rule::in(array_keys(Course::getTypes()))], 'code' => 'required|string', 'name' => 'required|string|max:255', @@ -138,7 +139,12 @@ protected function validateMarksAllocation() public function updated($propertyName) { $this->canUpdate = false; - $this->validateCurrentStep(); + + if (!($this->version == null || $this->semester == null)) { + // This to allow fillings while either version or semester is null + $this->validateCurrentStep(); + } + if ($this->getErrorBag()->has('marks_allocation.total')) { return; } @@ -181,8 +187,12 @@ public function mount(Course $course) ]; })->toArray(); $this->prerequisites = $course->prerequisites->pluck('id')->toArray(); + // Update semesters list based on academic program and version $this->updateSemestersList(); + + // Update curriculum list based on academic program + $this->updateCurriculumList(); } public function updatePrerequisites($selectedCourses) @@ -218,20 +228,14 @@ public function previous() public function update() { - try { - - $this->validateCurrentStep(); - $this->updateCourse(); - return redirect()->route('dashboard.courses.index')->with('Success', 'Course updated successfully.'); - } catch (\Exception $e) { - \Log::error("Error in update method: " . $e->getMessage()); - session()->flash('error', 'There was an error updating the course: ' . $e->getMessage()); - } - $this->resetForm(); + $this->validateCurrentStep(); + $this->updateCourse(); + return redirect()->route('dashboard.courses.index')->with('Success', 'Course updated successfully.'); } public function updatedAcademicProgram() { + $this->updateCurriculumList(); $this->updateSemestersList(); } @@ -240,6 +244,19 @@ public function updatedVersion() $this->updateSemestersList(); } + public function updateCurriculumList() + { + if ($this->academicProgram) { + $this->curriculumList = Course::getVersions($this->academicProgram); + } else { + $this->curriculumList = []; + } + if (!array_key_exists($this->version, $this->curriculumList)) { + // Unset if it not belongs to + $this->version = ''; + } + } + public function updateSemestersList() { if ($this->academicProgram && $this->version) { @@ -250,6 +267,11 @@ public function updateSemestersList() } else { $this->semestersList = []; } + + if (count($this->semestersList) == 0 || !array_key_exists($this->semester, $this->semestersList)) { + // Unset if it not belongs to + $this->semester = ''; + } } protected function updateCourse() @@ -334,4 +356,4 @@ public function render() { return view('livewire.backend.edit-courses'); } -} \ No newline at end of file +} diff --git a/database/migrations/2024_10_11_124838_alter_column_version.php b/database/migrations/2024_10_11_124838_alter_column_version.php new file mode 100644 index 00000000..6043e33b --- /dev/null +++ b/database/migrations/2024_10_11_124838_alter_column_version.php @@ -0,0 +1,39 @@ +integer('version')->change(); + }); + Schema::table('courses', function (Blueprint $table) { + $table->integer('version')->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('semesters', function (Blueprint $table) { + $table->enum('version', array_keys(Course::getVersions()))->change(); + }); + Schema::table('courses', function (Blueprint $table) { + $table->enum('version', array_keys(Course::getVersions()))->change(); + }); + } +} diff --git a/resources/views/backend/semesters/create.blade.php b/resources/views/backend/semesters/create.blade.php index 08b14f42..e439d556 100644 --- a/resources/views/backend/semesters/create.blade.php +++ b/resources/views/backend/semesters/create.blade.php @@ -55,8 +55,9 @@
- {!! Form::label('version', 'Version*', ['class' => 'col-md-2 col-form-label']) !!} + {!! Form::label('version', 'Curriculum*', ['class' => 'col-md-2 col-form-label']) !!}
+ {{-- TODO make this depends from the Academic Program --}} {!! Form::select('version', \App\Domains\AcademicProgram\Semester\Models\Semester::getVersions(), null, [ 'class' => 'form-select', 'placeholder' => 'Select Version', diff --git a/resources/views/backend/semesters/edit.blade.php b/resources/views/backend/semesters/edit.blade.php index 2fb08e96..e84ffd49 100644 --- a/resources/views/backend/semesters/edit.blade.php +++ b/resources/views/backend/semesters/edit.blade.php @@ -53,8 +53,9 @@
- {!! Form::label('version', 'Version*', ['class' => 'col-md-2 col-form-label']) !!} + {!! Form::label('version', 'Curriculum*', ['class' => 'col-md-2 col-form-label']) !!}
+ {{-- TODO make this depends from the Academic Program --}} {!! Form::select('version', \App\Domains\AcademicProgram\Semester\Models\Semester::getVersions(), null, [ 'class' => 'form-control', 'required' => true, diff --git a/resources/views/livewire/backend/create-courses.blade.php b/resources/views/livewire/backend/create-courses.blade.php index 56c8bbe7..9c8f2b1c 100644 --- a/resources/views/livewire/backend/create-courses.blade.php +++ b/resources/views/livewire/backend/create-courses.blade.php @@ -25,11 +25,12 @@
-
- @foreach ($academicProgramsList as $academicProgramId => $academicProgramTitle)
- +
- - @foreach (App\Domains\AcademicProgram\Course\Models\Course::getVersions() as $key => $value) + @foreach ($curriculumList as $key => $value) @endforeach @@ -56,9 +57,10 @@
- +
- @foreach ($semestersList as $semesterId => $semesterTitle) @@ -111,7 +113,7 @@
- +
@error('credits') {{ $message }} diff --git a/resources/views/livewire/backend/edit-courses.blade.php b/resources/views/livewire/backend/edit-courses.blade.php index 44c2db67..ddf47589 100644 --- a/resources/views/livewire/backend/edit-courses.blade.php +++ b/resources/views/livewire/backend/edit-courses.blade.php @@ -29,7 +29,8 @@ Academic Program
- @foreach ($academicProgramsList as $academicProgramId => $academicProgramTitle)
- +
- - @foreach (App\Domains\AcademicProgram\Course\Models\Course::getVersions() as $key => $value) + @foreach ($curriculumList as $key => $value) @endforeach @@ -56,9 +58,10 @@
- +
- @foreach ($semestersList as $semesterId => $semesterTitle) @@ -112,7 +115,7 @@
- +
@error('credits') {{ $message }} From 14821f97d2f2f9870d74b789e1ec0fe29f6637fa Mon Sep 17 00:00:00 2001 From: NuwanJ Date: Fri, 18 Oct 2024 13:49:33 +0530 Subject: [PATCH 2/4] Factory update --- database/factories/CourseFactory.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/database/factories/CourseFactory.php b/database/factories/CourseFactory.php index 1d223f87..9ad21512 100644 --- a/database/factories/CourseFactory.php +++ b/database/factories/CourseFactory.php @@ -25,11 +25,14 @@ class CourseFactory extends Factory */ public function definition() { + $academicProgram = $this->faker->randomElement(array_keys(Course::getAcademicPrograms())); return [ 'code' => $this->faker->unique()->regexify('[A-Z]{4}[0-9]{4}'), 'semester_id' => $this->faker->numberBetween(1, 8), - 'academic_program' => $this->faker->randomElement(array_keys(Course::getAcademicPrograms())), - 'version' => $this->faker->randomElement([1, 2]), + 'academic_program' => $academicProgram, + 'version' => $this->faker->randomElement( + array_keys(Course::getVersions($academicProgram)) + ), 'name' => $this->faker->sentence(3), 'credits' => $this->faker->numberBetween(1, 6), 'type' => $this->faker->randomElement(array_keys(Course::getTypes())), From 872663149f99b45c4270814c16967571508f7b8e Mon Sep 17 00:00:00 2001 From: NuwanJ Date: Fri, 18 Oct 2024 14:05:59 +0530 Subject: [PATCH 3/4] On going works related to courses --- app/Domains/AcademicProgram/Course/Models/Course.php | 11 +++++++++-- tests/Feature/Backend/Courses/CourseTest.php | 5 +++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/Domains/AcademicProgram/Course/Models/Course.php b/app/Domains/AcademicProgram/Course/Models/Course.php index 1ec81d71..c65b5546 100644 --- a/app/Domains/AcademicProgram/Course/Models/Course.php +++ b/app/Domains/AcademicProgram/Course/Models/Course.php @@ -36,6 +36,8 @@ class Course extends AcademicProgram 'name', 'credits', 'type', + 'teaching_methods', + 'faq_page', 'content', 'objectives', 'time_allocation', @@ -122,7 +124,12 @@ public function semester() public function version() { - return $this->getVersions()[$this->version]; + $versions = $this->getVersions(); + if ($this->version != null && array_key_exists($this->version, $versions)) { + return $versions[$this->version]; + } else { + return "Unknown"; + } } public function modules() @@ -150,4 +157,4 @@ protected static function newFactory() { return CourseFactory::new(); } -} \ No newline at end of file +} diff --git a/tests/Feature/Backend/Courses/CourseTest.php b/tests/Feature/Backend/Courses/CourseTest.php index e5d1c53f..414c019d 100644 --- a/tests/Feature/Backend/Courses/CourseTest.php +++ b/tests/Feature/Backend/Courses/CourseTest.php @@ -65,7 +65,8 @@ public function a_course_can_be_updated_via_livewire() $this->loginAsCourseManager(); $course = Course::factory()->create(); - Livewire::test(\App\Http\Livewire\Backend\CreateCourses::class) + Livewire::test(\App\Http\Livewire\Backend\EditCourses::class) + ->set('course', $course) ->set('academicProgram', $course->academic_program) ->set('semester', (string) $course->semester_id) ->set('version', (string) $course->version) @@ -146,4 +147,4 @@ public function update_course_requires_valid_data() ->call('submit') ->assertHasErrors(['academicProgram', 'semester', 'version', 'type', 'code', 'name', 'credits']); } -} \ No newline at end of file +} From a53c9b0a6786e819ffb9d3f2f9d499549489fa41 Mon Sep 17 00:00:00 2001 From: kusaljayawardhana Date: Mon, 21 Oct 2024 17:33:39 +0530 Subject: [PATCH 4/4] Update for Course tests --- tests/Feature/Backend/Courses/CourseTest.php | 110 ++++++++++++++----- 1 file changed, 82 insertions(+), 28 deletions(-) diff --git a/tests/Feature/Backend/Courses/CourseTest.php b/tests/Feature/Backend/Courses/CourseTest.php index 414c019d..bef773e3 100644 --- a/tests/Feature/Backend/Courses/CourseTest.php +++ b/tests/Feature/Backend/Courses/CourseTest.php @@ -32,60 +32,114 @@ public function a_course_manager_can_access_the_create_course_page() /** @test */ public function a_course_can_be_created_via_livewire() { - $this->loginAsCourseManager(); - - $semester = Semester::factory()->create(); - - Livewire::test(\App\Http\Livewire\Backend\CreateCourses::class) - ->set('academicProgram', 'undergraduate') - ->set('semester', (string) $semester->id) - ->set('version', '1') - ->set('type', 'Core') - ->set('code', 'CS101') - ->set('name', 'Introduction to Computer Science') - ->set('credits', 3) - ->set('content', 'Basic concepts of computer science.') - ->set('objectives', 'Learn the basics of computer science') - ->set('time_allocation', ['lecture' => 3, 'tutorial' => 1, 'practical' => 1]) - ->set('marks_allocation', ['practicals' => 20, 'mid_exam' => 30, 'end_exam' => 50]) - ->set('ilos', ['knowledge' => ['Understand basic algorithms'], 'skills' => ['Implement basic programs']]) - ->set('references', ['Introduction to Algorithms']) - ->call('submit') - ->assertHasNoErrors(); + $this->loginAsCourseManager(); + + $semester = Semester::factory()->create([ + 'academic_program' => 'undergraduate', + 'version' => '1', + ]); + + Livewire::test(\App\Http\Livewire\Backend\CreateCourses::class) + + ->set('academicProgram', 'undergraduate') + ->set('version', '1') + ->set('semester', (string) $semester->id) + ->set('type', 'Core') + ->set('code', 'CL101') + ->set('name', 'Introduction to Computer Science') + ->set('credits', 3) + ->set('content', 'Basic concepts of computer science.') + ->set('teaching_methods', 'Lecture and practical') + ->set('time_allocation', ['lecture' => 3, 'tutorial' => 1, 'practical' => 1]) + ->set('marks_allocation', ['practicals' => 20, 'mid_exam' => 30, 'end_exam' => 50]) + ->call('next') + ->assertHasNoErrors() + + ->set('objectives', 'Learn the basics of computer science') + ->set('ilos', [ + 'knowledge' => ['Understand basic algorithms'], + 'skills' => ['Implement basic programs'] + ]) + ->call('next') + ->assertHasNoErrors() + + ->set('references', ['Introduction to Algorithms']) + ->set('modules', [ + [ + 'name' => 'Module 1', + 'description' => 'Introduction to programming', + 'time_allocation' => ['lectures' => 2, 'tutorials' => 1, 'practicals' => 1] + ] + ]) + ->call('submit') + ->assertHasNoErrors(); $this->assertDatabaseHas('courses', [ - 'code' => 'CS101', + 'code' => 'CL101', 'name' => 'Introduction to Computer Science', + 'credits' => 3, + 'type' => 'Core', ]); } + /** @test */ public function a_course_can_be_updated_via_livewire() { $this->loginAsCourseManager(); - $course = Course::factory()->create(); - Livewire::test(\App\Http\Livewire\Backend\EditCourses::class) - ->set('course', $course) + $course = Course::factory()->create([ + 'academic_program' => 'undergraduate', + 'version' => '1', + 'type' => 'Core', + ]); + + $semester = Semester::factory()->create([ + 'academic_program' => 'undergraduate', + 'version' => '1', + ]); + + Livewire::test(\App\Http\Livewire\Backend\EditCourses::class, ['course' => $course]) ->set('academicProgram', $course->academic_program) - ->set('semester', (string) $course->semester_id) ->set('version', (string) $course->version) + ->set('semester', (string) $semester->id) ->set('type', $course->type) ->set('code', 'CS102') ->set('name', 'Advanced Computer Science') ->set('credits', 3) ->set('content', 'Advanced topics in computer science.') - ->set('objectives', 'Learn advanced topics') + ->set('teaching_methods', 'Lecture and practical') ->set('time_allocation', ['lecture' => 3, 'tutorial' => 1, 'practical' => 2]) ->set('marks_allocation', ['practicals' => 30, 'mid_exam' => 20, 'end_exam' => 50]) - ->set('ilos', ['knowledge' => ['Understand advanced algorithms']]) + ->call('next') + ->assertHasNoErrors() + + ->set('objectives', 'Learn advanced topics') + ->set('ilos', [ + 'knowledge' => ['Understand advanced algorithms'], + 'skills' => ['Implement advanced programs'] + ]) + ->call('next') + ->assertHasNoErrors() + ->set('references', ['Advanced Algorithms']) - ->call('submit') + ->set('modules', [ + [ + 'name' => 'Module 1', + 'description' => 'Advanced programming concepts', + 'time_allocation' => ['lectures' => 2, 'tutorials' => 1, 'practicals' => 2] + ] + ]) + ->call('update') ->assertHasNoErrors(); $this->assertDatabaseHas('courses', [ + 'id' => $course->id, 'code' => 'CS102', 'name' => 'Advanced Computer Science', + 'credits' => 3, + 'type' => 'Core', + 'content' => 'Advanced topics in computer science.', ]); }