1010from django .template .loader import render_to_string
1111
1212from ietf .doc .models import Document , NewRevisionDocEvent , DocEvent , State , DocAlias
13- from ietf .ietfauth .utils import is_authorized_in_doc_stream , user_is_person
13+ from ietf .ietfauth .utils import is_authorized_in_doc_stream , user_is_person , has_role
1414from ietf .name .models import ReviewRequestStateName , ReviewResultName , DocTypeName
1515from ietf .review .models import ReviewRequest
16- from ietf .person .fields import PersonEmailChoiceField
16+ from ietf .person .fields import PersonEmailChoiceField , SearchablePersonField
1717from ietf .review .utils import (active_review_teams , assign_review_request_to_reviewer ,
1818 can_request_review_of_doc , can_manage_review_requests_for_team ,
19- email_about_review_request , make_new_review_request_from_existing )
19+ email_review_request_change , make_new_review_request_from_existing ,
20+ close_review_request_states , close_review_request )
2021from ietf .review import mailarch
2122from ietf .utils .fields import DatepickerDateField
2223from ietf .utils .text import skip_prefix
@@ -38,7 +39,7 @@ class RequestReviewForm(forms.ModelForm):
3839
3940 class Meta :
4041 model = ReviewRequest
41- fields = ('type' , 'team' , 'deadline' , 'requested_rev' )
42+ fields = ('requested_by' , ' type' , 'team' , 'deadline' , 'requested_rev' )
4243
4344 def __init__ (self , user , doc , * args , ** kwargs ):
4445 super (RequestReviewForm , self ).__init__ (* args , ** kwargs )
@@ -57,6 +58,12 @@ def __init__(self, user, doc, *args, **kwargs):
5758 self .fields ["deadline" ].required = False
5859 self .fields ["requested_rev" ].label = "Document revision"
5960
61+ if has_role (user , "Secretariat" ):
62+ self .fields ["requested_by" ] = SearchablePersonField ()
63+ else :
64+ self .fields ["requested_by" ].widget = forms .HiddenInput ()
65+ self .fields ["requested_by" ].initial = user .person .pk
66+
6067 def clean_deadline_date (self ):
6168 v = self .cleaned_data .get ('deadline_date' )
6269 if v < datetime .date .today ():
@@ -119,9 +126,9 @@ def review_request(request, name, request_id):
119126 is_reviewer = review_req .reviewer and user_is_person (request .user , review_req .reviewer .person )
120127 can_manage_request = can_manage_review_requests_for_team (request .user , review_req .team )
121128
122- can_withdraw_request = (review_req .state_id in ["requested" , "accepted" ]
123- and (is_authorized_in_doc_stream (request .user , doc )
124- or can_manage_request ))
129+ can_close_request = (review_req .state_id in ["requested" , "accepted" ]
130+ and (is_authorized_in_doc_stream (request .user , doc )
131+ or can_manage_request ))
125132
126133 can_assign_reviewer = (review_req .state_id in ["requested" , "accepted" ]
127134 and can_manage_request )
@@ -147,47 +154,55 @@ def review_request(request, name, request_id):
147154 return render (request , 'doc/review/review_request.html' , {
148155 'doc' : doc ,
149156 'review_req' : review_req ,
150- 'can_withdraw_request ' : can_withdraw_request ,
157+ 'can_close_request ' : can_close_request ,
151158 'can_reject_reviewer_assignment' : can_reject_reviewer_assignment ,
152159 'can_assign_reviewer' : can_assign_reviewer ,
153160 'can_accept_reviewer_assignment' : can_accept_reviewer_assignment ,
154161 'can_complete_review' : can_complete_review ,
155162 })
156163
164+
165+ class CloseReviewRequestForm (forms .Form ):
166+ close_reason = forms .ModelChoiceField (queryset = close_review_request_states (), widget = forms .RadioSelect , empty_label = None )
167+
168+ def __init__ (self , can_manage_request , * args , ** kwargs ):
169+ super (CloseReviewRequestForm , self ).__init__ (* args , ** kwargs )
170+
171+ if not can_manage_request :
172+ self .fields ["close_reason" ].queryset = self .fields ["close_reason" ].queryset .filter (slug__in = ["withdrawn" ])
173+
174+ if len (self .fields ["close_reason" ].queryset ) == 1 :
175+ self .fields ["close_reason" ].initial = self .fields ["close_reason" ].queryset .first ().pk
176+ self .fields ["close_reason" ].widget = forms .HiddenInput ()
177+
178+
157179@login_required
158- def withdraw_request (request , name , request_id ):
180+ def close_request (request , name , request_id ):
159181 doc = get_object_or_404 (Document , name = name )
160182 review_req = get_object_or_404 (ReviewRequest , pk = request_id , state__in = ["requested" , "accepted" ])
161183
162- if not is_authorized_in_doc_stream (request .user , doc ):
163- return HttpResponseForbidden ("You do not have permission to perform this action" )
164-
165- if request .method == "POST" and request .POST .get ("action" ) == "withdraw" :
166- prev_state = review_req .state
167- review_req .state = ReviewRequestStateName .objects .get (slug = "withdrawn" )
168- review_req .save ()
184+ can_request = is_authorized_in_doc_stream (request .user , doc )
185+ can_manage_request = can_manage_review_requests_for_team (request .user , review_req .team )
169186
170- DocEvent .objects .create (
171- type = "changed_review_request" ,
172- doc = doc ,
173- by = request .user .person ,
174- desc = "Withdrew request for {} review by {}" .format (review_req .type .name , review_req .team .acronym .upper ()),
175- )
187+ if not (can_request or can_manage_request ):
188+ return HttpResponseForbidden ("You do not have permission to perform this action" )
176189
177- if prev_state .slug != "requested" :
178- email_about_review_request (
179- request , review_req ,
180- "Withdrew review request for %s" % review_req .doc .name ,
181- "Review request has been withdrawn by %s." % request .user .person ,
182- by = request .user .person , notify_secretary = False , notify_reviewer = True )
190+ if request .method == "POST" :
191+ form = CloseReviewRequestForm (can_manage_request , request .POST )
192+ if form .is_valid ():
193+ close_review_request (request , review_req , form .cleaned_data ["close_reason" ])
183194
184195 return redirect (review_request , name = review_req .doc .name , request_id = review_req .pk )
196+ else :
197+ form = CloseReviewRequestForm (can_manage_request )
185198
186- return render (request , 'doc/review/withdraw_request .html' , {
199+ return render (request , 'doc/review/close_request .html' , {
187200 'doc' : doc ,
188201 'review_req' : review_req ,
202+ 'form' : form ,
189203 })
190204
205+
191206class AssignReviewerForm (forms .Form ):
192207 reviewer = PersonEmailChoiceField (widget = forms .RadioSelect , empty_label = "(None)" , required = False )
193208
@@ -266,7 +281,7 @@ def reject_reviewer_assignment(request, name, request_id):
266281 "message_to_secretary" : form .cleaned_data .get ("message_to_secretary" )
267282 })
268283
269- email_about_review_request (request , review_req , "Reviewer assignment rejected" , msg , by = request .user .person , notify_secretary = True , notify_reviewer = True )
284+ email_review_request_change (request , review_req , "Reviewer assignment rejected" , msg , by = request .user .person , notify_secretary = True , notify_reviewer = True , notify_requested_by = False )
270285
271286 return redirect (review_request , name = new_review_req .doc .name , request_id = new_review_req .pk )
272287 else :
@@ -438,7 +453,7 @@ def complete_review(request, name, request_id):
438453 "new_review_req" : new_review_req ,
439454 })
440455
441- email_about_review_request (request , review_req , subject , msg , request .user .person , notify_secretary = True , notify_reviewer = False )
456+ email_review_request_change (request , review_req , subject , msg , request .user .person , notify_secretary = True , notify_reviewer = False , notify_requested_by = False )
442457
443458 if review_submission != "link" and review_req .team .list_email :
444459 # email the review
0 commit comments