From b3d8b12c80e813ad039c78a362c2aef174dc254e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org> Date: Fri, 28 Jan 2022 22:33:10 +0100 Subject: [PATCH] Basic nomination form, but dal is bugging --- scipost_django/colleges/forms.py | 72 ++++++++++++++++++- scipost_django/colleges/models/nomination.py | 8 +++ .../templates/colleges/nominations.html | 11 +++ scipost_django/colleges/views.py | 14 +++- 4 files changed, 102 insertions(+), 3 deletions(-) diff --git a/scipost_django/colleges/forms.py b/scipost_django/colleges/forms.py index 81f8ad6bc..294d50619 100644 --- a/scipost_django/colleges/forms.py +++ b/scipost_django/colleges/forms.py @@ -283,6 +283,67 @@ class PotentialFellowshipEventForm(forms.ModelForm): # Nominations # ############### +class FellowshipNominationForm(forms.Form): + + college = forms.ModelChoiceField( + queryset=College.objects.all(), + ) + nominee = forms.ModelChoiceField( + queryset=Profile.objects.all(), + widget=autocomplete.ModelSelect2(url='/profiles/profile-autocomplete'), + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper() + self.helper.layout = Layout( + Div( + Div(FloatingField('college'), css_class='col-lg-6'), + Div(FloatingField('nominee'), css_class='col-lg-6'), + css_class='row' + ) + ) + + def clean_nominee(self): + """ + Requirements: + + - no current Fellowship exists + - no current FellowshipNomination exists + - no 'not elected' decision in last 2 years + - no invitation was turned down in the last 2 years + """ + nominee = self.cleaned_data['nominee'] + if Fellowship.objects.active().regular_or_senior().filter( + contributor__profile=nominee).exists(): + self.add_error('This Profile is associated to an active Fellowship.') + latest_nomination = FellowshipNomination.objects.filter( + profile=self.cleaned_data.get('nominee')).first() + try: + if (latest_nomination.decision.fixed_on + + datetime.timedelta(days=730)) > timezone.now(): + if latest_nomination.decision.elected: + try: + if latest_nomination.invitation.declined: + self.add_error('Invitation declined less that 2 years ago. ' + 'Wait to try again.') + else: + self.add_error('Already elected, invitation in process.') + except AttributeError: + self.add_error('Already elected, invitation pending.') + + self.add_error('Election failed less that 2 years ago. Must wait.') + except AttributeError: # no decision yet + self.add_error('This Profile is associated to an ongoing Nomination process.') + return nominee + + def clean(self): + data = super().clean() + if data['college'].acad_field != data['nominee'].acad_field: + self.add_error('Mismatch between college.acad_field and nominee.acad_field.') + return data + + class FellowshipNominationSearchForm(forms.Form): """Filter a FellowshipNomination queryset using basic search fields.""" @@ -305,6 +366,10 @@ class FellowshipNominationSearchForm(forms.Form): label='Name (through Profile)', required=False ) + # name = forms.CharField( + # max_length=128, + # required=False + # ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -316,7 +381,8 @@ class FellowshipNominationSearchForm(forms.Form): css_class='row' ), Div( - Div(FloatingField('profile'), css_class='col-lg-6'), + Div(FloatingField('profile'), css_id='search-profile', css_class='col-lg-6'), + #Div(FloatingField('name'), css_class='col-lg-6'), css_class='row' ), ) @@ -325,6 +391,10 @@ class FellowshipNominationSearchForm(forms.Form): if self.cleaned_data.get('profile'): nominations = FellowshipNomination.objects.filter( profile=self.cleaned_data.get('profile')) + # if self.cleaned_data.get('name'): + # nominations = FellowshipNomination.objects.filter( + # Q(profile__last_name__icontains=self.cleaned_data.get('profile')) | + # Q(profile__first_name__icontains=self.cleaned_data.get('profile'))) else: nominations = FellowshipNomination.objects.all() if self.cleaned_data.get('college'): diff --git a/scipost_django/colleges/models/nomination.py b/scipost_django/colleges/models/nomination.py index 65f7be47a..31c9298d5 100644 --- a/scipost_django/colleges/models/nomination.py +++ b/scipost_django/colleges/models/nomination.py @@ -163,6 +163,10 @@ class FellowshipNominationDecision(models.Model): def __str__(self): return f'Decision for {nomination}: {self.get_outcome_display()}' + @property + def elected(self): + return self.outcome == self.OUTCOME_ELECTED + class FellowshipInvitation(models.Model): @@ -206,3 +210,7 @@ class FellowshipInvitation(models.Model): def __str__(self): return f'Invitation for {nomination}' + + @property + def declined(self): + return self.response == self.RESPONSE_DECLINED diff --git a/scipost_django/colleges/templates/colleges/nominations.html b/scipost_django/colleges/templates/colleges/nominations.html index e3840f52b..8a75ad627 100644 --- a/scipost_django/colleges/templates/colleges/nominations.html +++ b/scipost_django/colleges/templates/colleges/nominations.html @@ -15,6 +15,17 @@ <h1 class="highlight">Fellowship Nominations</h1> + <div class="card"> + <div class="card-header"> + Nominate somebody for a Fellowship + </div> + <div class="card-body"> + <form> + {% crispy nomination_form %} + </form> + </div> + </div> + <div class="card"> <div class="card-header"> Search / filter diff --git a/scipost_django/colleges/views.py b/scipost_django/colleges/views.py index df3c2e387..7c56720c8 100644 --- a/scipost_django/colleges/views.py +++ b/scipost_django/colleges/views.py @@ -34,7 +34,7 @@ from .forms import ( SubmissionAddFellowshipForm, FellowshipRemoveProceedingsForm, FellowshipAddProceedingsForm, PotentialFellowshipForm, PotentialFellowshipStatusForm, PotentialFellowshipEventForm, - FellowshipNominationSearchForm, + FellowshipNominationForm, FellowshipNominationSearchForm, ) from .models import College, Fellowship, PotentialFellowship, PotentialFellowshipEvent @@ -534,7 +534,8 @@ def nominations(request): List Nominations. """ context = { - 'form': FellowshipNominationSearchForm() + 'form': FellowshipNominationSearchForm(), + 'nomination_form': FellowshipNominationForm() } return render(request, 'colleges/nominations.html', context) @@ -552,3 +553,12 @@ def _hx_nominations(request): page_obj = paginator.get_page(page_nr) context = { 'page_obj': page_obj } return render(request, 'colleges/_hx_nominations.html', context) + + +# @login_required +# @user_passes_test(is_edadmin_or_active_regular_or_senior_fellow) +# def _hx_nominate(request): +# form = FellowshipNominationForm(request.POST or None) +# if form.is_valid(): +# nomination = form.save() +# return render(reverse('colleges/_hx_nominations.html -- GitLab