diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e703683d..99a6fd1d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,10 +10,10 @@ jobs: steps: - name: "Checkout the repository" - uses: "actions/checkout@v1" + uses: "actions/checkout@v4" - name: "Setup Python" - uses: "actions/setup-python@v1" + uses: "actions/setup-python@v3" with: python-version: '3.10' @@ -23,7 +23,7 @@ jobs: python -m pip install poetry - name: "Restore any cached Poetry dependencies" - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.cache/pypoetry/virtualenvs key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }} @@ -55,10 +55,10 @@ jobs: steps: - name: "Checkout the repository" - uses: "actions/checkout@v1" + uses: "actions/checkout@v4" - name: "Setup Python" - uses: "actions/setup-python@v1" + uses: "actions/setup-python@v3" with: python-version: '3.10' @@ -68,7 +68,7 @@ jobs: python -m pip install poetry - name: "Restore any cached Poetry dependencies" - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.cache/pypoetry/virtualenvs key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }} diff --git a/website/projects/admin.py b/website/projects/admin.py index 1181da95..a9e77330 100644 --- a/website/projects/admin.py +++ b/website/projects/admin.py @@ -165,6 +165,7 @@ def synchronise_to_GitHub(self, request, queryset): synchronise_to_GitHub.short_description = "Synchronise selected projects to GitHub" def export_project_members(self, request, queryset): + """Export project members to a CSV file.""" content = StringIO() writer = csv.writer(content, delimiter=",", quotechar='"', quoting=csv.QUOTE_ALL) writer.writerow( diff --git a/website/projects/tests/test_admin.py b/website/projects/tests/test_admin.py index 8dcaf403..e7312f0b 100644 --- a/website/projects/tests/test_admin.py +++ b/website/projects/tests/test_admin.py @@ -37,7 +37,13 @@ def setUpTestData(cls): name="test-archived", slug="test-archived", semester=cls.semester ) - cls.manager = User.objects.create(github_id=1, github_username="manager") + cls.manager = User.objects.create( + github_id=1, + github_username="manager", + first_name="John", + last_name="Doe", + student_number="s1234567", + ) reg = Registration.objects.create( user=cls.manager, semester=cls.semester, @@ -46,6 +52,7 @@ def setUpTestData(cls): dev_experience=Registration.EXPERIENCE_ADVANCED, ) reg.project = cls.project + reg.projects.add(cls.project) cls.repo1 = Repository.objects.create(name="testrepo1", project=cls.project) cls.repo2 = Repository.objects.create(name="testrepo2", project=cls.project) @@ -291,3 +298,16 @@ def test_archived_filter__all(self): self.assertEqual(result.count(), 2) self.assertIn(self.project, result) self.assertIn(self.project_archived, result) + + def test_export_project_members(self): + response = self.client.post( + reverse("admin:projects_project_changelist"), + {ACTION_CHECKBOX_NAME: [self.project.pk], "action": "export_project_members", "index": 0}, + ) + self.assertEqual(response.status_code, 200) + self.assertContains(response, '"Project","First name","Last name","Student number","GitHub username","Role"') + self.assertContains( + response, + f'"{self.project.name}","{self.manager.first_name}","{self.manager.last_name}",' + f'"{self.manager.student_number}","{self.manager.github_username}"', + ) diff --git a/website/questionnaires/admin.py b/website/questionnaires/admin.py index 0556aa70..3cc2cba3 100644 --- a/website/questionnaires/admin.py +++ b/website/questionnaires/admin.py @@ -340,7 +340,7 @@ def export_answers(self, request, queryset): answer.submission.late, answer.question.question, answer.peer, - answer.answer.comments if answer.question.is_closed else answer.answer.value, + answer.answer.get_value_display() if answer.question.is_closed else answer.answer.value, answer.answer.value if answer.question.is_closed else "", ] ) diff --git a/website/registrations/admin.py b/website/registrations/admin.py index 3572c711..0232ca73 100644 --- a/website/registrations/admin.py +++ b/website/registrations/admin.py @@ -162,6 +162,13 @@ def export_registrations(self, request, queryset): "Available during scheduled timeslot 1", "Available during scheduled timeslot 2", "Available during scheduled timeslot 3", + "Available during scheduled timeslot 4", + "Available during scheduled timeslot 5", + "Available during scheduled timeslot 6", + "Available during scheduled timeslot 7", + "Available during scheduled timeslot 8", + "Available during scheduled timeslot 9", + "Available during scheduled timeslot 10", "Has problems with signing an NDA", "Registration Comments", ] @@ -189,6 +196,13 @@ def export_registrations(self, request, queryset): registration.available_during_scheduled_timeslot_1, registration.available_during_scheduled_timeslot_2, registration.available_during_scheduled_timeslot_3, + registration.available_during_scheduled_timeslot_4, + registration.available_during_scheduled_timeslot_5, + registration.available_during_scheduled_timeslot_6, + registration.available_during_scheduled_timeslot_7, + registration.available_during_scheduled_timeslot_8, + registration.available_during_scheduled_timeslot_9, + registration.available_during_scheduled_timeslot_10, registration.has_problems_with_signing_an_nda, registration.comments, ] diff --git a/website/registrations/forms.py b/website/registrations/forms.py index 76b2d7b9..6ab18780 100644 --- a/website/registrations/forms.py +++ b/website/registrations/forms.py @@ -135,21 +135,70 @@ def __init__(self, *args, **kwargs): label="I am available during scheduled timeslot 1 for the course", required=False, initial=True, - help_text="Timeslot 1: Thursday 15:30 - 17:15", + help_text="Timeslot 1: Monday 8:30 - 12:30", ) available_during_scheduled_timeslot_2 = forms.BooleanField( label="I am available during scheduled timeslot 2 for the course", required=False, initial=True, - help_text="Timeslot 2: Friday 13:30 - 15:15", + help_text="Timeslot 2: Monday 13:30 - 17:30", ) available_during_scheduled_timeslot_3 = forms.BooleanField( label="I am available during scheduled timeslot 3 for the course", required=False, initial=True, - help_text="Timeslot 3: Friday 15:30 - 17:15", + help_text="Timeslot 3: Tuesday 8:30 - 12:30", + ) + + available_during_scheduled_timeslot_4 = forms.BooleanField( + label="I am available during scheduled timeslot 4 for the course", + required=False, + initial=True, + help_text="Timeslot 4: Tuesday 13:30 - 17:30", + ) + + available_during_scheduled_timeslot_5 = forms.BooleanField( + label="I am available during scheduled timeslot 5 for the course", + required=False, + initial=True, + help_text="Timeslot 5: Wednesday 8:30 - 12:30", + ) + + available_during_scheduled_timeslot_6 = forms.BooleanField( + label="I am available during scheduled timeslot 6 for the course", + required=False, + initial=True, + help_text="Timeslot 6: Wednesday 13:30 - 17:30", + ) + + available_during_scheduled_timeslot_7 = forms.BooleanField( + label="I am available during scheduled timeslot 7 for the course", + required=False, + initial=True, + help_text="Timeslot 7: Thursday 8:30 - 12:30", + ) + + available_during_scheduled_timeslot_8 = forms.BooleanField( + label="I am available during scheduled timeslot 8 for the course", + required=False, + initial=True, + help_text="Timeslot 8: Thursday 13:30 - 17:30", + ) + + available_during_scheduled_timeslot_9 = forms.BooleanField( + label="I am available during scheduled timeslot 9 for the course", + required=False, + initial=True, + help_text="Timeslot 9: Friday 8:30 - 12:30", + ) + + available_during_scheduled_timeslot_10 = forms.BooleanField( + label="I am available during scheduled timeslot 10 for the course", + required=False, + initial=True, + help_text="Timeslot 10: Friday 13:30 - 17:30", ) has_problems_with_signing_an_nda = forms.BooleanField( diff --git a/website/registrations/migrations/0014_registration_available_during_scheduled_timeslot_10_and_more.py b/website/registrations/migrations/0014_registration_available_during_scheduled_timeslot_10_and_more.py new file mode 100644 index 00000000..e9f7aba6 --- /dev/null +++ b/website/registrations/migrations/0014_registration_available_during_scheduled_timeslot_10_and_more.py @@ -0,0 +1,48 @@ +# Generated by Django 4.2.17 on 2026-01-19 13:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("registrations", "0013_alter_registration_projects"), + ] + + operations = [ + migrations.AddField( + model_name="registration", + name="available_during_scheduled_timeslot_10", + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name="registration", + name="available_during_scheduled_timeslot_4", + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name="registration", + name="available_during_scheduled_timeslot_5", + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name="registration", + name="available_during_scheduled_timeslot_6", + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name="registration", + name="available_during_scheduled_timeslot_7", + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name="registration", + name="available_during_scheduled_timeslot_8", + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name="registration", + name="available_during_scheduled_timeslot_9", + field=models.BooleanField(default=True), + ), + ] diff --git a/website/registrations/models/registration.py b/website/registrations/models/registration.py index 2029bea4..2ea00300 100644 --- a/website/registrations/models/registration.py +++ b/website/registrations/models/registration.py @@ -56,6 +56,13 @@ class Meta: available_during_scheduled_timeslot_1 = models.BooleanField(default=True) available_during_scheduled_timeslot_2 = models.BooleanField(default=True) available_during_scheduled_timeslot_3 = models.BooleanField(default=True) + available_during_scheduled_timeslot_4 = models.BooleanField(default=True) + available_during_scheduled_timeslot_5 = models.BooleanField(default=True) + available_during_scheduled_timeslot_6 = models.BooleanField(default=True) + available_during_scheduled_timeslot_7 = models.BooleanField(default=True) + available_during_scheduled_timeslot_8 = models.BooleanField(default=True) + available_during_scheduled_timeslot_9 = models.BooleanField(default=True) + available_during_scheduled_timeslot_10 = models.BooleanField(default=True) has_problems_with_signing_an_nda = models.BooleanField(default=False) comments = models.TextField(null=True, blank=True) diff --git a/website/registrations/tests/test_admin.py b/website/registrations/tests/test_admin.py index a5211d03..61987dd7 100644 --- a/website/registrations/tests/test_admin.py +++ b/website/registrations/tests/test_admin.py @@ -163,6 +163,10 @@ def test_registration_csv_export(self): '"Dev Experience","Git Experience","Scrum Experience","Management Interest",' '"Non-dutch","Available during scheduled timeslot 1",' '"Available during scheduled timeslot 2","Available during scheduled timeslot 3",' + '"Available during scheduled timeslot 4","Available during scheduled timeslot 5",' + '"Available during scheduled timeslot 6","Available during scheduled timeslot 7",' + '"Available during scheduled timeslot 8","Available during scheduled timeslot 9",' + '"Available during scheduled timeslot 10",' '"Has problems with signing an NDA","Registration Comments"' ), ) @@ -188,6 +192,13 @@ def test_registration_csv_export(self): f'"{self.registration.available_during_scheduled_timeslot_1}",' f'"{self.registration.available_during_scheduled_timeslot_2}",' f'"{self.registration.available_during_scheduled_timeslot_3}",' + f'"{self.registration.available_during_scheduled_timeslot_4}",' + f'"{self.registration.available_during_scheduled_timeslot_5}",' + f'"{self.registration.available_during_scheduled_timeslot_6}",' + f'"{self.registration.available_during_scheduled_timeslot_7}",' + f'"{self.registration.available_during_scheduled_timeslot_8}",' + f'"{self.registration.available_during_scheduled_timeslot_9}",' + f'"{self.registration.available_during_scheduled_timeslot_10}",' f'"{self.registration.has_problems_with_signing_an_nda}",' f'"{self.registration.comments}"' ), diff --git a/website/registrations/views.py b/website/registrations/views.py index 109db001..360ee920 100644 --- a/website/registrations/views.py +++ b/website/registrations/views.py @@ -111,6 +111,13 @@ def form_valid(self, form): available_during_scheduled_timeslot_1=form.cleaned_data["available_during_scheduled_timeslot_1"], available_during_scheduled_timeslot_2=form.cleaned_data["available_during_scheduled_timeslot_2"], available_during_scheduled_timeslot_3=form.cleaned_data["available_during_scheduled_timeslot_3"], + available_during_scheduled_timeslot_4=form.cleaned_data["available_during_scheduled_timeslot_4"], + available_during_scheduled_timeslot_5=form.cleaned_data["available_during_scheduled_timeslot_5"], + available_during_scheduled_timeslot_6=form.cleaned_data["available_during_scheduled_timeslot_6"], + available_during_scheduled_timeslot_7=form.cleaned_data["available_during_scheduled_timeslot_7"], + available_during_scheduled_timeslot_8=form.cleaned_data["available_during_scheduled_timeslot_8"], + available_during_scheduled_timeslot_9=form.cleaned_data["available_during_scheduled_timeslot_9"], + available_during_scheduled_timeslot_10=form.cleaned_data["available_during_scheduled_timeslot_10"], has_problems_with_signing_an_nda=form.cleaned_data["has_problems_with_signing_an_nda"], )