diff --git a/DB.drawio b/DB.drawio index de9d55a..bef0b83 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/adminModelViews.py b/advlabdb/adminModelViews.py index 6c85abd..7a1a2ca 100644 --- a/advlabdb/adminModelViews.py +++ b/advlabdb/adminModelViews.py @@ -38,6 +38,10 @@ from advlabdb.utils import ( ) +def semesterExperimentQueryFactory(): + return SemesterExperiment.query.filter(SemesterExperiment.semester == userActiveSemester()) + + class UserView(SecureAdminModelView): class CreateForm(Form): def roleQueryFactory(): @@ -56,6 +60,22 @@ class UserView(SecureAdminModelView): validators=[DataRequired()], default=[Role.query.filter(Role.name == "assistant").first()], ) + + first_name = TextField("First Name", validators=[DataRequired()]) + last_name = TextField("Last Name", validators=[DataRequired()]) + phone_number = TextField("Phone Number") + mobile_phone_number = TextField("Mobile Phone Number") + room = TextField("Room") + building = TextField("Building") + + semester_experiments = QuerySelectMultipleField( + "Semester Experiments", + query_factory=semesterExperimentQueryFactory, + allow_blank=True, + blank_text="-", + description="Only needed if the user has the assistant role", + ) + active = BooleanField("Active", default=True) active_semester = QuerySelectField( "Active Semester", @@ -66,15 +86,25 @@ class UserView(SecureAdminModelView): ) class EditForm(CreateForm): + semester_experiments = None + generate_new_password = BooleanField("Generate new random password", default=False) form = EditForm can_view_details = True - column_list = ["email", "active", "roles", "assistant", "active_semester"] - column_searchable_list = ["email"] - column_filters = ["active", "active_semester", "assistant"] + column_list = ["first_name", "last_name", "email", "active", "roles", "assistant", "active_semester"] + column_details_list = column_list + [ + "phone_number", + "mobile_phone_number", + "room", + "building", + "create_datetime", + "update_datetime", + ] + column_searchable_list = ["first_name", "last_name", "email"] + column_filters = ["active", "active_semester"] column_editable_list = ["active"] def create_form(self, obj=None): @@ -94,9 +124,23 @@ class UserView(SecureAdminModelView): roles = [role.name for role in form.roles.data] model = user_datastore.create_user( - email=email, password=hashedPassword, roles=roles, active_semester=form.active_semester.data + email=email, + password=hashedPassword, + roles=roles, + first_name=form.first_name.data, + last_name=form.last_name.data, + phone_number=form.phone_number.data, + mobile_phone_number=form.mobile_phone_number.data, + room=form.room.data, + building=form.building.data, + active=form.active.data, + active_semester=form.active_semester.data, ) + if "assistant" in roles: + assistant = Assistant(user=model, semester_experiments=form.semester_experiments.data) + self.session.add(assistant) + self.on_model_change(form, model, True) self.session.commit() except Exception as ex: @@ -439,18 +483,18 @@ class AssistantView(SecureAdminModelView): can_view_details = True - column_list = ["first_name", "last_name", "user", "semester_experiments"] + column_list = ["user.first_name", "user.last_name", "user", "semester_experiments"] column_details_list = column_list + [ - "phone_number", - "mobile_phone_number", - "room", - "building", + "user.phone_number", + "user.mobile_phone_number", + "user.room", + "user.building", "appointments", "experiment_marks", ] - column_searchable_list = ["first_name", "last_name", "user.email"] + column_searchable_list = ["user.first_name", "user.last_name", "user.email"] column_filters = ["user.active"] - form_excluded_columns = ["experiment_marks", "appointments", "semester_experiments", "user"] + form_excluded_columns = ["experiment_marks", "appointments"] form_extra_fields = { "user": QuerySelectField( @@ -459,7 +503,13 @@ class AssistantView(SecureAdminModelView): validators=[DataRequired()], allow_blank=True, blank_text="-", - ) + ), + "semester_experiments": QuerySelectMultipleField( + "Semester Experiments", + query_factory=semesterExperimentQueryFactory, + allow_blank=True, + blank_text="-", + ), } @@ -468,9 +518,6 @@ assistantBlankText = "Auto assign if experiment has only one assistant" class GroupExperimentView(SecureAdminModelView): class CreateForm(Form): - def semesterExperimentQueryFactory(): - return SemesterExperiment.query.filter(SemesterExperiment.semester == userActiveSemester()) - group = QuerySelectField( "Group", query_factory=groupQueryFactory, @@ -566,7 +613,7 @@ class AppointmentView(SecureAdminModelView): "special", "group_experiment.group", "group_experiment.semester_experiment.experiment", - "assistant", + "assistant.user", ] column_editable_list = ["date", "special"] @@ -648,8 +695,8 @@ class ExperimentMarkView(SecureAdminModelView): "group_experiment.group", "group_experiment.semester_experiment.semester", "group_experiment.semester_experiment.experiment", - "assistant", "edited_by_admin", + "assistant.user", ] column_default_sort = [("oral_mark", False), ("protocol_mark", False)] @@ -708,11 +755,11 @@ adminSpace.add_view(AppointmentView(Appointment, db.session)) adminSpace.add_view(ExperimentMarkView(ExperimentMark, db.session)) adminSpace.add_view(ExperimentView(Experiment, db.session)) adminSpace.add_view(SemesterExperimentView(SemesterExperiment, db.session)) -adminSpace.add_view(AssistantView(Assistant, db.session)) -adminSpace.add_view(ProgramView(Program, db.session)) -adminSpace.add_view(PartView(Part, db.session)) adminSpace.add_view(SemesterView(Semester, db.session)) +adminSpace.add_view(PartView(Part, db.session)) +adminSpace.add_view(AssistantView(Assistant, db.session)) adminSpace.add_view(UserView(User, db.session)) adminSpace.add_view(RoleView(Role, db.session)) +adminSpace.add_view(ProgramView(Program, db.session)) initActiveSemesterMenuLinks(adminSpace) diff --git a/advlabdb/models.py b/advlabdb/models.py index 125b8eb..3c9086b 100644 --- a/advlabdb/models.py +++ b/advlabdb/models.py @@ -248,12 +248,6 @@ class SemesterExperiment(db.Model): class Assistant(db.Model): id = db.Column(db.Integer, primary_key=True) - first_name = db.Column(db.String(100), nullable=False) - last_name = db.Column(db.String(100), nullable=False) - phone_number = db.Column(db.String(50), nullable=True) - mobile_phone_number = db.Column(db.String(50), nullable=True) - room = db.Column(db.String(100), nullable=True) - building = db.Column(db.String(100), nullable=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False, unique=True) @@ -261,7 +255,7 @@ class Assistant(db.Model): experiment_marks = db.relationship("ExperimentMark", backref="assistant", lazy=True) def repr(self): - return f"{self.first_name} {self.last_name}" + return f"{self.user.first_name} {self.user.last_name}" def __repr__(self): return f"" @@ -411,12 +405,19 @@ class ExperimentMark(db.Model): class User(db.Model, FsUserMixin): + first_name = db.Column(db.String(100), nullable=False) + last_name = db.Column(db.String(100), nullable=False) + phone_number = db.Column(db.String(50), nullable=True) + mobile_phone_number = db.Column(db.String(50), nullable=True) + room = db.Column(db.String(100), nullable=True) + building = db.Column(db.String(100), nullable=True) + active_semester_id = db.Column(db.Integer, db.ForeignKey("semester.id"), nullable=True) assistant = db.relationship("Assistant", backref="user", lazy=True, uselist=False) def repr(self): - return f"{self.email}" + return f"{self.first_name} {self.last_name}" def __repr__(self): return f"" diff --git a/poetry.lock b/poetry.lock index 93137e8..95254ea 100644 --- a/poetry.lock +++ b/poetry.lock @@ -538,12 +538,22 @@ jinja2 = [ {file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"}, ] markupsafe = [ + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -552,14 +562,21 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -569,6 +586,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, diff --git a/testDB.py b/testDB.py index 7b083b2..1b97cb0 100644 --- a/testDB.py +++ b/testDB.py @@ -104,19 +104,35 @@ with app.app_context(): user_datastore.create_role(name="admin") user_datastore.create_role(name="assistant") - user_datastore.create_user(email="admin@protonmail.com", password=hash_password("admin"), roles=["admin"]) + user_datastore.create_user( + email="admin@protonmail.com", + password=hash_password("admin"), + roles=["admin"], + first_name="Peter", + last_name="Blümler", + ) - us1 = user_datastore.create_user(email="test@protonmail.com", password=hash_password("h1"), roles=["assistant"]) - us2 = user_datastore.create_user(email="test2@protonmail.com", password=hash_password("h2"), roles=["assistant"]) - - as1 = Assistant( + us1 = user_datastore.create_user( + email="test@protonmail.com", + password=hash_password("h1"), + roles=["assistant"], first_name="As1", last_name="l", phone_number="012333212", mobile_phone_number="012334123", + ) + us2 = user_datastore.create_user( + email="test2@protonmail.com", + password=hash_password("h2"), + roles=["assistant"], + first_name="As2", + last_name="l", + ) + + as1 = Assistant( user=us1, ) - as2 = Assistant(first_name="As2", last_name="l", user=us2) + as2 = Assistant(user=us2) as1.semester_experiments.append(sx1) as2.semester_experiments.append(sx2)