SciPost Code Repository

Skip to content
Snippets Groups Projects
Commit 0dd6a9fc authored by Jean-Sébastien Caux's avatar Jean-Sébastien Caux
Browse files

Enable PotFel nominations

parent 97d7d5f7
No related branches found
No related tags found
No related merge requests found
......@@ -4,6 +4,7 @@ __license__ = "AGPL v3"
POTENTIAL_FELLOWSHIP_IDENTIFIED = 'identified'
POTENTIAL_FELLOWSHIP_NOMINATED = 'nominated'
POTENTIAL_FELLOWSHIP_ELECTION_VOTE_ONGOING = 'electionvoteongoing'
POTENTIAL_FELLOWSHIP_ELECTED = 'elected'
POTENTIAL_FELLOWSHIP_NOT_ELECTED = 'notelected'
POTENTIAL_FELLOWSHIP_INVITED = 'invited'
......@@ -21,6 +22,7 @@ POTENTIAL_FELLOWSHIP_SCIPOST_EMERITUS = 'emeritus'
POTENTIAL_FELLOWSHIP_STATUSES = (
(POTENTIAL_FELLOWSHIP_IDENTIFIED, 'Identified as potential Fellow'),
(POTENTIAL_FELLOWSHIP_NOMINATED, 'Nominated for Fellowship'),
(POTENTIAL_FELLOWSHIP_ELECTION_VOTE_ONGOING, 'Election vote ongoing'),
(POTENTIAL_FELLOWSHIP_ELECTED, 'Elected by the College'),
(POTENTIAL_FELLOWSHIP_NOT_ELECTED, 'Not elected by the College'),
(POTENTIAL_FELLOWSHIP_INVITED, 'Invited to become Fellow'),
......
......@@ -10,9 +10,11 @@ from ajax_select.fields import AutoCompleteSelectField
from proceedings.models import Proceedings
from submissions.models import Submission
from scipost.forms import RequestFormMixin
from scipost.models import Contributor
from .models import Fellowship, PotentialFellowship, PotentialFellowshipEvent
from .constants import POTENTIAL_FELLOWSHIP_NOMINATED
class AddFellowshipForm(forms.ModelForm):
......@@ -224,12 +226,26 @@ class FellowshipAddProceedingsForm(forms.ModelForm):
return fellowship
class PotentialFellowshipForm(forms.ModelForm):
class PotentialFellowshipForm(RequestFormMixin, forms.ModelForm):
profile = AutoCompleteSelectField('profile_lookup')
class Meta:
model = PotentialFellowship
fields = ['profile', 'status']
fields = ['profile']
def save(self):
"""
The default status is IDENTIFIED, which is appropriate if the
if the PotentialFellow was added directly by SciPost Admin.
But if the PotFel is nominated by somebody on the Advisory Board
or by an existing Fellow, the status is set to NOMINATED and
the person nominating is added to the list of in_agreement with election.
"""
if self.request.user.groups.filter(name__in=[
'AdvisoryBoard', 'EditorialCollege']).exists():
self.instance.status = POTENTIAL_FELLOWSHIP_NOMINATED
self.instance.in_agreement.add(self.request.user.contributor)
return super().save()
class PotentialFellowshipStatusForm(forms.ModelForm):
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2019-01-14 04:50
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('scipost', '0018_contributor_duplicate_of'),
('colleges', '0011_auto_20190113_1942'),
]
operations = [
migrations.AddField(
model_name='potentialfellowship',
name='elected',
field=models.NullBooleanField(),
),
migrations.AddField(
model_name='potentialfellowship',
name='in_abstain',
field=models.ManyToManyField(blank=True, related_name='in_abstain_with_election', to='scipost.Contributor'),
),
migrations.AddField(
model_name='potentialfellowship',
name='in_agreement',
field=models.ManyToManyField(blank=True, related_name='in_agreement_with_election', to='scipost.Contributor'),
),
migrations.AddField(
model_name='potentialfellowship',
name='in_disagreement',
field=models.ManyToManyField(blank=True, related_name='in_disagreement_with_election', to='scipost.Contributor'),
),
migrations.AddField(
model_name='potentialfellowship',
name='voting_deadline',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='voting deadline'),
),
migrations.AlterField(
model_name='potentialfellowship',
name='status',
field=models.CharField(choices=[('identified', 'Identified as potential Fellow'), ('nominated', 'Nominated for Fellowship'), ('electionvoteongoing', 'Election vote ongoing'), ('elected', 'Elected by the College'), ('notelected', 'Not elected by the College'), ('invited', 'Invited to become Fellow'), ('reinvited', 'Reinvited after initial invitation'), ('multiplyreinvited', 'Multiply reinvited'), ('declined', 'Declined the invitation'), ('unresponsive', 'Marked as unresponsive'), ('retired', 'Retired'), ('deceased', 'Deceased'), ('interested', 'Marked as interested, Fellowship being set up'), ('registered', 'Registered as Contributor'), ('activeincollege', 'Currently active in a College'), ('emeritus', 'SciPost Emeritus')], default='identified', max_length=32),
),
]
......@@ -72,7 +72,8 @@ class Fellowship(TimeStampedModel):
class PotentialFellowship(models.Model):
"""
A PotentialFellowship is defined when a researcher has been identified by
Admin or EdAdmin as a potential member of an Editorial College.
Admin or EdAdmin as a potential member of an Editorial College,
or when a current Advisory Board member or Fellow nominates the person.
It is linked to Profile as ForeignKey and not as OneToOne, since the same
person can eventually be approached on different occasions.
......@@ -84,6 +85,17 @@ class PotentialFellowship(models.Model):
profile = models.ForeignKey('profiles.Profile', on_delete=models.CASCADE)
status = models.CharField(max_length=32, choices=POTENTIAL_FELLOWSHIP_STATUSES,
default=POTENTIAL_FELLOWSHIP_IDENTIFIED)
in_agreement = models.ManyToManyField(
'scipost.Contributor',
related_name='in_agreement_with_election', blank=True)
in_abstain = models.ManyToManyField(
'scipost.Contributor',
related_name='in_abstain_with_election', blank=True)
in_disagreement = models.ManyToManyField(
'scipost.Contributor',
related_name='in_disagreement_with_election', blank=True)
voting_deadline = models.DateTimeField('voting deadline', default=timezone.now)
elected = models.NullBooleanField()
class Meta:
ordering = ['profile__last_name']
......
......@@ -18,6 +18,17 @@
<input type="submit" value="Submit" class="btn btn-primary">
</div>
</div>
<div class="row">
<div class="col-12">
<h3 class="mb-2">Not found?</h3>
<p>Then add to our database by <a href="{% url 'profiles:profile_create' %}" target="_blank">creating a new Profile</a> (opens in new window).</p>
</div>
</div>
{% endblock content %}
{% block footer_script %}
......
......@@ -20,8 +20,13 @@ $(document).ready(function($) {
{% block content %}
<div class="row">
<div class="col-12">
<a href="{% url 'colleges:potential_fellowship_create' %}">Add a Potential Fellowship</a>
{% if perms.scipost.can_add_potentialfellowship %}
<p>
Do you know somebody qualified who could serve as a Fellow?<br/>
Nominate them by <a href="{% url 'colleges:potential_fellowship_create' %}">adding a Potential Fellowship</a>.
</p>
<br/><br/>
{% endif %}
<p>
<ul class="list-inline">
<li class="list-inline-item">
......
......@@ -6,6 +6,7 @@ from django import template
from ..constants import (
POTENTIAL_FELLOWSHIP_IDENTIFIED, POTENTIAL_FELLOWSHIP_NOMINATED,
POTENTIAL_FELLOWSHIP_ELECTION_VOTE_ONGOING,
POTENTIAL_FELLOWSHIP_ELECTED, POTENTIAL_FELLOWSHIP_NOT_ELECTED,
POTENTIAL_FELLOWSHIP_INVITED, POTENTIAL_FELLOWSHIP_REINVITED,
POTENTIAL_FELLOWSHIP_MULTIPLY_REINVITED, POTENTIAL_FELLOWSHIP_DECLINED,
......@@ -27,6 +28,8 @@ def potfelstatuscolor(status):
color = hslColorWheel(12, 8)
elif status == POTENTIAL_FELLOWSHIP_NOMINATED:
color = 'Orange'
elif status == POTENTIAL_FELLOWSHIP_ELECTION_VOTE_ONGOING:
color = 'DodgerBlue'
elif status == POTENTIAL_FELLOWSHIP_ELECTED:
color = 'MediumSeaGreen'
elif status == POTENTIAL_FELLOWSHIP_NOT_ELECTED:
......
......@@ -25,7 +25,7 @@ from .forms import FellowshipForm, FellowshipTerminateForm, FellowshipRemoveSubm
from .models import Fellowship, PotentialFellowship, PotentialFellowshipEvent
from scipost.constants import SCIPOST_SUBJECT_AREAS
from scipost.mixins import PermissionsMixin, PaginationMixin
from scipost.mixins import PermissionsMixin, PaginationMixin, RequestViewMixin
from mails.forms import EmailTemplateForm
from mails.views import MailView
......@@ -302,7 +302,7 @@ def fellowship_add_proceedings(request, id):
# Potential Fellowships
class PotentialFellowshipCreateView(PermissionsMixin, CreateView):
class PotentialFellowshipCreateView(PermissionsMixin, RequestViewMixin, CreateView):
"""
Formview to create a new Potential Fellowship.
"""
......@@ -311,6 +311,11 @@ class PotentialFellowshipCreateView(PermissionsMixin, CreateView):
template_name = 'colleges/potentialfellowship_form.html'
success_url = reverse_lazy('colleges:potential_fellowships')
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
class PotentialFellowshipUpdateView(PermissionsMixin, UpdateView):
"""
......@@ -357,7 +362,7 @@ class PotentialFellowshipListView(PermissionsMixin, PaginationMixin, ListView):
"""
List the PotentialFellowship object instances.
"""
permission_required = 'scipost.can_manage_college_composition'
permission_required = 'scipost.can_view_potentialfellowship_list'
model = PotentialFellowship
paginate_by = 25
......@@ -379,7 +384,7 @@ class PotentialFellowshipListView(PermissionsMixin, PaginationMixin, ListView):
class PotentialFellowshipDetailView(PermissionsMixin, DetailView):
permission_required = 'scipost.can_manage_college_composition'
permission_required = 'scipost.can_view_potentialfellowship_list'
model = PotentialFellowship
def get_context_data(self, *args, **kwargs):
......
......@@ -125,6 +125,14 @@ class Command(BaseCommand):
codename='can_attend_VGMs',
name='Can attend Virtual General Meetings',
content_type=content_type)
can_view_potentialfellowship_list, created = Permission.objects.get_or_create(
codename='can_view_potentialfellowship_list',
name='Can view PotentialFellowship list',
content_type=content_type)
can_add_potentialfellowship, created = Permission.objects.get_or_create(
codename='can_add_potentialfellowship',
name='Can add PotentialFellowship',
content_type=content_type)
# Contributions (not related to submissions)
can_submit_comments, created = Permission.objects.get_or_create(
......@@ -350,6 +358,8 @@ class Command(BaseCommand):
can_create_profiles,
can_view_profiles,
can_manage_ontology,
can_view_potentialfellowship_list,
can_add_potentialfellowship,
])
FinancialAdmin.permissions.set([
......@@ -362,6 +372,8 @@ class Command(BaseCommand):
can_create_registration_invitations,
can_attend_VGMs,
can_view_statistics,
can_view_potentialfellowship_list,
can_add_potentialfellowship,
])
EditorialAdmin.permissions.set([
......@@ -393,6 +405,8 @@ class Command(BaseCommand):
can_create_profiles,
can_view_profiles,
can_manage_ontology,
can_view_potentialfellowship_list,
can_add_potentialfellowship,
])
EditorialCollege.permissions.set([
......@@ -403,6 +417,8 @@ class Command(BaseCommand):
can_attend_VGMs,
can_view_statistics,
can_manage_ontology,
can_view_potentialfellowship_list,
can_add_potentialfellowship,
])
VettingEditors.permissions.set([
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment