diff --git a/advlabdb/adminModelViews.py b/advlabdb/adminModelViews.py index 4e80301..8d4c526 100644 --- a/advlabdb/adminModelViews.py +++ b/advlabdb/adminModelViews.py @@ -1071,6 +1071,8 @@ class AppointmentView(SecureAdminModelView): assistant=form.assistant.data, ) + return True + class ExperimentMarkView(SecureAdminModelView): class AssistantFilter(AssistantRowFilter): @@ -1167,22 +1169,16 @@ class ExperimentMarkView(SecureAdminModelView): def customCreateModel(self, form): return ExperimentMark(part_student=form.part_student.data, group_experiment=form.group_experiment.data) - def update_model(self, form, model): - if (form.oral_mark.data != model.oral_mark) or (form.protocol_mark.data != model.protocol_mark): + def customUpdateModel(self, form, model): + form_oral_mark = form.oral_mark.data + form_protocol_mark = form.protocol_mark.data + + if (form_oral_mark != model.oral_mark) or (form_protocol_mark != model.protocol_mark): + model.set_oral_protocol_mark(form_oral_mark, form_protocol_mark) model.admin = current_user.admin + return True - updateSuccessful = super().update_model(form, model) - - if updateSuccessful: - final_part_mark_changed = model.part_student.checkThenSetFinalPartMark() - - if final_part_mark_changed: - model.group_experiment.update_experiment_marks_missing() - - return updateSuccessful - - # Nothing changed - return True + return False class ProgramView(SecureAdminModelView): diff --git a/advlabdb/assistantModelViews.py b/advlabdb/assistantModelViews.py index 304df3a..c370365 100644 --- a/advlabdb/assistantModelViews.py +++ b/advlabdb/assistantModelViews.py @@ -129,7 +129,7 @@ class AssistantGroupExperimentView(SecureAssistantModelView): ] if form.validate_on_submit(): - any_final_part_mark_changed = False + any_final_experiment_mark_changed = False try: for ind, appointment in enumerate(appointments): appointment.date = appointment_fields[ind].data @@ -142,16 +142,17 @@ class AssistantGroupExperimentView(SecureAssistantModelView): form_oral_mark != experiment_mark.oral_mark or form_protocol_mark != experiment_mark.protocol_mark ): - experiment_mark.oral_mark = form_oral_mark - experiment_mark.protocol_mark = form_protocol_mark + final_experiment_mark_changed = experiment_mark.set_oral_protocol_mark( + form_oral_mark, + form_protocol_mark, + call_update_experiment_marks_missing=False, + ) + if final_experiment_mark_changed: + any_final_experiment_mark_changed = True experiment_mark.assistant = current_user.assistant - final_part_mark_changed = experiment_mark.part_student.checkThenSetFinalPartMark() - if final_part_mark_changed: - any_final_part_mark_changed = True - - if any_final_part_mark_changed: + if any_final_experiment_mark_changed: group_experiment.update_experiment_marks_missing() group_experiment.note = form.note.data diff --git a/advlabdb/models.py b/advlabdb/models.py index 80cc2a4..188ccfe 100644 --- a/advlabdb/models.py +++ b/advlabdb/models.py @@ -360,7 +360,7 @@ class SemesterExperiment(db.Model): def updateFinalExperimentAndPartMarks(self): for groupExperiment in self.group_experiments: for experimentMark in groupExperiment.experiment_marks: - experimentMark.updateFinalExperimentMark() + experimentMark.update_final_experiment_mark() for groupExperiment in self.group_experiments: for partStudent in groupExperiment.group.part_students: @@ -546,29 +546,6 @@ class Semester(db.Model): class ExperimentMark(db.Model): # A mark for a student after a specific experiment - def final_experiment_mark_update(context): - params = context.get_current_parameters() - - experimentMark = db.session.get(ExperimentMark, params["experiment_mark_id"]) - - oral_mark = params.get("oral_mark") - if oral_mark is None: - oral_mark = experimentMark.oral_mark - if oral_mark is None: - return - - protocol_mark = params.get("protocol_mark") - if protocol_mark is None: - protocol_mark = experimentMark.protocol_mark - if protocol_mark is None: - return - - semesterExperiment = experimentMark.group_experiment.semester_experiment - - return roundHalfUpToInt( - semesterExperiment.oral_weighting * oral_mark + semesterExperiment.protocol_weighting * protocol_mark - ) - id = db.Column(db.Integer, primary_key=True) oral_mark = db.Column( @@ -585,7 +562,6 @@ class ExperimentMark(db.Model): final_experiment_mark = db.Column( db.Integer, db.CheckConstraint(f"oral_mark BETWEEN {MIN_MARK} AND {MAX_MARK}"), - onupdate=final_experiment_mark_update, nullable=True, ) @@ -622,14 +598,40 @@ class ExperimentMark(db.Model): super().__init__(part_student=part_student, group_experiment=group_experiment) - def updateFinalExperimentMark(self): - if None not in (self.oral_mark, self.protocol_mark): + def update_final_experiment_mark(self): + """ + Return True if final_experiment_mark changed, False otherwise. + """ + old_final_experiment_mark = self.final_experiment_mark + oral_mark = self.oral_mark + protocol_mark = self.protocol_mark + + if None in (oral_mark, protocol_mark): + self.final_experiment_mark = None + else: semesterExperiment = self.group_experiment.semester_experiment self.final_experiment_mark = roundHalfUpToInt( - semesterExperiment.oral_weighting * self.oral_mark - + semesterExperiment.protocol_weighting * self.protocol_mark + semesterExperiment.oral_weighting * oral_mark + semesterExperiment.protocol_weighting * protocol_mark ) + final_experiment_mark_changed = self.final_experiment_mark != old_final_experiment_mark + return final_experiment_mark_changed + + def set_oral_protocol_mark(self, oral_mark: int, protocol_mark: int, call_update_experiment_marks_missing=True): + """ + Return True if final_experiment_mark changed, False otherwise. + """ + self.oral_mark = oral_mark + self.protocol_mark = protocol_mark + + final_experiment_mark_changed = self.update_final_experiment_mark() + if final_experiment_mark_changed: + self.part_student.checkThenSetFinalPartMark() + if call_update_experiment_marks_missing: + self.group_experiment.update_experiment_marks_missing() + + return final_experiment_mark_changed + class User(db.Model, FsUserMixin): first_name = db.Column(db.String(100), nullable=False)