66from django .contrib .auth .decorators import login_required
77
88from ietf .doc .models import Document , NewRevisionDocEvent , DocEvent
9- from ietf .doc .utils import can_request_review_of_doc
10- from ietf .ietfauth .utils import is_authorized_in_doc_stream
9+ from ietf .doc .utils import can_request_review_of_doc , can_manage_review_requests_for_team
10+ from ietf .ietfauth .utils import is_authorized_in_doc_stream , user_is_person
1111from ietf .review .models import ReviewRequest , ReviewRequestStateName
1212from ietf .review .utils import active_review_teams
1313from ietf .utils .fields import DatepickerDateField
@@ -104,10 +104,21 @@ def review_request(request, name, request_id):
104104 doc = get_object_or_404 (Document , name = name )
105105 review_req = get_object_or_404 (ReviewRequest , pk = request_id )
106106
107+ is_reviewer = review_req .reviewer and user_is_person (request .user , review_req .reviewer .role .person )
108+ can_manage_req = can_manage_review_requests_for_team (request .user , review_req .team )
109+
110+ can_withdraw_request = (review_req .state_id in ["requested" , "accepted" ]
111+ and is_authorized_in_doc_stream (request .user , doc ))
112+
113+ can_reject_request_assignment = (review_req .state_id in ["requested" , "accepted" ]
114+ and review_req .reviewer_id is not None
115+ and (is_reviewer or can_manage_req ))
116+
107117 return render (request , 'doc/review/review_request.html' , {
108118 'doc' : doc ,
109119 'review_req' : review_req ,
110- 'can_withdraw_request' : review_req .state_id in ["requested" , "accepted" ] and is_authorized_in_doc_stream (request .user , doc ),
120+ 'can_withdraw_request' : can_withdraw_request ,
121+ 'can_reject_request_assignment' : can_reject_request_assignment ,
111122 })
112123
113124def withdraw_request (request , name , request_id ):
@@ -122,7 +133,7 @@ def withdraw_request(request, name, request_id):
122133 review_req .save ()
123134
124135 DocEvent .objects .create (
125- type = "withdrew_review_request " ,
136+ type = "changed_review_request " ,
126137 doc = doc ,
127138 by = request .user .person ,
128139 desc = "Withdrew request for {} review by {}" .format (review_req .type .name , review_req .team .acronym .upper ()),
@@ -138,3 +149,53 @@ def withdraw_request(request, name, request_id):
138149 'doc' : doc ,
139150 'review_req' : review_req ,
140151 })
152+
153+ class RejectRequestAssignmentForm (forms .Form ):
154+ message_to_secretary = forms .CharField (widget = forms .Textarea , required = False , help_text = "Optional explanation of rejection, will be emailed to team secretary" )
155+
156+ def reject_request_assignment (request , name , request_id ):
157+ doc = get_object_or_404 (Document , name = name )
158+ review_req = get_object_or_404 (ReviewRequest , pk = request_id , state__in = ["requested" , "accepted" ])
159+
160+ if not review_req .reviewer :
161+ return redirect (review_request , name = review_req .doc .name , request_id = review_req .pk )
162+
163+ is_reviewer = user_is_person (request .user , review_req .reviewer .role .person )
164+ can_manage_req = can_manage_review_requests_for_team (request .user , review_req .team )
165+
166+ if not (is_reviewer or can_manage_req ):
167+ return HttpResponseForbidden ("You do not have permission to perform this action" )
168+
169+ if request .method == "POST" and request .POST .get ("action" ) == "reject" :
170+ # reject the old request
171+ prev_state = review_req .state
172+ review_req .state = ReviewRequestStateName .objects .get (slug = "rejected" )
173+ review_req .save ()
174+
175+ # assignment of reviewer is currently considered minutia, so
176+ # not reported in the log
177+ if prev_state .slug == "accepted" :
178+ DocEvent .objects .create (
179+ type = "changed_review_request" ,
180+ doc = doc ,
181+ by = request .user .person ,
182+ desc = "Request for {} review by {} is unassigned" .format (review_req .type .name , review_req .team .acronym .upper ()),
183+ )
184+
185+ # make a new, open review request
186+ ReviewRequest .objects .create (
187+ time = review_req .time ,
188+ type = review_req .type ,
189+ doc = review_req .doc ,
190+ team = review_req .team ,
191+ deadline = review_req .deadline ,
192+ requested_rev = review_req .requested_rev ,
193+ state = prev_state ,
194+ )
195+
196+ return redirect (review_request , name = review_req .doc .name , request_id = review_req .pk )
197+
198+ return render (request , 'doc/review/reject_request_assignment.html' , {
199+ 'doc' : doc ,
200+ 'review_req' : review_req ,
201+ })
0 commit comments