diff --git a/scipost/admin.py b/scipost/admin.py index 9885605ac927d8d2bb975c5e7efc89f429710dd2..00f47a7b248664fca1678ad6c5f6556c5fa0143d 100644 --- a/scipost/admin.py +++ b/scipost/admin.py @@ -29,6 +29,11 @@ class RemarkAdmin(admin.ModelAdmin): admin.site.register(Remark, RemarkAdmin) +class DraftInvitationAdmin(admin.ModelAdmin): + search_fields = ['first_name', 'last_name', 'email', 'processed'] + +admin.site.register(DraftInvitation, DraftInvitationAdmin) + class RegistrationInvitationAdmin(admin.ModelAdmin): search_fields = ['first_name', 'last_name', 'email', 'invitation_key'] diff --git a/scipost/forms.py b/scipost/forms.py index 010507cacb76ed84c55cde0acd2c770d48442bf6..2753365557085f8811b43d20245e1c59eef9626b 100644 --- a/scipost/forms.py +++ b/scipost/forms.py @@ -53,6 +53,38 @@ class RegistrationForm(forms.Form): captcha = CaptchaField(label='* Answer this simple maths question:') +class DraftInvitationForm(forms.ModelForm): + class Meta: + model = DraftInvitation + fields = ['title', 'first_name', 'last_name', 'email', + 'invitation_type', + 'cited_in_submission', 'cited_in_publication',] + + def __init__(self, *args, **kwargs): + super(DraftInvitationForm, self).__init__(*args, **kwargs) + self.fields['cited_in_submission'] = forms.ModelChoiceField( + queryset=Submission.objects.all().exclude( + status__in=SUBMISSION_STATUS_PUBLICLY_UNLISTED).order_by('-submission_date'), + required=False) + self.fields['cited_in_publication'] = forms.ModelChoiceField( + queryset=Publication.objects.all().order_by('-publication_date'), + required=False) + self.helper = FormHelper() + self.helper.layout = Layout( + Div( + Div( + Field('title'), Field('first_name'), Field('last_name'), + Field('email'), Field('invitation_type'), + css_class="col-6"), + Div( + Submit('submit', 'Save draft'), + css_class="col-6"), + css_class="row"), + Div(Field('cited_in_submission'),), + Div(Field('cited_in_publication'),), + ) + + class RegistrationInvitationForm(forms.ModelForm): class Meta: model = RegistrationInvitation diff --git a/scipost/management/commands/add_groups_and_permissions.py b/scipost/management/commands/add_groups_and_permissions.py index ac87aa78d57dcfd2cc5654b26759d21422837da2..51d2f874401a483a89db1de75e2da83aab9b1d60 100644 --- a/scipost/management/commands/add_groups_and_permissions.py +++ b/scipost/management/commands/add_groups_and_permissions.py @@ -18,21 +18,24 @@ class Command(BaseCommand): RegisteredContributors, created = Group.objects.get_or_create(name='Registered Contributors') Testers, created = Group.objects.get_or_create(name='Testers') Ambassadors, created = Group.objects.get_or_create(name='Ambassadors') + JuniorAmbassadors, created = Group.objects.get_or_create(name='Junior Ambassadors') # Create Permissions content_type = ContentType.objects.get_for_model(Contributor) - # Registration + # Registration and invitations can_vet_registration_requests, created = Permission.objects.get_or_create( codename='can_vet_registration_requests', name= 'Can vet registration requests', content_type=content_type) + can_draft_registration_invitations, created = Permission.objects.get_or_create( + codename='can_draft_registration_invitations', + name= 'Can draft registration invitations', + content_type=content_type) can_manage_registration_invitations, created = Permission.objects.get_or_create( codename='can_manage_registration_invitations', name= 'Can manage registration invitations', content_type=content_type) - - # Invitations can_invite_Fellows, created = Permission.objects.get_or_create( codename='can_invite_Fellows', name= 'Can invite Fellows', @@ -189,5 +192,8 @@ class Command(BaseCommand): Ambassadors.permissions.add( can_manage_registration_invitations, ) + JuniorAmbassadors.permissions.add( + can_draft_registration_invitations, + ) self.stdout.write(self.style.SUCCESS('Successfully created groups and permissions')) diff --git a/scipost/models.py b/scipost/models.py index 87f37443cb40e21f86582f576134c15fd9f3c518..803d4fca6c216ef3d630b5b8cfdd7ddd677a7b4f 100644 --- a/scipost/models.py +++ b/scipost/models.py @@ -388,6 +388,31 @@ INVITATION_STYLE = ( ('P', 'personal'), ) +class DraftInvitation(models.Model): + """ + Draft of an invitation, filled in by an officer. + """ + title = models.CharField(max_length=4, choices=TITLE_CHOICES) + first_name = models.CharField(max_length=30, default='') + last_name = models.CharField(max_length=30, default='') + email = models.EmailField() + invitation_type = models.CharField(max_length=2, choices=INVITATION_TYPE, default='C') + cited_in_submission = models.ForeignKey('submissions.Submission', + on_delete=models.CASCADE, + blank=True, null=True) + cited_in_publication = models.ForeignKey('journals.Publication', + on_delete=models.CASCADE, + blank=True, null=True) + drafted_by = models.ForeignKey(Contributor, + on_delete=models.CASCADE, + blank=True, null=True) + date_drafted = models.DateTimeField(default=timezone.now) + processed = models.BooleanField(default=False) + + def __str__ (self): + return (self.invitation_type + ' ' + self.first_name + ' ' + self.last_name) + + class RegistrationInvitation(models.Model): """ Invitation to particular persons for registration diff --git a/scipost/templates/scipost/draft_registration_invitation.html b/scipost/templates/scipost/draft_registration_invitation.html new file mode 100644 index 0000000000000000000000000000000000000000..02d8ceeff467beaa5c3f7d3895c8f3c339d1e2d5 --- /dev/null +++ b/scipost/templates/scipost/draft_registration_invitation.html @@ -0,0 +1,268 @@ +{% extends 'scipost/base.html' %} + +{% block pagetitle %}: registration invitations{% endblock pagetitle %} + +{% block bodysup %} + +{% load scipost_extras %} + +<script> + $(document).ready(function(){ + + $("#div_id_cited_in_submission").hide(); + $("#div_id_cited_in_publication").hide(); + + $('select#id_invitation_type').on('change', function() { + switch ($('select#id_invitation_type').val()) { + case "ci": + $("#div_id_cited_in_submission").show(); + $("#div_id_cited_in_publication").hide(); + break; + case "cp": + $("#div_id_cited_in_submission").hide(); + $("#div_id_cited_in_publication").show(); + break; + default: + $("#div_id_cited_in_submission").hide(); + $("#div_id_cited_in_publication").hide(); + } + }); + }); +</script> + +<section> + <div class="flex-greybox"> + <h1>Draft a registration invitation</h1> + </div> +</section> +<hr class="hr12"/> +<section> + <div class="flex-greybox"> + <h2>Draft a new invitation:</h2> + </div> + {% if errormessage %} + <h3 style="color: red;">{{ errormessage }}</h3> + {% endif %} + <form action="{% url 'scipost:draft_registration_invitation' %}" method="post"> + {% csrf_token %} + {% load crispy_forms_tags %} + {% crispy draft_inv_form %} + </form> +</section> +<hr class="hr12"/> +<section> + <div class="flex-greybox"> + <h2>Existing drafts (to be processed by Admin):</h2> + </div> + <table class="tableofInvitees"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date drafted</td><td>Type</td><td>Drafted by</td></tr> + {% for draft in existing_drafts %} + <tr> + <td>{{ draft.last_name }}</td> + <td>{{ draft.first_name }}</td> + <td>{{ draft.email }}</td> + <td>{{ draft.date_drafted }} </td> + <td>{{ draft.invitation_type }}</td> + <td>{{ draft.drafted_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> +</section> +<hr class="hr12"/> +<section> + <div class="flex-greybox"> + <h2>Invitations sent (response pending) EF ({{ nr_sent_reg_inv_fellows }}), C ({{ nr_sent_reg_inv_contrib }}), R ({{ nr_sent_reg_inv_ref }}), cited in sub ({{ nr_sent_reg_inv_cited_sub }}), cited in pub ({{ nr_sent_reg_inv_cited_pub }}):</h2> + </div> + <hr class="hr6"/> + <h3>Editorial Fellows ({{ nr_sent_reg_inv_fellows }})</h3> + <table class="tableofInvitees"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in sent_reg_inv_fellows %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + <hr class="hr6"/> + <h3>Normal Contributors ({{ nr_sent_reg_inv_contrib }})</h3> + <table class="tableofInvitees"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in sent_reg_inv_contrib %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + <hr class="hr6"/> + <h3>Referees ({{ nr_sent_reg_inv_ref }})</h3> + <table class="tableofInvitees"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in sent_reg_inv_ref %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + <hr class="hr6"/> + <h3>Cited in sub ({{ nr_sent_reg_inv_cited_sub }})</h3> + <table class="tableofInvitees"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in sent_reg_inv_cited_sub %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + <hr class="hr6"/> + <h3>Cited in pub ({{ nr_sent_reg_inv_cited_pub }})</h3> + <table class="tableofInvitees"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in sent_reg_inv_cited_pub %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> +</section> + <hr class="hr12"/> +<section> + <div class="flex-greybox"> + <h2>Invitations sent (responded) EF ({{ nr_resp_reg_inv_fellows }}), C ({{ nr_resp_reg_inv_contrib }}), R ({{ nr_resp_reg_inv_ref }}), cited in sub ({{ nr_resp_reg_inv_cited_sub }}), cited in pub ({{ nr_resp_reg_inv_cited_pub }}):</h2> + </div> + <hr class="hr6"/> + <h3>Editorial Fellows ({{ nr_resp_reg_inv_fellows }})</h3> + <table class="tableofInviteesResponded"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in resp_reg_inv_fellows %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + <hr class="hr6"/> + <h3>Normal Contributors ({{ nr_resp_reg_inv_contrib}})</h3> + <table class="tableofInviteesResponded"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in resp_reg_inv_contrib %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + + <hr class="hr6"/> + <h3>Referees ({{ nr_resp_reg_inv_ref }})</h3> + <table class="tableofInviteesResponded"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in resp_reg_inv_ref %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + + <hr class="hr6"/> + <h3>Cited in sub ({{ nr_resp_reg_inv_cited_sub }})</h3> + <table class="tableofInviteesResponded"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in resp_reg_inv_cited_sub %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + + <hr class="hr6"/> + <h3>Cited in pub ({{ nr_resp_reg_inv_cited_pub }})</h3> + <table class="tableofInviteesResponded"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in resp_reg_inv_cited_pub %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + + <hr class="hr6"/> + <h3>Declined</h3> + <table class="tableofInviteesDeclined"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date sent</td><td>Type</td><td>Invited by</td></tr> + {% for fellow in decl_reg_inv %} + <tr> + <td>{{ fellow.last_name }}</td> + <td>{{ fellow.first_name }}</td> + <td>{{ fellow.email }}</td> + <td>{{ fellow.date_sent }} </td> + <td>{{ fellow.invitation_type }}</td> + <td>{{ fellow.invited_by.user.last_name }}</td> + </tr> + {% endfor %} + </table> + +</section> + + +<hr class="hr12"/> + +<section> + <div class="flex-greybox"> + <h2>List of already-registered contributors:</h3> + </div> + <p> + {% for first_name, last_name in names_reg_contributors %} + {{ first_name }} {{ last_name }}, + {% endfor %} + </p> +</section> + +{% endblock bodysup %} diff --git a/scipost/templates/scipost/registration_invitations.html b/scipost/templates/scipost/registration_invitations.html index 358d20ea97e8ca930c66e267ca6d8c3d1d21ca76..f74909628e7797f71ad13b1c829c1ec66acdfab7 100644 --- a/scipost/templates/scipost/registration_invitations.html +++ b/scipost/templates/scipost/registration_invitations.html @@ -53,6 +53,26 @@ </form> </section> <hr class="hr12"/> +<section> + <div class="flex-greybox"> + <h2>Existing drafts (to be processed by Admin):</h2> + </div> + <table class="tableofInvitees"> + <tr><td>Last name</td><td>First name</td><td>Email</td><td>Date drafted</td><td>Type</td><td>Drafted by</td></tr> + {% for draft in existing_drafts %} + <tr> + <td>{{ draft.last_name }}</td> + <td>{{ draft.first_name }}</td> + <td>{{ draft.email }}</td> + <td>{{ draft.date_drafted }} </td> + <td>{{ draft.invitation_type }}</td> + <td>{{ draft.drafted_by.user.last_name }}</td> + <td><a href="{% url 'scipost:registration_invitations_from_draft' draft_id=draft.id %}">Process</a></td> + </tr> + {% endfor %} + </table> +</section> +<hr class="hr12"/> <section> <div class="flex-greybox"> <h2>Invitations sent (response pending) EF ({{ nr_sent_reg_inv_fellows }}), C ({{ nr_sent_reg_inv_contrib }}), R ({{ nr_sent_reg_inv_ref }}), cited in sub ({{ nr_sent_reg_inv_cited_sub }}), cited in pub ({{ nr_sent_reg_inv_cited_pub }}):</h2> diff --git a/scipost/urls.py b/scipost/urls.py index d5d51881cc8cd2ae226d811f301a1cf6ef566277..e9438ef27af09ec6be7c11d0a9f5c18fef22fd93 100644 --- a/scipost/urls.py +++ b/scipost/urls.py @@ -60,8 +60,12 @@ urlpatterns = [ views.vet_registration_requests, name='vet_registration_requests'), url(r'^vet_registration_request_ack/(?P<contributor_id>[0-9]+)$', views.vet_registration_request_ack, name='vet_registration_request_ack'), + url(r'^registration_invitations/(?P<draft_id>[0-9]+)$', + views.registration_invitations, name="registration_invitations_from_draft"), url(r'^registration_invitations$', views.registration_invitations, name="registration_invitations"), + url(r'^draft_registration_invitation$', + views.draft_registration_invitation, name="draft_registration_invitation"), url(r'^registration_invitations_cleanup$', views.registration_invitations_cleanup, name="registration_invitations_cleanup"), diff --git a/scipost/utils.py b/scipost/utils.py index 46ba72ff110c79d2a7699c693c3a99c3a99801a8..5747cbbba14e5ddde4b74d4a6debc3e394c52497 100644 --- a/scipost/utils.py +++ b/scipost/utils.py @@ -109,6 +109,13 @@ class Utils(object): else: return False + @classmethod + def email_already_drafted(cls): + if DraftInvitation.objects.filter(email=cls.form.cleaned_data['email']).exists(): + return True + else: + return False + @classmethod def create_and_save_contributor(cls, invitation_key): user = User.objects.create_user ( @@ -182,6 +189,19 @@ class Utils(object): emailmessage.attach_alternative(html_version, 'text/html') emailmessage.send(fail_silently=False) + @classmethod + def create_draft_invitation(cls): + invitation = DraftInvitation ( + title = cls.form.cleaned_data['title'], + first_name = cls.form.cleaned_data['first_name'], + last_name = cls.form.cleaned_data['last_name'], + email = cls.form.cleaned_data['email'], + invitation_type = cls.form.cleaned_data['invitation_type'], + cited_in_submission = cls.form.cleaned_data['cited_in_submission'], + cited_in_publication = cls.form.cleaned_data['cited_in_publication'], + drafted_by = cls.contributor, + ) + invitation.save() @classmethod def create_invitation(cls): diff --git a/scipost/views.py b/scipost/views.py index 0a3cf578b4e3c50046712754e5f8d3a4cfe8e409..238cc4feaea54542bd293fbbc2aa2cbd70e4a12a 100644 --- a/scipost/views.py +++ b/scipost/views.py @@ -476,8 +476,108 @@ def vet_registration_request_ack(request, contributor_id): return render(request, 'scipost/acknowledgement.html', context) +@permission_required('scipost.can_draft_registration_invitations', return_403=True) +def draft_registration_invitation(request): + """ + For officers to prefill registration invitations. + This is similar to the registration_invitations method, + which is used to complete the invitation process. + """ + errormessage = '' + if request.method == 'POST': + draft_inv_form = DraftInvitationForm(request.POST) + Utils.load({'contributor': request.user.contributor, 'form': draft_inv_form}) + if draft_inv_form.is_valid(): + if Utils.email_already_invited(): + errormessage = ('DUPLICATE ERROR: ' + 'This email address has already been used for an invitation') + elif Utils.email_already_drafted(): + errormessage = ('DUPLICATE ERROR: ' + 'This email address has already been used for a draft invitation') + elif Utils.email_already_taken(): + errormessage = ('DUPLICATE ERROR: ' + 'This email address is already associated to a Contributor') + elif (draft_inv_form.cleaned_data['invitation_type'] == 'F' + and not request.user.has_perm('scipost.can_invite_Fellows')): + errormessage = ('You do not have the authorization to send a Fellow-type ' + 'invitation. Consider Contributor, or cited (sub/pub). ') + elif (draft_inv_form.cleaned_data['invitation_type'] == 'R'): + errormessage = ('Referee-type invitations must be made by the Editor-in-charge ' + 'at the relevant Submission\'s Editorial Page. ') + else: + Utils.create_draft_invitation() + context = {'ack_header': 'Draft invitation saved.', + 'followup_message': 'Return to the ', + 'followup_link': reverse('scipost:draft_registration_invitation'), + 'followup_link_label': 'drafting page'} + return render(request, 'scipost/acknowledgement.html', context) + else: + errormessage = 'The form was not filled validly.' + + else: + draft_inv_form = DraftInvitationForm() + + sent_reg_inv = RegistrationInvitation.objects.filter(responded=False, declined=False) + sent_reg_inv_fellows = sent_reg_inv.filter(invitation_type='F').order_by('last_name') + nr_sent_reg_inv_fellows = sent_reg_inv_fellows.count() + sent_reg_inv_contrib = sent_reg_inv.filter(invitation_type='C').order_by('last_name') + nr_sent_reg_inv_contrib = sent_reg_inv_contrib.count() + sent_reg_inv_ref = sent_reg_inv.filter(invitation_type='R').order_by('last_name') + nr_sent_reg_inv_ref = sent_reg_inv_ref.count() + sent_reg_inv_cited_sub = sent_reg_inv.filter(invitation_type='ci').order_by('last_name') + nr_sent_reg_inv_cited_sub = sent_reg_inv_cited_sub.count() + sent_reg_inv_cited_pub = sent_reg_inv.filter(invitation_type='cp').order_by('last_name') + nr_sent_reg_inv_cited_pub = sent_reg_inv_cited_pub.count() + + resp_reg_inv = RegistrationInvitation.objects.filter(responded=True, declined=False) + resp_reg_inv_fellows = resp_reg_inv.filter(invitation_type='F').order_by('last_name') + nr_resp_reg_inv_fellows = resp_reg_inv_fellows.count() + resp_reg_inv_contrib = resp_reg_inv.filter(invitation_type='C').order_by('last_name') + nr_resp_reg_inv_contrib = resp_reg_inv_contrib.count() + resp_reg_inv_ref = resp_reg_inv.filter(invitation_type='R').order_by('last_name') + nr_resp_reg_inv_ref = resp_reg_inv_ref.count() + resp_reg_inv_cited_sub = resp_reg_inv.filter(invitation_type='ci').order_by('last_name') + nr_resp_reg_inv_cited_sub = resp_reg_inv_cited_sub.count() + resp_reg_inv_cited_pub = resp_reg_inv.filter(invitation_type='cp').order_by('last_name') + nr_resp_reg_inv_cited_pub = resp_reg_inv_cited_pub.count() + + decl_reg_inv = RegistrationInvitation.objects.filter(responded=True, declined=True) + + names_reg_contributors = Contributor.objects.filter( + status=1).order_by('user__last_name').values_list( + 'user__first_name', 'user__last_name') + existing_drafts = DraftInvitation.objects.filter(processed=False).order_by('last_name') + + context = {'draft_inv_form': draft_inv_form, 'errormessage': errormessage, + 'sent_reg_inv_fellows': sent_reg_inv_fellows, + 'nr_sent_reg_inv_fellows': nr_sent_reg_inv_fellows, + 'sent_reg_inv_contrib': sent_reg_inv_contrib, + 'nr_sent_reg_inv_contrib': nr_sent_reg_inv_contrib, + 'sent_reg_inv_ref': sent_reg_inv_ref, + 'nr_sent_reg_inv_ref': nr_sent_reg_inv_ref, + 'sent_reg_inv_cited_sub': sent_reg_inv_cited_sub, + 'nr_sent_reg_inv_cited_sub': nr_sent_reg_inv_cited_sub, + 'sent_reg_inv_cited_pub': sent_reg_inv_cited_pub, + 'nr_sent_reg_inv_cited_pub': nr_sent_reg_inv_cited_pub, + 'resp_reg_inv_fellows': resp_reg_inv_fellows, + 'nr_resp_reg_inv_fellows': nr_resp_reg_inv_fellows, + 'resp_reg_inv_contrib': resp_reg_inv_contrib, + 'nr_resp_reg_inv_contrib': nr_resp_reg_inv_contrib, + 'resp_reg_inv_ref': resp_reg_inv_ref, + 'nr_resp_reg_inv_ref': nr_resp_reg_inv_ref, + 'resp_reg_inv_cited_sub': resp_reg_inv_cited_sub, + 'nr_resp_reg_inv_cited_sub': nr_resp_reg_inv_cited_sub, + 'resp_reg_inv_cited_pub': resp_reg_inv_cited_pub, + 'nr_resp_reg_inv_cited_pub': nr_resp_reg_inv_cited_pub, + 'decl_reg_inv': decl_reg_inv, + 'names_reg_contributors': names_reg_contributors, + 'existing_drafts': existing_drafts, + } + return render(request, 'scipost/draft_registration_invitation.html', context) + + @permission_required('scipost.can_manage_registration_invitations', return_403=True) -def registration_invitations(request): +def registration_invitations(request, draft_id=None): """ Overview and tools for administrators """ # List invitations sent; send new ones errormessage = '' @@ -502,12 +602,35 @@ def registration_invitations(request): else: Utils.create_invitation() Utils.send_registration_invitation_email() + try: + draft = DraftInvitation.objects.get( + email=reg_inv_form.cleaned_data['email']) + draft.processed = True + draft.save() + except ObjectDoesNotExist: + pass + except MultipleObjectsReturned: + # Delete the first invitation + draft_to_delete = RegistrationInvitation.objects.filter( + email=reg_inv_form.cleaned_data['email']).first() + draft_to_delete.delete() return HttpResponseRedirect('registration_invitation_sent') else: errormessage = 'The form was not filled validly.' else: - reg_inv_form = RegistrationInvitationForm() + initial = {} + if draft_id: + draft = get_object_or_404(DraftInvitation, id=draft_id) + initial = {'title': draft.title, + 'first_name': draft.first_name, + 'last_name': draft.last_name, + 'email': draft.email, + 'invitation_type': draft.invitation_type, + 'cited_in_submission': draft.cited_in_submission, + 'cited_in_publication': draft.cited_in_publication, + } + reg_inv_form = RegistrationInvitationForm(initial=initial) sent_reg_inv = RegistrationInvitation.objects.filter(responded=False, declined=False) sent_reg_inv_fellows = sent_reg_inv.filter(invitation_type='F').order_by('last_name') @@ -538,6 +661,7 @@ def registration_invitations(request): names_reg_contributors = Contributor.objects.filter( status=1).order_by('user__last_name').values_list( 'user__first_name', 'user__last_name') + existing_drafts = DraftInvitation.objects.filter(processed=False).order_by('last_name') context = {'reg_inv_form': reg_inv_form, 'errormessage': errormessage, 'sent_reg_inv_fellows': sent_reg_inv_fellows, @@ -562,6 +686,7 @@ def registration_invitations(request): 'nr_resp_reg_inv_cited_pub': nr_resp_reg_inv_cited_pub, 'decl_reg_inv': decl_reg_inv, 'names_reg_contributors': names_reg_contributors, + 'existing_drafts': existing_drafts, } return render(request, 'scipost/registration_invitations.html', context)