diff --git a/DB.drawio b/DB.drawio index 4cfcca3..98b81e9 100644 --- a/DB.drawio +++ b/DB.drawio @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/advlabdb/modelViews.py b/advlabdb/modelViews.py index d4b6a16..744fb46 100644 --- a/advlabdb/modelViews.py +++ b/advlabdb/modelViews.py @@ -534,14 +534,76 @@ class ExperimentMarkView(SecureModelView): else: return False + class CreateForm(Form): + part_student = QuerySelectField( + "Part Student", + query_factory=partStudentsQueryFactory, + validators=[DataRequired()], + allow_blank=True, + blank_text="-", + ) + group_experiment = QuerySelectField( + "Group Experiment", + query_factory=groupExperimentQueryFactory, + validators=[DataRequired()], + allow_blank=True, + blank_text="-", + ) + + oral_mark = SelectField("Oral Mark", choices=markChoices, coerce=int) + protocol_mark = SelectField("Protocol Mark", choices=markChoices, coerce=int) + + form = CreateForm + column_filters = [ StudentIdFilter(PartStudent.id, "Student / ID"), "part_student.student", "group_experiment.semester_experiment.semester", "group_experiment.semester_experiment.experiment", "assistant", + "edited_by_admin", ] + def queryFilter(self=None): + return GroupExperiment.semester_experiment_id.in_( + [ + semesterExperiment.id + for semesterExperiment in SemesterExperiment.query.filter( + SemesterExperiment.semester == userActiveSemester() + ) + ] + ) + + def checkForm(form): + if form.oral_mark.data == -1: + form.oral_mark.data = None + + if form.protocol_mark.data == -1: + form.protocol_mark.data = None + + return form + + def create_model(self, form): + form = ExperimentMarkView.checkForm(form) + + return super().create_model(form) + + def update_model(self, form, model): + form = ExperimentMarkView.checkForm(form) + + return super().update_model(form, model) + + def after_model_change(self, form, model, is_created): + if model.oral_mark or model.protocol_mark: + try: + model.edited_by_admin = True + + self.session.commit() + except Exception as ex: + flash(str(ex), "error") + + self.session.rollback() + admin.add_view(StudentView(Student, db.session)) admin.add_view(PartStudentView(PartStudent, db.session)) diff --git a/advlabdb/models.py b/advlabdb/models.py index 3d8a537..7b44fc0 100644 --- a/advlabdb/models.py +++ b/advlabdb/models.py @@ -106,7 +106,12 @@ class GroupExperiment(db.Model): f"{student} has already done {semester_experiment.experiment} in {partStudent.part} and had {experimentMark}!" ) - return GroupExperiment(semester_experiment=semester_experiment, group=group) + groupExperiment = GroupExperiment(semester_experiment=semester_experiment, group=group) + + for partStudent in group.part_students: + db.session.add(ExperimentMark(part_student=partStudent, group_experiment=groupExperiment)) + + return groupExperiment def repr(self): return f"SemExp {self.semester_experiment.repr()}; Gr {self.group.repr()}" @@ -125,7 +130,7 @@ class Experiment(db.Model): building = db.Column(db.String(100), nullable=False) responsibility = db.Column(db.String(200), nullable=True) duration_in_days = db.Column(db.Integer, db.CheckConstraint("duration_in_days > -1"), nullable=False) - active = db.Column(db.Boolean, nullable=False, default=True) + active = db.Column(db.Boolean, default=True, nullable=False) oral_weighting = db.Column(db.Float, nullable=False) protocol_weighting = db.Column(db.Float, nullable=False) final_weighting = db.Column(db.Float, nullable=False) @@ -187,7 +192,7 @@ class Assistant(db.Model): class Appointment(db.Model): id = db.Column(db.Integer, primary_key=True) date = db.Column(db.Date, nullable=False) # To be specified with the python package "datetime" - special = db.Column(db.Boolean, nullable=False) # In the break or not + special = db.Column(db.Boolean, default=False, nullable=False) # In the break or not group_experiment_id = db.Column(db.Integer, db.ForeignKey("group_experiment.id"), nullable=False) assistant_id = db.Column(db.Integer, db.ForeignKey("assistant.id"), nullable=False) @@ -284,6 +289,7 @@ class ExperimentMark(db.Model): protocol_mark = db.Column( db.Integer, db.CheckConstraint("protocol_mark > -1"), db.CheckConstraint("protocol_mark < 16"), nullable=True ) + edited_by_admin = db.Column(db.Boolean, default=False, nullable=True) part_student_id = db.Column(db.Integer, db.ForeignKey("part_student.id"), nullable=False) group_experiment_id = db.Column(db.Integer, db.ForeignKey("group_experiment.id"), nullable=False) assistant_id = db.Column(