diff --git a/scipost_django/colleges/forms.py b/scipost_django/colleges/forms.py index 2fba465b63896513bf87fa8555f303a8ebbbe00c..e076868a1237e88b5377bac6744f555bd0556103 100644 --- a/scipost_django/colleges/forms.py +++ b/scipost_django/colleges/forms.py @@ -24,6 +24,8 @@ from submissions.models import Submission from scipost.forms import RequestFormMixin from scipost.models import Contributor +from colleges.permissions import is_edadmin + from .models import ( College, Fellowship, @@ -417,7 +419,10 @@ class FellowshipNominationForm(forms.ModelForm): self.profile = kwargs.pop("profile") super().__init__(*args, **kwargs) self.fields["college"].queryset = College.objects.filter( - acad_field=self.profile.acad_field + acad_field=self.profile.acad_field, + # id__in=Fellowship.objects.active() + # .filter(contributor=self.fields["nominated_by"].initial) + # .values_list("college", flat=True), ) self.fields["college"].empty_label = None self.fields["nominator_comments"].label = False @@ -456,6 +461,16 @@ class FellowshipNominationForm(forms.ModelForm): self.add_error( "college", "Mismatch between college.acad_field and profile.acad_field." ) + if (not is_edadmin(data["nominated_by"].user)) and ( + data["college"].id + not in Fellowship.objects.active() + .filter(contributor=data["nominated_by"]) + .values_list("college", flat=True) + ): + self.add_error( + "college", + "You do not have an active Fellowship in the selected College.", + ) return data def save(self): @@ -515,10 +530,15 @@ class FellowshipNominationForm(forms.ModelForm): class FellowshipNominationSearchForm(forms.Form): + all_nominations = FellowshipNomination.objects.all() + nomination_colleges = all_nominations.values_list("college", flat=True).distinct() + nominee = forms.CharField(max_length=100, required=False, label="Nominee") college = forms.MultipleChoiceField( - choices=College.objects.all().order_by("name").values_list("id", "name"), + choices=College.objects.filter(id__in=nomination_colleges) + .order_by("name") + .values_list("id", "name"), required=False, ) @@ -551,6 +571,7 @@ class FellowshipNominationSearchForm(forms.Form): ("latest_round_open", "Voting start"), ("latest_round_decision_outcome", "Decision"), ("profile__last_name", "Nominee"), + ("nominated_on", "Nominated date"), ), required=False, ) @@ -653,9 +674,8 @@ class FellowshipNominationSearchForm(forms.Form): .distinct() ) - if self.cleaned_data.get("can_vote") or not self.user.has_perm( - "scipost.can_view_all_nomination_voting_rounds" - ): + if self.cleaned_data.get("can_vote"): + # or not self.user.has_perm("scipost.can_view_all_nomination_voting_rounds"): # Restrict rounds to those the user can vote on nominations = nominations.with_user_votable_rounds(self.user).distinct() @@ -889,9 +909,8 @@ class FellowshipNominationVotingRoundSearchForm(forms.Form): rounds = FellowshipNominationVotingRound.objects.all() - if self.cleaned_data.get("can_vote") or not self.user.has_perm( - "scipost.can_view_all_nomination_voting_rounds" - ): + if self.cleaned_data.get("can_vote"): + # or not self.user.has_perm("scipost.can_view_all_nomination_voting_rounds"): # Restrict rounds to those the user can vote on rounds = rounds.where_user_can_vote(self.user) diff --git a/scipost_django/colleges/templates/colleges/_hx_nomination_li_contents.html b/scipost_django/colleges/templates/colleges/_hx_nomination_li_contents.html index a0abaa3bca27909659b697a9e5e70d75c320d435..27a967d38b5f08b246d935d98bea4feb95b3e87e 100644 --- a/scipost_django/colleges/templates/colleges/_hx_nomination_li_contents.html +++ b/scipost_django/colleges/templates/colleges/_hx_nomination_li_contents.html @@ -1,3 +1,6 @@ +{% load user_groups %} +{% is_ed_admin request.user as is_ed_admin %} + <div class="p-2"> <div class="row mb-0"> @@ -88,7 +91,7 @@ {% comment %} or "active_senior_fellow" in user_roles {% endcomment %} - {% if "edadmin" in user_roles %} + {% if is_ed_admin %} <div class="col-12 col-md mb-3"> <details class="card"> <summary class="card-header d-flex flex-row justify-content-between list-triangle"> @@ -129,16 +132,22 @@ </div> </div> - <details {% if not nomination.invitation %}open{% endif %} class="card mb-3"> - <summary class="card-header list-triangle">Voting Rounds</summary> - <div class="card-body"> - <div hx-get="{% url 'colleges:_hx_nomination_voting_rounds_tab' nomination_id=nomination.id round_id=nomination.latest_voting_round.id|default:0 %}" - hx-trigger="intersect once"></div> - </div> - </details> + {% if nomination.voting_rounds.exists or perms.scipost.can_manage_college_composition %} + <details + {% if not nomination.invitation or 'edadmin' not in user_roles %}open{% endif %} + class="card mb-3"> + <summary class="card-header list-triangle">Voting Rounds</summary> + <div class="card-body"> + <div hx-get="{% url 'colleges:_hx_nomination_voting_rounds_tab' nomination_id=nomination.id round_id=nomination.latest_voting_round.id|default:0 %}" + hx-trigger="intersect once"></div> + </div> + </details> + {% endif %} - {% if "edadmin" in user_roles and nomination.decision.outcome == 'elected' %} - <details {% if nomination.invitation %}open{% endif %} class="card"> + {% if is_ed_admin and nomination.decision.outcome == 'elected' %} + <details + {% if nomination.invitation %}open{% endif %} + class="card"> <summary class="card-header d-flex flex-row justify-content-between list-triangle"> <div>Invitation</div> <div>{{ nomination.invitation.get_response_display }}</div> diff --git a/scipost_django/colleges/templates/colleges/_hx_nomination_vote.html b/scipost_django/colleges/templates/colleges/_hx_nomination_vote.html index 9cb3d1f68e39c8eb9b28a2230fd694779842d662..2ae93766053e4ae5505c9852e139502ae30db87d 100644 --- a/scipost_django/colleges/templates/colleges/_hx_nomination_vote.html +++ b/scipost_django/colleges/templates/colleges/_hx_nomination_vote.html @@ -1,25 +1,19 @@ -<div class="row"> - <div class="col-12 col-md"> - <h3>Cast your vote:</h3> +<h3>Cast your vote:</h3> - {% for vote_option, color in vote_options %} +{% for vote_option, color in vote_options %} - <form hx-post="{% url 'colleges:_hx_nomination_vote' voting_round_id=voting_round.id %}" - hx-target="#nomination-{{ voting_round.nomination.id }}-vote"> - {% csrf_token %} - <input type="hidden" name="vote" value="{{ vote_option }}" /> - <button class="btn d-flex justify-content-between align-items-center w-100 mb-2 bg-{{ color }} text-white"> - <div>{{ vote_option|title }}</div> + <form hx-post="{% url 'colleges:_hx_nomination_vote' voting_round_id=voting_round.id %}" + hx-target="#nomination-{{ voting_round.nomination.id }}-vote"> + {% csrf_token %} + <input type="hidden" name="vote" value="{{ vote_option }}" /> + <button class="btn d-flex justify-content-between align-items-center w-100 mb-2 bg-{{ color }} text-white"> + <div>{{ vote_option|title }}</div> - {% if vote_object.vote == vote_option %} - {% include 'bi/check-square-fill.html' %} - {% endif %} + {% if vote_object.vote == vote_option %} + {% include 'bi/check-square-fill.html' %} + {% endif %} - </button> - </form> + </button> + </form> - {% endfor %} - - - </div> -</div> +{% endfor %} diff --git a/scipost_django/colleges/templates/colleges/_hx_voting_round_details.html b/scipost_django/colleges/templates/colleges/_hx_voting_round_details.html index ac91b51e5d5886b85425644161fd1a61f0ebda9f..42f237aba1b5d15b85354f83c3a0a5d95e6ad984 100644 --- a/scipost_django/colleges/templates/colleges/_hx_voting_round_details.html +++ b/scipost_django/colleges/templates/colleges/_hx_voting_round_details.html @@ -8,7 +8,7 @@ hx-trigger="intersect once"></div> </div> - <div class="col-auto d-flex flex-column justify-content-between"> + <div class="col-12 col-md-auto d-flex flex-column justify-content-between"> {% if not voting_round.is_closed %} @@ -42,10 +42,9 @@ </button> </div> - {% elif session_fellowship and session_fellowship in voting_round.eligible_to_vote.all %} + {% elif session_fellowship and session_fellowship in voting_round.eligible_to_vote.all and voting_round.is_open %} <div id="nomination-{{ voting_round.nomination.id }}-vote" - class="col-12 col-md-4" hx-get="{% url 'colleges:_hx_nomination_vote' voting_round_id=voting_round.id %}" hx-trigger="intersect once"></div> diff --git a/scipost_django/colleges/views.py b/scipost_django/colleges/views.py index bab345269f459c79570729066b95cf3e62e2bf11..a3ab0c3e22c10a88aa955945a7a858d52b98e850 100644 --- a/scipost_django/colleges/views.py +++ b/scipost_django/colleges/views.py @@ -1060,6 +1060,14 @@ def _hx_nomination_vote(request, voting_round_id): pk=voting_round_id, eligible_to_vote=fellowship, ) + + # Check if the voting round is still open + if not voting_round.is_open: + return HTMXResponse( + """You cannot vote in non-open rounds.""", + tag="danger", + ) + vote_options_with_color = [ (FellowshipNominationVote.VOTE_AGREE, "success"), (FellowshipNominationVote.VOTE_ABSTAIN, "warning"),