Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add section to RecruitmentPosition model #1410

Merged
merged 2 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 5.1.1 on 2024-09-29 16:52

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('samfundet', '0005_role_content_type_role_created_at_role_created_by_and_more'),
]

operations = [
migrations.AddField(
model_name='recruitmentposition',
name='section',
field=models.ForeignKey(blank=True, help_text='The section that is recruiting', null=True, on_delete=django.db.models.deletion.CASCADE, to='samfundet.gangsection'),
),
migrations.AlterField(
model_name='recruitmentposition',
name='gang',
field=models.ForeignKey(blank=True, help_text='The gang that is recruiting', null=True, on_delete=django.db.models.deletion.CASCADE, to='samfundet.gang'),
),
]
18 changes: 16 additions & 2 deletions backend/samfundet/models/recruitment.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from root.utils.mixins import CustomBaseModel, FullCleanSaveMixin

from .general import Gang, User, Campus, Organization
from .general import Gang, User, Campus, GangSection, Organization
from .model_choices import RecruitmentStatusChoices, RecruitmentApplicantStates, RecruitmentPriorityChoices


Expand Down Expand Up @@ -136,7 +136,9 @@ class RecruitmentPosition(CustomBaseModel):

norwegian_applicants_only = models.BooleanField(help_text='Is this position only for Norwegian applicants?', default=False)

gang = models.ForeignKey(to=Gang, on_delete=models.CASCADE, help_text='The gang that is recruiting')
gang = models.ForeignKey(to=Gang, on_delete=models.CASCADE, help_text='The gang that is recruiting', null=True, blank=True)
section = models.ForeignKey(GangSection, on_delete=models.CASCADE, help_text='The section that is recruiting', null=True, blank=True)

recruitment = models.ForeignKey(
Recruitment,
on_delete=models.CASCADE,
Expand All @@ -161,6 +163,12 @@ class RecruitmentPosition(CustomBaseModel):
# TODO: Implement interviewer functionality
interviewers = models.ManyToManyField(to=User, help_text='Interviewers for the position', blank=True, related_name='interviewers')

def resolve_section(self, *, return_id: bool = False) -> GangSection | int:
if return_id:
# noinspection PyTypeChecker
return self.section_id
return self.section

def resolve_gang(self, *, return_id: bool = False) -> Gang | int:
if return_id:
# noinspection PyTypeChecker
Expand All @@ -173,6 +181,12 @@ def resolve_org(self, *, return_id: bool = False) -> Organization | int:
def __str__(self) -> str:
return f'Position: {self.name_en} in {self.recruitment}'

def clean(self) -> None:
super().clean()

if (self.gang and self.section) or not (self.gang or self.section):
raise ValidationError('Position must be owned by either gang or section, not both')

def save(self, *args: tuple, **kwargs: dict) -> None:
if self.norwegian_applicants_only:
self.name_en = 'Norwegian speaking applicants only'
Expand Down
21 changes: 20 additions & 1 deletion backend/samfundet/models/tests/test_recruitment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.utils import timezone
from django.core.exceptions import ValidationError

from samfundet.models.general import Gang, User, Campus
from samfundet.models.general import Gang, User, Campus, GangSection
from samfundet.models.recruitment import (
Interview,
Recruitment,
Expand Down Expand Up @@ -834,3 +834,22 @@ def test_recruitment_progress_applications_multiple_new_updates_progress(
new_application.recruiter_status = RecruitmentStatusChoices.CALLED_AND_ACCEPTED
new_application.save()
assert fixture_recruitment.recruitment_progress() == 1


def test_position_must_have_single_owner(fixture_recruitment_position: RecruitmentPosition, fixture_gang: Gang, fixture_gang_section: GangSection):
fixture_recruitment_position.gang = fixture_gang
fixture_recruitment_position.section = fixture_gang_section
with pytest.raises(ValidationError):
fixture_recruitment_position.save()

fixture_recruitment_position.gang = None
fixture_recruitment_position.section = None
with pytest.raises(ValidationError):
fixture_recruitment_position.save()

fixture_recruitment_position.gang = fixture_gang
fixture_recruitment_position.save()

fixture_recruitment_position.gang = None
fixture_recruitment_position.section = fixture_gang_section
fixture_recruitment_position.save()
Loading