diff --git a/scipost_django/colleges/forms.py b/scipost_django/colleges/forms.py index 10b0dd99a07489c32013764ed60295e168705c7b..aefa515b3664beb36b87aac769ed0f49b3602420 100644 --- a/scipost_django/colleges/forms.py +++ b/scipost_django/colleges/forms.py @@ -552,6 +552,7 @@ class FellowshipNominationDecisionForm(forms.ModelForm): ] def __init__(self, *args, **kwargs): + voting_round = kwargs.pop("voting_round", None) super().__init__(*args, **kwargs) self.helper = FormHelper() self.helper.layout = Layout( @@ -568,6 +569,9 @@ class FellowshipNominationDecisionForm(forms.ModelForm): ), ) + if voting_round: + self.fields["outcome"].initial = voting_round.vote_outcome + class FellowshipInvitationResponseForm(forms.ModelForm): class Meta: diff --git a/scipost_django/colleges/models/nomination.py b/scipost_django/colleges/models/nomination.py index 6487d2a841550277eeda7752d74b85c4b2a48bf1..1db4b616d50745bfcf1dff720b2c1f5bfd72b0b8 100644 --- a/scipost_django/colleges/models/nomination.py +++ b/scipost_django/colleges/models/nomination.py @@ -218,6 +218,28 @@ class FellowshipNominationVotingRound(models.Model): def is_open(self): return self.voting_opens <= timezone.now() <= self.voting_deadline + @property + def vote_outcome(self): + """The outcome as determined by the votes.""" + if self.votes.veto(): + return FellowshipNominationDecision.OUTCOME_NOT_ELECTED + + nr_votes_agree = self.votes.agree().count() + nr_votes_disagree = self.votes.disagree().count() + nr_non_abstaining_votes = nr_votes_agree + nr_votes_disagree + + # Guard division by zero + if nr_non_abstaining_votes == 0: + return FellowshipNominationDecision.OUTCOME_NOT_ELECTED + + # By-laws 1.3.4 grand fellowship if there is a majority of non-abstaining votes. + # Agree is counted as +1, disagree as -1 + agree_ratio = (nr_votes_agree - nr_votes_disagree) / nr_non_abstaining_votes + if agree_ratio >= 0.5: + return FellowshipNominationDecision.OUTCOME_ELECTED + else: + return FellowshipNominationDecision.OUTCOME_NOT_ELECTED + class FellowshipNominationVote(models.Model): VOTE_AGREE = "agree" diff --git a/scipost_django/colleges/views.py b/scipost_django/colleges/views.py index ec3c3c6276b1455f20d5f60d4b55dd8662380ab0..8cc95efe419afb8fbf56a4f09fe71bcee18fc324 100644 --- a/scipost_django/colleges/views.py +++ b/scipost_django/colleges/views.py @@ -961,7 +961,9 @@ def _hx_nomination_vote(request, voting_round_id): def _hx_nomination_decision_form(request, round_id): voting_round = get_object_or_404(FellowshipNominationVotingRound, pk=round_id) nomination = voting_round.nomination - decision_form = FellowshipNominationDecisionForm(request.POST or None) + decision_form = FellowshipNominationDecisionForm( + request.POST or None, voting_round=voting_round + ) if decision_form.is_valid(): decision = decision_form.save() nomination.add_event(description="Decision fixed", by=request.user.contributor) @@ -974,8 +976,6 @@ def _hx_nomination_decision_form(request, round_id): nomination.add_event( description="Invitation created", by=request.user.contributor ) - else: - decision_form.fields["voting_round"].initial = voting_round context = { "voting_round": voting_round, "decision_form": decision_form,