From ba8b4d3a38e92c55b7907b1b96cb5d1fcc949919 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Mon, 22 Jan 2018 21:43:53 +0000 Subject: [PATCH] Allow those people who can make a review request to edit the request deadline. Send mail to other directorate secretaries when one secretary makes a change to a request. Fixes #2233. Commit ready for merge. - Legacy-Id: 14549 --- ietf/doc/tests_review.py | 21 +++++++++ ietf/doc/urls_review.py | 1 + ietf/doc/views_review.py | 44 +++++++++++++++++++ ietf/review/utils.py | 22 ++++------ .../doc/review/edit_request_deadline.html | 30 +++++++++++++ ietf/templates/doc/review/request_info.html | 6 ++- ietf/templates/review/deadline_changed.txt | 5 +++ 7 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 ietf/templates/doc/review/edit_request_deadline.html create mode 100644 ietf/templates/review/deadline_changed.txt diff --git a/ietf/doc/tests_review.py b/ietf/doc/tests_review.py index 31c371cda..eaa04a99a 100644 --- a/ietf/doc/tests_review.py +++ b/ietf/doc/tests_review.py @@ -800,3 +800,24 @@ class ReviewTests(TestCase): self.assertEqual(r.status_code, 302) review_req = reload_db_objects(review_req) self.assertEqual(review_req.comment,'iHsnReEHXEmNPXcixsvAF9Aa') + + def test_edit_deadline(self): + doc = make_test_data() + review_req = make_review_data(doc) + + url = urlreverse('ietf.doc.views_review.edit_deadline', kwargs={ "name": doc.name, "request_id": review_req.pk }) + + login_testing_unauthorized(self, "ad", url) + + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + + old_deadline = review_req.deadline.date() + new_deadline = old_deadline + datetime.timedelta(days=1) + r = self.client.post(url, data={ + "deadline": new_deadline.isoformat(), + }) + self.assertEqual(r.status_code, 302) + review_req = reload_db_objects(review_req) + self.assertEqual(review_req.deadline,new_deadline) + self.assertTrue('Deadline changed' in outbox[-1]['Subject']) diff --git a/ietf/doc/urls_review.py b/ietf/doc/urls_review.py index 3feb8c419..20d8d8923 100644 --- a/ietf/doc/urls_review.py +++ b/ietf/doc/urls_review.py @@ -10,4 +10,5 @@ urlpatterns = [ url(r'^(?P[0-9]+)/complete/$', views_review.complete_review), url(r'^(?P[0-9]+)/searchmailarchive/$', views_review.search_mail_archive), url(r'^(?P[0-9]+)/editcomment/$', views_review.edit_comment), + url(r'^(?P[0-9]+)/editdeadline/$', views_review.edit_deadline), ] diff --git a/ietf/doc/views_review.py b/ietf/doc/views_review.py index 074445dd5..49c1642d8 100644 --- a/ietf/doc/views_review.py +++ b/ietf/doc/views_review.py @@ -200,6 +200,7 @@ def review_request(request, name, request_id): and (is_reviewer or can_manage_request)) can_edit_comment = can_request_review_of_doc(request.user, doc) + can_edit_deadline = can_edit_comment if request.method == "POST" and request.POST.get("action") == "accept" and can_accept_reviewer_assignment: review_req.state = ReviewRequestStateName.objects.get(slug="accepted") @@ -216,6 +217,7 @@ def review_request(request, name, request_id): 'can_accept_reviewer_assignment': can_accept_reviewer_assignment, 'can_complete_review': can_complete_review, 'can_edit_comment': can_edit_comment, + 'can_edit_deadline': can_edit_deadline, }) @@ -684,3 +686,45 @@ def edit_comment(request, name, request_id): 'review_req': review_req, 'form' : form, }) + +class EditReviewRequestDeadlineForm(forms.ModelForm): + deadline = DatepickerDateField(date_format="yyyy-mm-dd", picker_settings={ "autoclose": "1", "start-date": "+0d" }) + class Meta: + fields = ['deadline',] + model = ReviewRequest + + def clean_deadline(self): + v = self.cleaned_data.get('deadline') + if v < datetime.date.today(): + raise forms.ValidationError("Select today or a date in the future.") + return v + + +def edit_deadline(request, name, request_id): + review_req = get_object_or_404(ReviewRequest, pk=request_id) + if not can_request_review_of_doc(request.user, review_req.doc): + return HttpResponseForbidden("You do not have permission to perform this action") + + old_deadline = review_req.deadline + + if request.method == "POST": + form = EditReviewRequestDeadlineForm(request.POST, instance=review_req) + if form.is_valid(): + if form.cleaned_data['deadline'] != old_deadline: + form.save() + subject = "Deadline changed: {} {} review of {}-{}".format(review_req.team.acronym.capitalize(),review_req.type.name.lower(), review_req.doc.name, review_req.reviewed_rev) + msg = render_to_string("review/deadline_changed.txt", { + "review_req": review_req, + "old_deadline": old_deadline, + "by": request.user.person, + }) + email_review_request_change(request, review_req, subject, msg, request.user.person, notify_secretary=True, notify_reviewer=True, notify_requested_by=True) + + return redirect(review_request, name=review_req.doc.name, request_id=review_req.pk) + else: + form = EditReviewRequestDeadlineForm(instance=review_req) + + return render(request, 'doc/review/edit_request_deadline.html', { + 'review_req': review_req, + 'form' : form, + }) diff --git a/ietf/review/utils.py b/ietf/review/utils.py index d295fa65a..407a5e23d 100644 --- a/ietf/review/utils.py +++ b/ietf/review/utils.py @@ -340,22 +340,14 @@ def email_review_request_change(request, review_req, subject, msg, by, notify_se system_email = Person.objects.get(name="(System)").formatted_email() - to = [] + to = set() def extract_email_addresses(objs): - if any(o.person == by for o in objs if o): - l = [] - else: - l = [] - for o in objs: - if o: - e = o.formatted_email() - if e != system_email: - l.append(e) - - for e in l: - if e not in to: - to.append(e) + for o in objs: + if o and o.person!=by: + e = o.formatted_email() + if e != system_email: + to.add(e) if notify_secretary: extract_email_addresses(Role.objects.filter(name="secr", group=review_req.team).distinct()) @@ -367,6 +359,8 @@ def email_review_request_change(request, review_req, subject, msg, by, notify_se if not to: return + to = list(to) + url = urlreverse("ietf.doc.views_review.review_request", kwargs={ "name": review_req.doc.name, "request_id": review_req.pk }) url = request.build_absolute_uri(url) send_mail(request, to, request.user.person.formatted_email(), subject, "review/review_request_changed.txt", { diff --git a/ietf/templates/doc/review/edit_request_deadline.html b/ietf/templates/doc/review/edit_request_deadline.html new file mode 100644 index 000000000..e204b50dc --- /dev/null +++ b/ietf/templates/doc/review/edit_request_deadline.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2016, All Rights Reserved #} +{% load origin bootstrap3 static %} + +{% block pagehead %} + +{% endblock %} + +{% block title %}Edit review request deadline for {{ review_req.doc.name }}{% endblock %} + +{% block content %} + {% origin %} +

Edit review request deadline
{{ review_req.doc.name }}

+ +
+ {% csrf_token %} + + {% bootstrap_form form %} + + {% buttons %} + Cancel + + {% endbuttons %} +
+ +{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/ietf/templates/doc/review/request_info.html b/ietf/templates/doc/review/request_info.html index d3a881137..a59c607c0 100644 --- a/ietf/templates/doc/review/request_info.html +++ b/ietf/templates/doc/review/request_info.html @@ -47,7 +47,11 @@ Deadline - {{ review_req.deadline|date:"Y-m-d" }} + {{ review_req.deadline|date:"Y-m-d" }} + {% if can_edit_deadline %} + Edit + {% endif %} + diff --git a/ietf/templates/review/deadline_changed.txt b/ietf/templates/review/deadline_changed.txt new file mode 100644 index 000000000..632804d93 --- /dev/null +++ b/ietf/templates/review/deadline_changed.txt @@ -0,0 +1,5 @@ +{% load ietf_filters %}{% autoescape off %} +{{by.plain_name }} has changed the deadline for this review request to: {{ review_req.deadline|date:"Y-m-d" }} + +(The original deadline was {{old_deadline|date:"Y-m-d"}}) +{% endautoescape %}