From b32ccb564181fbd05d7e9366d99c1179220df27f Mon Sep 17 00:00:00 2001 From: "J.-S. Caux" <J.S.Caux@uva.nl> Date: Mon, 22 Apr 2019 17:32:24 +0200 Subject: [PATCH] Rework Fellowship add and update into CBVs. --- colleges/forms.py | 50 ++++---- .../colleges/_potentialfellowship_card.html | 7 +- .../templates/colleges/fellowship_detail.html | 4 +- .../templates/colleges/fellowship_edit.html | 27 ----- ...llowship_add.html => fellowship_form.html} | 8 +- .../templates/colleges/fellowship_list.html | 3 - colleges/urls.py | 20 ++-- colleges/views.py | 112 ++++++++++-------- 8 files changed, 118 insertions(+), 113 deletions(-) delete mode 100644 colleges/templates/colleges/fellowship_edit.html rename colleges/templates/colleges/{fellowship_add.html => fellowship_form.html} (61%) diff --git a/colleges/forms.py b/colleges/forms.py index a09f430ab..e2f3a922a 100644 --- a/colleges/forms.py +++ b/colleges/forms.py @@ -18,37 +18,45 @@ from .constants import POTENTIAL_FELLOWSHIP_IDENTIFIED, POTENTIAL_FELLOWSHIP_NOM POTENTIAL_FELLOWSHIP_EVENT_DEFINED, POTENTIAL_FELLOWSHIP_EVENT_NOMINATED -class AddFellowshipForm(forms.ModelForm): +# class AddFellowshipForm(forms.ModelForm): +# class Meta: +# model = Fellowship +# fields = ( +# 'guest', +# 'contributor', +# 'start_date', +# 'until_date', +# ) + +# def __init__(self, *args, **kwargs): +# super().__init__(*args, **kwargs) +# self.fields['contributor'].queryset = Contributor.objects.active() +# self.fields['contributor'].label = "Fellow" + +# def clean(self): +# start = self.cleaned_data.get('start_date') +# until = self.cleaned_data.get('until_date') +# if start and until: +# if until <= start: +# self.add_error('until_date', 'The given dates are not in chronological order.') + + +class FellowshipForm(forms.ModelForm): class Meta: model = Fellowship fields = ( - 'guest', 'contributor', 'start_date', 'until_date', + 'guest', ) + help_texts = { + 'guest': '[select if this is a guest Fellowship]' + } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['contributor'].queryset = Contributor.objects.active() - self.fields['contributor'].label = "Fellow" - - def clean(self): - start = self.cleaned_data.get('start_date') - until = self.cleaned_data.get('until_date') - if start and until: - if until <= start: - self.add_error('until_date', 'The given dates are not in chronological order.') - - -class FellowshipForm(forms.ModelForm): - class Meta: - model = Fellowship - fields = ( - 'guest', - 'start_date', - 'until_date', - ) + self.fields['contributor'].disabled = True def clean(self): start = self.cleaned_data.get('start_date') diff --git a/colleges/templates/colleges/_potentialfellowship_card.html b/colleges/templates/colleges/_potentialfellowship_card.html index b6369bfca..cdb3b4882 100644 --- a/colleges/templates/colleges/_potentialfellowship_card.html +++ b/colleges/templates/colleges/_potentialfellowship_card.html @@ -33,7 +33,12 @@ <ul> <li><a href="{% url 'colleges:potential_fellowship_update' pk=potfel.id %}">Update</a> the data</li> <li><a href="{% url 'colleges:potential_fellowship_delete' pk=potfel.id %}">Delete</a> this Potential Fellowship</li> - <li><a href="{% url 'colleges:potential_fellowship_email_initial' pk=potfel.id %}">Prepare and send initial email</a></li> + <li>For named or elected: <a href="{% url 'colleges:potential_fellowship_email_initial' pk=potfel.id %}">prepare and send initial email</a></li> + {% if not potfel.profile.contributor %} + <li class="text-danger">N.B.: this potential Fellow is not yet registered as a Contributor</li> + {% else %} + <li>Accepted to serve as Fellow but not currently active in a College? <a href="{% url 'colleges:fellowship_create' contributor_id=potfel.profile.contributor.id %}">Set up a Fellowship</a></li> + {% endif %} </ul> </div> diff --git a/colleges/templates/colleges/fellowship_detail.html b/colleges/templates/colleges/fellowship_detail.html index 7687c8786..c5c83a2f4 100644 --- a/colleges/templates/colleges/fellowship_detail.html +++ b/colleges/templates/colleges/fellowship_detail.html @@ -55,7 +55,7 @@ {% csrf_token %} <button type="submit" class="btn btn-danger">Terminate Fellowship</button> </form> - <a href="{% url 'colleges:fellowship_edit' fellowship.id %}" class="btn btn-info ml-2">Edit Fellowship</a> + <a href="{% url 'colleges:fellowship_update' fellowship.id %}" class="btn btn-info ml-2">Update this Fellowship</a> </div> <div class="col-md-6"> <h3>All fellowships of this fellow</h3> @@ -89,7 +89,7 @@ {% endfor %} </tbody> </table> - <a href="{% url 'colleges:fellowship_add' %}?contributor={{ fellowship.contributor.id }}">Add new Fellowship for {{ fellowship.contributor }}</a> + <a href="{% url 'colleges:fellowship_create' contributor_id=fellowship.contributor.id %}">Add new Fellowship for {{ fellowship.contributor }}</a> </div> </div> diff --git a/colleges/templates/colleges/fellowship_edit.html b/colleges/templates/colleges/fellowship_edit.html deleted file mode 100644 index ed3070fb3..000000000 --- a/colleges/templates/colleges/fellowship_edit.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends 'colleges/base.html' %} - -{% load bootstrap %} - -{% block breadcrumb_items %} - {{ block.super }} - <a href="{% url 'colleges:colleges' %}" class="breadcrumb-item">Colleges</a> - <a href="{% url 'colleges:fellowships' %}" class="breadcrumb-item">Fellowships</a> - <a href="{{ fellowship.get_absolute_url }}" class="breadcrumb-item">Fellowship details</a> - <span class="breadcrumb-item">Edit Fellowship</span> -{% endblock %} - -{% block pagetitle %}: Edit Fellowship{% endblock pagetitle %} - -{% block content %} - <h1>Edit Fellowship</h1> - <h2 class="text-primary">{{ fellowship }}</h2> - <br> - - <form method="post"> - {% csrf_token %} - {{ form|bootstrap }} - <input class="btn btn-primary" type="submit" value="Save"> - </form> - - -{% endblock %} diff --git a/colleges/templates/colleges/fellowship_add.html b/colleges/templates/colleges/fellowship_form.html similarity index 61% rename from colleges/templates/colleges/fellowship_add.html rename to colleges/templates/colleges/fellowship_form.html index 7748e83b1..2a6e898f0 100644 --- a/colleges/templates/colleges/fellowship_add.html +++ b/colleges/templates/colleges/fellowship_form.html @@ -6,19 +6,17 @@ {{ block.super }} <a href="{% url 'colleges:colleges' %}" class="breadcrumb-item">Colleges</a> <a href="{% url 'colleges:fellowships' %}" class="breadcrumb-item">Fellowships</a> - <span class="breadcrumb-item">Add Fellowship</span> + <span class="breadcrumb-item">{% if form.instance.id %}Update {{ form.instance }}{% else %}Add new Fellowship{% endif %}</span> {% endblock %} -{% block pagetitle %}: Add Fellowship{% endblock pagetitle %} +{% block pagetitle %}: Fellowship{% endblock pagetitle %} {% block content %} - <h1>Add Fellowship</h1> - <br> <form method="post"> {% csrf_token %} {{ form|bootstrap }} - <input class="btn btn-primary" type="submit" value="Add Fellowship"> + <input class="btn btn-primary" type="submit" value="Submit"> </form> diff --git a/colleges/templates/colleges/fellowship_list.html b/colleges/templates/colleges/fellowship_list.html index 993ac50e6..71d77d104 100644 --- a/colleges/templates/colleges/fellowship_list.html +++ b/colleges/templates/colleges/fellowship_list.html @@ -16,9 +16,6 @@ <h1 class="highlight">Fellowships</h1> <ul> - <li> - <a href="{% url 'colleges:fellowship_add' %}">Add new Fellowship</a> - </li> <li> View <a href="{% add_get_parameters type='all' %}">all</a>, <a href="{% add_get_parameters type='regular' %}">only regular</a> or diff --git a/colleges/urls.py b/colleges/urls.py index 26cb7f036..8755d2e3b 100644 --- a/colleges/urls.py +++ b/colleges/urls.py @@ -16,6 +16,19 @@ urlpatterns = [ name='colleges' ), # Fellowships + url( + r'^fellowships/(?P<contributor_id>[0-9]+)/add/$', + views.FellowshipCreateView.as_view(), + name='fellowship_create'), + url( + r'^fellowships/(?P<pk>[0-9]+)/update/$', + views.FellowshipUpdateView.as_view(), + name='fellowship_update'), + url( + r'^fellowships/(?P<pk>[0-9]+)/$', + views.FellowshipDetailView.as_view(), + name='fellowship_detail' + ), url( r'^fellowships/(?P<discipline>[a-zA-Z]+)/(?P<expertise>[a-zA-Z:]+)/$', views.FellowshipListView.as_view(), @@ -31,13 +44,6 @@ urlpatterns = [ views.FellowshipListView.as_view(), name='fellowships' ), - url(r'^fellowships/add$', views.fellowship_add, name='fellowship_add'), - url( - r'^fellowships/(?P<pk>[0-9]+)/$', - views.FellowshipDetailView.as_view(), - name='fellowship_detail' - ), - url(r'^fellowships/(?P<id>[0-9]+)/edit$', views.fellowship_edit, name='fellowship_edit'), url(r'^fellowships/(?P<id>[0-9]+)/terminate$', views.fellowship_terminate, name='fellowship_terminate'), url(r'^fellowships/submissions/{regex}/$'.format( diff --git a/colleges/views.py b/colleges/views.py index 8b62906b9..f13fa5afa 100644 --- a/colleges/views.py +++ b/colleges/views.py @@ -2,6 +2,8 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" __license__ = "AGPL v3" +import datetime + from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required from django.core.urlresolvers import reverse, reverse_lazy @@ -17,10 +19,11 @@ from submissions.models import Submission from .constants import ( POTENTIAL_FELLOWSHIP_STATUSES, POTENTIAL_FELLOWSHIP_EVENT_STATUSUPDATED, - POTENTIAL_FELLOWSHIP_INVITED, potential_fellowship_statuses_dict, + POTENTIAL_FELLOWSHIP_INVITED, POTENTIAL_FELLOWSHIP_ACTIVE_IN_COLLEGE, + potential_fellowship_statuses_dict, POTENTIAL_FELLOWSHIP_EVENT_VOTED_ON, POTENTIAL_FELLOWSHIP_EVENT_EMAILED) from .forms import FellowshipForm, FellowshipTerminateForm, FellowshipRemoveSubmissionForm,\ - FellowshipAddSubmissionForm, AddFellowshipForm, SubmissionAddFellowshipForm,\ + FellowshipAddSubmissionForm, SubmissionAddFellowshipForm,\ FellowshipRemoveProceedingsForm, FellowshipAddProceedingsForm, SubmissionAddVotingFellowForm,\ FellowVotingRemoveSubmissionForm,\ PotentialFellowshipForm, PotentialFellowshipStatusForm, PotentialFellowshipEventForm @@ -28,6 +31,7 @@ from .models import Fellowship, PotentialFellowship, PotentialFellowshipEvent from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS, subject_areas_raw_dict from scipost.mixins import PermissionsMixin, PaginationMixin, RequestViewMixin +from scipost.models import Contributor from mails.views import MailView @@ -51,6 +55,65 @@ class EditorialCollegesView(ListView): return context +class FellowshipCreateView(PermissionsMixin, CreateView): + """ + Create a new Fellowship instance for an existing Contributor. + + A new Fellowship can be created only for: + * an existing Fellow who is renewed + * out of an existing PotentialFellowship (elected, or named by Admin) + + If the elected/named Fellow does not yet have a Contributor object, + this must be set up first. + """ + permission_required = 'scipost.can_manage_college_composition' + form_class = FellowshipForm + template_name = 'colleges/fellowship_form.html' + + def get_initial(self): + initial = super().get_initial() + contributor = get_object_or_404(Contributor, pk=self.kwargs.get('contributor_id')) + initial.update({ + 'contributor': contributor.id, + 'start_date': datetime.date.today(), + 'until_date': datetime.date.today() + datetime.timedelta(days=int(5*365.25)) + }) + return initial + + def form_valid(self, form): + """ + Save the new Fellowship, and update the status of any existing PotentialFellowship. + """ + self.object = form.save() + potfels = PotentialFellowship.objects.filter(profile=self.object.contributor.profile) + for potfel in potfels: + potfelevent = PotentialFellowshipEvent( + potfel=potfel, + event=POTENTIAL_FELLOWSHIP_EVENT_STATUSUPDATED, + comments='Fellowship created for this Potential Fellow', + noted_on=timezone.now(), + noted_by=self.request.user.contributor) + potfelevent.save() + potfel.status = POTENTIAL_FELLOWSHIP_ACTIVE_IN_COLLEGE + potfel.save() + return redirect(self.get_success_url()) + + +class FellowshipUpdateView(PermissionsMixin, UpdateView): + """ + Update an existing Fellowship. + """ + permission_required = 'scipost.can_manage_college_composition' + model = Fellowship + form_class = FellowshipForm + template_name = 'colleges/fellowship_form.html' + + +class FellowshipDetailView(PermissionsMixin, DetailView): + permission_required = 'scipost.can_manage_college_composition' + model = Fellowship + + class FellowshipListView(PermissionsMixin, PaginationMixin, ListView): """ List Fellowship instances (accessible to College managers). @@ -83,51 +146,6 @@ class FellowshipListView(PermissionsMixin, PaginationMixin, ListView): return context -class FellowshipDetailView(PermissionsMixin, DetailView): - permission_required = 'scipost.can_manage_college_composition' - model = Fellowship - - -@login_required -@permission_required('scipost.can_manage_college_composition', raise_exception=True) -def fellowship_add(request): - """ - Create a new Fellowship. - """ - form = AddFellowshipForm(request.POST or None, initial=request.GET or None) - - if form.is_valid(): - fellowship = form.save() - messages.success(request, 'Fellowship added.') - return redirect(fellowship.get_absolute_url()) - - context = { - 'form': form - } - return render(request, 'colleges/fellowship_add.html', context) - - -@login_required -@permission_required('scipost.can_manage_college_composition', raise_exception=True) -def fellowship_edit(request, id): - """ - Edit basic information about fellowship. - """ - fellowship = get_object_or_404(Fellowship, id=id) - form = FellowshipForm(request.POST or None, instance=fellowship) - - if form.is_valid(): - form.save() - messages.success(request, 'Fellowship updated.') - return redirect(fellowship.get_absolute_url()) - - context = { - 'fellowship': fellowship, - 'form': form - } - return render(request, 'colleges/fellowship_edit.html', context) - - @login_required @permission_required('scipost.can_manage_college_composition', raise_exception=True) def fellowship_terminate(request, id): -- GitLab