diff --git a/backend/docs/CourseClass.md b/backend/docs/CourseClass.md index cebb08dc8975b23bfe27a425179e34a8037d7364..0e5d59c658db0dfd63c81cb2ea47609f3b4c74a6 100644 --- a/backend/docs/CourseClass.md +++ b/backend/docs/CourseClass.md @@ -139,7 +139,14 @@ "participantCount": 20, "semester": 2, "status": "OPEN", - "startYear": 2030 + "startYear": 2030, + "courseClassDefaultSchedules" : [ + { + "day": "MONDAY", + "start": "13:00:00", + "end": "15:00:00" + } + ] } ``` @@ -154,6 +161,17 @@ "participantCount": 20, "semester": "2", "status": "OPEN", + "courseClassDefaultSchedules": [ + { + "id": "6d5889e5-219b-4ab2-ad51-5a054b125280", + "day": "MONDAY", + "start": "13:00:00", + "end": "15:00:00", + "courseClassId": "a24a7b51-b705-49ea-85fe-e5f9df3f8e97", + "updatedAt": "2021-03-19T19:12:31.997Z", + "createdAt": "2021-03-19T19:12:31.997Z" + } + ], "updatedAt": "2021-03-02T07:12:41.065Z", "createdAt": "2021-03-02T07:12:41.065Z" } diff --git a/backend/src/controllers/courseclass.js b/backend/src/controllers/courseclass.js index 5fe68f8a856edc8b69d96f7e3f2b9937e60cd659..1f0156968d76432325c313f0cfde63e8ddb25f47 100644 --- a/backend/src/controllers/courseclass.js +++ b/backend/src/controllers/courseclass.js @@ -1,8 +1,8 @@ 'use strict'; const { handleRequestWithInvalidRequestBody } = require('../util/common'); -const { - getCourseClass, - createCourseClass +const { + getCourseClass, + createCourseClass } = require('../util/db/course-class'); exports.getCourseClassData = async(req, res) => { @@ -48,6 +48,7 @@ exports.createCourseClassData = async(req, res) => { participantCount, semester, status, + courseClassDefaultSchedules } = req.body; const newCourseClass = { @@ -57,7 +58,8 @@ exports.createCourseClassData = async(req, res) => { capacity, participantCount, semester, - status + status, + courseClassDefaultSchedules }; try { diff --git a/backend/src/hooks/course-class.js b/backend/src/hooks/course-class.js new file mode 100644 index 0000000000000000000000000000000000000000..632744ab82738b02e9297f487882b654f2e5c068 --- /dev/null +++ b/backend/src/hooks/course-class.js @@ -0,0 +1,18 @@ +const { + CourseClass, +} = require('../models/index'); + +const { + deleteCurrentMeetings +} = require('../util/hook'); + +const { generateCourseClassMeetings } = require('../util/common'); + +CourseClass.afterCreate(async courseClass => { + await generateCourseClassMeetings(courseClass); +}); + +CourseClass.afterUpdate(async courseClass => { + await deleteCurrentMeetings(courseClass); + await generateCourseClassMeetings(courseClass); +}); diff --git a/backend/src/hooks/study-plan.js b/backend/src/hooks/study-plan.js index 78b0f85869a01919d1f39742d9207ad5c6113d26..417ce3159dc9750fbcf5b7d3035794d2360b276b 100644 --- a/backend/src/hooks/study-plan.js +++ b/backend/src/hooks/study-plan.js @@ -1,7 +1,16 @@ const { StudyPlan, } = require('../models/index'); -const { calculateTotalCredits } = require('../util/hook'); + +const { + StudyPlanStatusEnum, +} = require('../enums/index'); + +const { + calculateTotalCredits, + deleteCurrentMeetingAttendances +} = require('../util/hook'); +const { generateCourseClassMeetingAttendances } = require('../util/common'); StudyPlan.beforeCreate(async studyPlan => { studyPlan.creditsTotal = await calculateTotalCredits(studyPlan.studyPlanCourses); @@ -9,4 +18,17 @@ StudyPlan.beforeCreate(async studyPlan => { StudyPlan.beforeUpdate(async studyPlan => { studyPlan.creditsTotal = await calculateTotalCredits(studyPlan.studyPlanCourses); -}); \ No newline at end of file +}); + +StudyPlan.afterCreate(async studyPlan => { + if (studyPlan.status === StudyPlanStatusEnum.FINAL){ + await generateCourseClassMeetingAttendances(studyPlan); + } +}); + +StudyPlan.afterUpdate(async studyPlan => { + if (studyPlan.status === StudyPlanStatusEnum.FINAL) { + await deleteCurrentMeetingAttendances(studyPlan); + await generateCourseClassMeetingAttendances(studyPlan); + } +}); diff --git a/backend/src/index.js b/backend/src/index.js index ab450826c6d84040cbe7929296c23f22658450a5..1a5ccbfea36a9ed2f31610e6a09a10e9c9d0500b 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -18,7 +18,7 @@ const courseRouter = require('./routes/course'); const studyPlanRouter = require('./routes/study-plan'); require('./hooks/study-plan'); - +require('./hooks/course-class'); app.use(cors()); app.use(express.json()); diff --git a/backend/src/test/courseclass.controller.test.js b/backend/src/test/courseclass.controller.test.js index 6b39abaa4c290e159098c552dc9ad39247399a72..b4e82b714e34b6fc3467123c23d6c5e33433fcbd 100644 --- a/backend/src/test/courseclass.controller.test.js +++ b/backend/src/test/courseclass.controller.test.js @@ -6,7 +6,10 @@ const { Lecturer } = require('../models/index'); -const { EndpointEnum } = require('../enums/index'); +const { + EndpointEnum, + DayEnum +} = require('../enums/index'); let chai = require('chai'); let chaiHttp = require('chai-http'); @@ -25,6 +28,8 @@ let COURSE_CODE = "IF2036"; let COURSE_NAME = "Rekayasa Perangkat Lunak"; let DUMMY_ID = '57e19842-d712-45fd-9068-04cde6bf41f3'; let INVALID_ID = '57e19842-d712-45fd-9068-04cde6bf41f'; +let START_TIME = '13:00:00'; +let END_TIME = '15:00:00'; const COURSE_CLASS_ENDPOINT = '/course-class'; @@ -185,7 +190,14 @@ describe('Course Class Test', () => { "participantCount": 20, "semester": "2", "status": STATUS, - "startYear": START_YEAR + "startYear": START_YEAR, + "courseClassDefaultSchedules" : [ + { + "day": DayEnum.MONDAY.name, + "start": START_TIME, + "end": END_TIME + } + ] }; chai.request(server) @@ -201,6 +213,7 @@ describe('Course Class Test', () => { res.body.should.have.property('semester').deep.equal(requestBody.semester); res.body.should.have.property('status').deep.equal(requestBody.status); res.body.should.have.property('startYear').deep.equal(requestBody.startYear); + res.body.should.have.property('courseClassDefaultSchedules').to.not.equal(null); res.body.should.have.property('updatedAt').to.not.equal(null); res.body.should.have.property('createdAt').to.not.equal(null); done(); diff --git a/backend/src/util/db/course-class.js b/backend/src/util/db/course-class.js index f43089553690d83d4098185b4252c04be8313d80..8d5e0021f4a3f262f9b6c9fb8333e666fd46400e 100644 --- a/backend/src/util/db/course-class.js +++ b/backend/src/util/db/course-class.js @@ -4,7 +4,8 @@ const { Course, Major, Faculty, - Lecturer + Lecturer, + CourseClassDefaultSchedule } = require('../../models/index'); const { @@ -56,7 +57,17 @@ const getCourseClass = async(req, getMany) =>{ const createCourseClass = async(data) => { try { - const courseClass = await CourseClass.create(data); + const courseClass = await CourseClass.create( + data, + { + include: [ + { + model: CourseClassDefaultSchedule, + as: 'courseClassDefaultSchedules', + } + ] + } + ); if (courseClass) return courseClass; else throw new NotExistError(); diff --git a/backend/src/util/hook.js b/backend/src/util/hook.js index 02545e0393a6961d472a1190f40b7c22af109049..c9cd479ef779ff352895d0420d88f45977a1fe4c 100644 --- a/backend/src/util/hook.js +++ b/backend/src/util/hook.js @@ -1,7 +1,11 @@ +const { Op } = require("sequelize"); 'use strict'; const { Course, - CourseClass + CourseClass, + CourseClassMeeting, + StudyPlanCourse, + CourseClassMeetingAttendance, } = require('../models/index'); const calculateTotalCredits = async (studyPlanCourses) => { @@ -20,6 +24,43 @@ const calculateTotalCredits = async (studyPlanCourses) => { return totalCredits; }; +const deleteCurrentMeetings = async (courseClass) => { + await CourseClassMeeting.destroy({ + where: { + courseClassId: courseClass.id + } + }); +}; + +const deleteCurrentMeetingAttendances = async (studyPlan) => { + const studyPlanCourses = await StudyPlanCourse.findAll({ + where: { + studyPlanId: studyPlan.id + } + }); + + for (let i = 0; i < studyPlanCourses.length; i++) { + const meetings = await CourseClassMeeting.findAll({ + where: { + courseClassId: studyPlanCourses[i].courseClassId + } + }); + + const meetingIds = meetings.map(meet => meet.id); + + await CourseClassMeetingAttendance.destroy({ + where : { + courseClassMeetingId: { + [Op.or]: meetingIds + }, + studentId: studyPlan.studentId, + } + }); + } +}; + module.exports = { - calculateTotalCredits + calculateTotalCredits, + deleteCurrentMeetings, + deleteCurrentMeetingAttendances };