diff --git a/scipost/forms.py b/scipost/forms.py index 21585bae2b99fa5b134c440574ab40d03839979f..9b50535f2c01468d1a3d3a7362bd559886c90e52 100644 --- a/scipost/forms.py +++ b/scipost/forms.py @@ -89,6 +89,10 @@ class RegistrationInvitationForm(forms.ModelForm): Div(Field('cited_in_publication'),), ) +class ModifyPersonalMessageForm(forms.Form): + personal_message = forms.CharField(widget=forms.Textarea()) + + class UpdateUserDataForm(forms.ModelForm): class Meta: model = User diff --git a/scipost/models.py b/scipost/models.py index f5f42c3d03c9916e53c684a34c3b8f69ccf8eb53..2cb8b2d3d1e7e243619230ae9276a0c69f354074 100644 --- a/scipost/models.py +++ b/scipost/models.py @@ -395,6 +395,7 @@ class RegistrationInvitation(models.Model): nr_reminders = models.PositiveSmallIntegerField(default=0) date_last_reminded = models.DateTimeField(blank=True, null=True) responded = models.BooleanField(default=False) + declined = models.BooleanField(default=False) def __str__ (self): return (self.invitation_type + ' ' + self.first_name + ' ' + self.last_name diff --git a/scipost/static/scipost/SciPost.css b/scipost/static/scipost/SciPost.css index 8a3a6b984e65f9c20169e683b9bb53245b4b972e..2808aa0cb95b19b35c0363a99907326ce67452c5 100644 --- a/scipost/static/scipost/SciPost.css +++ b/scipost/static/scipost/SciPost.css @@ -297,6 +297,10 @@ ul.personalTabMenu li a.inactive { background-color: #f0f0f0; padding: 0px 4px; } +.tableofInviteesDeclined td { + background-color: #e09090; + padding: 0px 4px; +} body { /* font-family: Merriweather, sans-serif; */ diff --git a/scipost/templates/scipost/edit_invitation_personal_message.html b/scipost/templates/scipost/edit_invitation_personal_message.html new file mode 100644 index 0000000000000000000000000000000000000000..24d3316f0a51c35545e76fc1a88cea23663fd211 --- /dev/null +++ b/scipost/templates/scipost/edit_invitation_personal_message.html @@ -0,0 +1,23 @@ +{% extends 'scipost/base.html' %} + +{% block pagetitle %}: registration invitation: edit personal message{% endblock pagetitle %} + +{% block bodysup %} + +{% load scipost_extras %} + +<section> + <div class="flex-greybox"> + <h2>Edit invitation's personal message: for {{ invitation.first_name }} {{ invitation.last_name }}</h2> + </div> + {% if errormessage %} + <h3 style="color: red;">{{ errormessage }}</h3> + {% endif %} + <form action="{% url 'scipost:edit_invitation_personal_message' invitation_id=invitation.id %}" method="post"> + {% csrf_token %} + {{ form }} + <input type="submit" value="Submit"> + </form> +</section> + +{% endblock bodysup %} diff --git a/scipost/templates/scipost/registration_invitations.html b/scipost/templates/scipost/registration_invitations.html index 73fffd7b4995d422079e603a27c7b46dc1cc9f35..9d831eb19595bee4dfa34f13b357d8cc718d6c5e 100644 --- a/scipost/templates/scipost/registration_invitations.html +++ b/scipost/templates/scipost/registration_invitations.html @@ -69,7 +69,9 @@ <td>{{ fellow.date_sent }} </td> <td>{{ fellow.invitation_type }}</td> <td>{{ fellow.invited_by.user.last_name }}</td> + <td><a href="{% url 'scipost:edit_invitation_personal_message' invitation_id=fellow.id %}">Edit message</a></td> <td><a href="{% url 'scipost:renew_registration_invitation' invitation_id=fellow.id %}">Renew</a> ({{ fellow.nr_reminders }}) {% if fellow.date_last_reminded %}(last: {{ fellow.date_last_reminded|date:"Y-m-d" }}){% endif %}</td> + <td><a href="{% url 'scipost:mark_reg_inv_as_declined' invitation_id=fellow.id %}">Declined</a></td> </tr> {% endfor %} </table> @@ -85,7 +87,9 @@ <td>{{ fellow.date_sent }} </td> <td>{{ fellow.invitation_type }}</td> <td>{{ fellow.invited_by.user.last_name }}</td> + <td><a href="{% url 'scipost:edit_invitation_personal_message' invitation_id=fellow.id %}">Edit msg</a></td> <td><a href="{% url 'scipost:renew_registration_invitation' invitation_id=fellow.id %}">Renew</a> ({{ fellow.nr_reminders }}) {% if fellow.date_last_reminded %}(last: {{ fellow.date_last_reminded|date:"Y-m-d" }}){% endif %}</td> + <td><a href="{% url 'scipost:mark_reg_inv_as_declined' invitation_id=fellow.id %}">Declined</a></td> </tr> {% endfor %} </table> @@ -220,9 +224,28 @@ </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"/> + +<hr class="hr12"/> + <section> <div class="flex-greybox"> <h2>List of already-registered contributors:</h3> diff --git a/scipost/urls.py b/scipost/urls.py index dff0c7e4545017df9f98f5643df38d8f1c0a2b85..fa9d103f00e540f47d17d5c1db3a4aa500428c68 100644 --- a/scipost/urls.py +++ b/scipost/urls.py @@ -65,10 +65,18 @@ urlpatterns = [ url(r'^registration_invitations_cleanup$', views.registration_invitations_cleanup, name="registration_invitations_cleanup"), - url(r'^remove_registration_invitation/(?P<invitation_id>[0-9]+)$', - views.remove_registration_invitation, name="remove_registration_invitation"), + url(r'^remove_registration_invitation/(?P<invitation_id>[0-9]+)$', + views.remove_registration_invitation, + name="remove_registration_invitation"), + url(r'^edit_invitation_personal_message/(?P<invitation_id>[0-9]+)$', + views.edit_invitation_personal_message, + name="edit_invitation_personal_message"), url(r'^renew_registration_invitation/(?P<invitation_id>[0-9]+)$', - views.renew_registration_invitation, name="renew_registration_invitation"), + views.renew_registration_invitation, + name="renew_registration_invitation"), + url(r'^mark_reg_inv_as_declined/(?P<invitation_id>[0-9]+)$', + views.mark_reg_inv_as_declined, + name="mark_reg_inv_as_declined"), url(r'^registration_invitation_sent$', TemplateView.as_view(template_name='scipost/registration_invitation_sent.html'), name='registration_invitation_sent'), diff --git a/scipost/utils.py b/scipost/utils.py index 2f093f7ea8b6dbb809036d8ca10d13a00258fa8a..a348749f75a95f05297567d19095e06e056c05ed 100644 --- a/scipost/utils.py +++ b/scipost/utils.py @@ -246,7 +246,7 @@ class Utils(object): email_text_html += ',<br/>' if len(cls.invitation.personal_message) > 3: email_text += cls.invitation.personal_message + '\n\n' - email_text_html += '<i>{{ personal_message|linebreaks }}</i><br/>\n' + email_text_html += '\n<i>{{ personal_message|linebreaks }}</i><br/>\n' email_context['personal_message'] = cls.invitation.personal_message # This text to be put in C, ci invitations diff --git a/scipost/views.py b/scipost/views.py index f0291a6eebf36f457cf65d7186621b999c3d680f..5a40d9485e42ff6cc6fb939653e4f24eef1e7d3b 100644 --- a/scipost/views.py +++ b/scipost/views.py @@ -480,7 +480,7 @@ def registration_invitations(request): else: reg_inv_form = RegistrationInvitationForm() - sent_reg_inv = RegistrationInvitation.objects.filter(responded=False) + 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') @@ -492,7 +492,7 @@ def registration_invitations(request): 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) + 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') @@ -504,6 +504,8 @@ def registration_invitations(request): 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).values_list( 'user__first_name', 'user__last_name') @@ -528,6 +530,7 @@ def registration_invitations(request): '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, } return render(request, 'scipost/registration_invitations.html', context) @@ -556,6 +559,26 @@ def remove_registration_invitation(request, invitation_id): return redirect(reverse('scipost:registration_invitations_cleanup')) +@permission_required('scipost.can_manage_registration_invitations', return_403=True) +def edit_invitation_personal_message(request, invitation_id): + invitation = get_object_or_404(RegistrationInvitation, pk=invitation_id) + errormessage = None + if request.method == 'POST': + form = ModifyPersonalMessageForm(request.POST) + if form.is_valid(): + invitation.personal_message = form.cleaned_data['personal_message'] + invitation.save() + return redirect(reverse('scipost:registration_invitations')) + else: + errormessage = 'The form was invalid.' + else: + form = ModifyPersonalMessageForm( + initial={'personal_message': invitation.personal_message,}) + context = {'invitation': invitation, + 'form': form, 'errormessage': errormessage,} + return render(request, 'scipost/edit_invitation_personal_message.html', context) + + @permission_required('scipost.can_manage_registration_invitations', return_403=True) def renew_registration_invitation(request, invitation_id): """ @@ -578,6 +601,18 @@ def renew_registration_invitation(request, invitation_id): return redirect(reverse('scipost:registration_invitations')) +@permission_required('scipost.can_manage_registration_invitations', return_403=True) +def mark_reg_inv_as_declined(request, invitation_id): + """ + Mark an invitation as declined (called from registration_invitations.html). + """ + invitation = get_object_or_404(RegistrationInvitation, pk=invitation_id) + invitation.responded = True + invitation.declined = True + invitation.save() + return redirect(reverse('scipost:registration_invitations')) + + def login_view(request): redirect_to = request.POST.get('next', request.GET.get('next', reverse('scipost:personal_page')))