Skip to content

Commit f57fb6b

Browse files
committed
Added the ability to withdraw individual assignments. Added the ability to mark individual assignments no-response.
- Legacy-Id: 16039
1 parent da3174a commit f57fb6b

4 files changed

Lines changed: 133 additions & 17 deletions

File tree

ietf/doc/tests_review.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,3 +942,34 @@ def test_edit_deadline(self):
942942
review_req = reload_db_objects(review_req)
943943
self.assertEqual(review_req.deadline,new_deadline)
944944
self.assertTrue('Deadline changed' in outbox[-1]['Subject'])
945+
946+
def test_mark_no_response(self):
947+
assignment = ReviewAssignmentFactory()
948+
secr = RoleFactory(group=assignment.review_request.team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr').person
949+
url = urlreverse('ietf.doc.views_review.mark_reviewer_assignment_no_response', kwargs={"name": assignment.review_request.doc.name, "assignment_id": assignment.pk})
950+
951+
login_testing_unauthorized(self, secr.user.username, url)
952+
r = self.client.get(url)
953+
self.assertEqual(r.status_code, 200)
954+
955+
r=self.client.post(url, data={"action":"noresponse"})
956+
self.assertEqual(r.status_code, 302)
957+
958+
assignment = reload_db_objects(assignment)
959+
self.assertEqual(assignment.state_id, 'no-response')
960+
961+
def test_withdraw_assignment(self):
962+
assignment = ReviewAssignmentFactory()
963+
secr = RoleFactory(group=assignment.review_request.team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr').person
964+
url = urlreverse('ietf.doc.views_review.withdraw_reviewer_assignment', kwargs={"name": assignment.review_request.doc.name, "assignment_id": assignment.pk})
965+
966+
login_testing_unauthorized(self, secr.user.username, url)
967+
r = self.client.get(url)
968+
self.assertEqual(r.status_code, 200)
969+
970+
r=self.client.post(url, data={"action":"withdraw"})
971+
self.assertEqual(r.status_code, 302)
972+
973+
assignment = reload_db_objects(assignment)
974+
self.assertEqual(assignment.state_id, 'withdrawn')
975+

ietf/doc/urls_review.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
url(r'^(?P<request_id>[0-9]+)/assignreviewer/$', views_review.assign_reviewer),
1010
url(r'^(?P<assignment_id>[0-9]+)/rejectreviewerassignment/$', views_review.reject_reviewer_assignment),
1111
url(r'^(?P<assignment_id>[0-9]+)/complete/$', views_review.complete_review),
12+
url(r'^(?P<assignment_id>[0-9]+)/withdraw/$', views_review.withdraw_reviewer_assignment),
13+
url(r'^(?P<assignment_id>[0-9]+)/noresponse/$', views_review.mark_reviewer_assignment_no_response),
1214
url(r'^(?P<assignment_id>[0-9]+)/searchmailarchive/$', views_review.search_mail_archive),
1315
url(r'^(?P<request_id>[0-9]+)/editcomment/$', views_review.edit_comment),
1416
url(r'^(?P<request_id>[0-9]+)/editdeadline/$', views_review.edit_deadline),

ietf/doc/views_review.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,81 @@ def reject_reviewer_assignment(request, name, assignment_id):
364364
'form': form,
365365
})
366366

367+
@login_required
368+
def withdraw_reviewer_assignment(request, name, assignment_id):
369+
get_object_or_404(Document, name=name)
370+
review_assignment = get_object_or_404(ReviewAssignment, pk=assignment_id, state__in=["assigned", "accepted"])
371+
372+
can_manage_request = can_manage_review_requests_for_team(request.user, review_assignment.review_request.team)
373+
if not can_manage_request:
374+
return HttpResponseForbidden("You do not have permission to perform this action")
375+
376+
if request.method == "POST" and request.POST.get("action") == "withdraw":
377+
review_assignment.state_id = 'withdrawn'
378+
review_assignment.save()
379+
380+
ReviewAssignmentDocEvent.objects.create(
381+
type="closed_review_request",
382+
doc=review_assignment.review_request.doc,
383+
rev=review_assignment.review_request.doc.rev,
384+
by=request.user.person,
385+
desc="Assignment of request for {} review by {} to {} was withdrawn".format(
386+
review_assignment.review_request.type.name,
387+
review_assignment.review_request.team.acronym.upper(),
388+
review_assignment.reviewer.person,
389+
),
390+
review_assignment=review_assignment,
391+
state=review_assignment.state,
392+
)
393+
394+
msg = "Review assignment withdrawn by %s"%request.user.person
395+
396+
email_review_assignment_change(request, review_assignment, "Reviewer assignment withdrawn", msg, by=request.user.person, notify_secretary=True, notify_reviewer=True, notify_requested_by=False)
397+
398+
return redirect(review_request, name=review_assignment.review_request.doc.name, request_id=review_assignment.review_request.pk)
399+
400+
return render(request, 'doc/review/withdraw_reviewer_assignment.html', {
401+
'assignment': review_assignment,
402+
})
403+
404+
@login_required
405+
def mark_reviewer_assignment_no_response(request, name, assignment_id):
406+
get_object_or_404(Document, name=name)
407+
review_assignment = get_object_or_404(ReviewAssignment, pk=assignment_id, state__in=["assigned", "accepted"])
408+
409+
can_manage_request = can_manage_review_requests_for_team(request.user, review_assignment.review_request.team)
410+
if not can_manage_request:
411+
return HttpResponseForbidden("You do not have permission to perform this action")
412+
413+
if request.method == "POST" and request.POST.get("action") == "noresponse":
414+
review_assignment.state_id = 'no-response'
415+
review_assignment.save()
416+
417+
ReviewAssignmentDocEvent.objects.create(
418+
type="closed_review_request",
419+
doc=review_assignment.review_request.doc,
420+
rev=review_assignment.review_request.doc.rev,
421+
by=request.user.person,
422+
desc="Assignment of request for {} review by {} to {} was marked no-response".format(
423+
review_assignment.review_request.type.name,
424+
review_assignment.review_request.team.acronym.upper(),
425+
review_assignment.reviewer.person,
426+
),
427+
review_assignment=review_assignment,
428+
state=review_assignment.state,
429+
)
430+
431+
msg = "Review assignment marked 'No Response' by %s"%request.user.person
432+
433+
email_review_assignment_change(request, review_assignment, "Reviewer assignment marked no-response", msg, by=request.user.person, notify_secretary=True, notify_reviewer=True, notify_requested_by=False)
434+
435+
return redirect(review_request, name=review_assignment.review_request.doc.name, request_id=review_assignment.review_request.pk)
436+
437+
return render(request, 'doc/review/mark_reviewer_assignment_no_response.html', {
438+
'assignment': review_assignment,
439+
})
440+
441+
367442
class CompleteReviewForm(forms.Form):
368443
state = forms.ModelChoiceField(queryset=ReviewAssignmentStateName.objects.filter(slug__in=("completed", "part-completed")).order_by("-order"), widget=forms.RadioSelect, initial="completed")
369444
reviewed_rev = forms.CharField(label="Reviewed revision", max_length=4)

ietf/templates/doc/review/request_info.html

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -139,23 +139,31 @@
139139
</td>
140140
</tr>
141141

142-
<tr>
143-
<th>Review</th>
144-
<td>
145-
{% if assignment.review %}
146-
<a href="{{ assignment.review.get_absolute_url }}">{{ assignment.review.name }}</a>
147-
{% elif assignment.state_id == "assigned" or assignment.state_id == "accepted" %}
148-
Not completed yet
149-
{% else %}
150-
Not available
151-
{% endif %}
152-
153-
{% if assignment.can_complete_review %}
154-
{# TODO: The url below needs to be to a new complete_assignment passed the assignment.pk #}
155-
<a class="btn btn-primary btn-xs" href="{% url "ietf.doc.views_review.complete_review" name=doc.name assignment_id=assignment.pk %}"><span class="fa fa-pencil-square-o"></span> {% if assignment.state_id == "assigned" or assignment.state_id == "accepted" %}Complete review{% else %}Correct review{% endif %}</a>
156-
{% endif %}
157-
</td>
158-
</tr>
142+
{% if assignment.state_id != "withdrawn" and assignment.state_id != "no-response" and assignment.state_id != "rejected" %}
143+
<tr>
144+
<th>Review</th>
145+
<td>
146+
{% if assignment.review %}
147+
<a href="{{ assignment.review.get_absolute_url }}">{{ assignment.review.name }}</a>
148+
{% elif assignment.state_id == "assigned" or assignment.state_id == "accepted" %}
149+
Not completed yet
150+
{% else %}
151+
Not available
152+
{% endif %}
153+
154+
{% if assignment.can_complete_review %}
155+
<a class="btn btn-primary btn-xs" href="{% url "ietf.doc.views_review.complete_review" name=doc.name assignment_id=assignment.pk %}"><span class="fa fa-pencil-square-o"></span> {% if assignment.state_id == "assigned" or assignment.state_id == "accepted" %}Complete review{% else %}Correct review{% endif %}</a>
156+
{% endif %}
157+
158+
{% if assignment.state_id == "assigned" or assignment.state_id == "accepted" %}
159+
{% if can_assign_reviewer %}
160+
<a class="btn btn-danger btn-xs" href="{% url "ietf.doc.views_review.mark_reviewer_assignment_no_response" name=doc.name assignment_id=assignment.pk %}"><span class="fa fa-ban"></span> No response</a>
161+
<a class="btn btn-danger btn-xs" href="{% url "ietf.doc.views_review.withdraw_reviewer_assignment" name=doc.name assignment_id=assignment.pk %}"><span class="fa fa-ban"></span> Withdraw</a>
162+
{% endif %}
163+
{% endif %}
164+
</td>
165+
</tr>
166+
{% endif %}
159167

160168
{% if assignment.review and assignment.review.external_url %}
161169
<tr>

0 commit comments

Comments
 (0)