@@ -165,10 +165,10 @@ def review_request(request, name, request_id):
165165 and review_req .reviewer
166166 and (is_reviewer or can_manage_request ))
167167
168- can_complete_review = (review_req .state_id in ["requested" , "accepted" ]
168+ can_complete_review = (review_req .state_id in ["requested" , "accepted" , "overtaken" , "no-response" , "part-completed" , "completed" ]
169169 and review_req .reviewer
170170 and (is_reviewer or can_manage_request ))
171-
171+
172172 if request .method == "POST" and request .POST .get ("action" ) == "accept" and can_accept_reviewer_assignment :
173173 review_req .state = ReviewRequestStateName .objects .get (slug = "accepted" )
174174 review_req .save ()
@@ -331,6 +331,8 @@ class CompleteReviewForm(forms.Form):
331331 review_url = forms .URLField (label = "Link to message" , required = False )
332332 review_file = forms .FileField (label = "Text file to upload" , required = False )
333333 review_content = forms .CharField (widget = forms .Textarea , required = False )
334+ completion_date = DatepickerDateField (date_format = "yyyy-mm-dd" , picker_settings = { "autoclose" : "1" }, initial = datetime .date .today , help_text = "Date of announcement of the results of this review" )
335+ completion_time = forms .TimeField (widget = forms .HiddenInput , initial = datetime .time .min )
334336 cc = forms .CharField (required = False , help_text = "Email addresses to send to in addition to the review team list" )
335337
336338 def __init__ (self , review_req , * args , ** kwargs ):
@@ -342,20 +344,33 @@ def __init__(self, review_req, *args, **kwargs):
342344
343345 known_revisions = NewRevisionDocEvent .objects .filter (doc = doc ).order_by ("time" , "id" ).values_list ("rev" , flat = True )
344346
345- self .fields ["state" ].choices = [
346- (slug , "{} - extra reviewer is to be assigned" .format (label )) if slug == "part-completed" else (slug , label )
347- for slug , label in self .fields ["state" ].choices
348- ]
347+ revising_review = review_req .state_id not in ["requested" , "accepted" ]
348+
349+ if not revising_review :
350+ self .fields ["state" ].choices = [
351+ (slug , "{} - extra reviewer is to be assigned" .format (label )) if slug == "part-completed" else (slug , label )
352+ for slug , label in self .fields ["state" ].choices
353+ ]
349354
350355 self .fields ["reviewed_rev" ].help_text = mark_safe (
351356 " " .join ("<a class=\" rev label label-default\" >{}</a>" .format (r )
352357 for r in known_revisions ))
353358
354359 self .fields ["result" ].queryset = self .fields ["result" ].queryset .filter (resultusedinreviewteam__team = review_req .team )
355- self .fields ["review_submission" ].choices = [
356- (k , label .format (mailing_list = review_req .team .list_email or "[error: team has no mailing list set]" ))
357- for k , label in self .fields ["review_submission" ].choices
358- ]
360+
361+ def format_submission_choice (label ):
362+ if revising_review :
363+ label = label .replace (" (automatically posts to {mailing_list})" , "" )
364+
365+ return label .format (mailing_list = review_req .team .list_email or "[error: team has no mailing list set]" )
366+
367+ self .fields ["review_submission" ].choices = [ (k , format_submission_choice (label )) for k , label in self .fields ["review_submission" ].choices ]
368+
369+ if revising_review :
370+ del self .fields ["cc" ]
371+ else :
372+ del self .fields ["completion_date" ]
373+ del self .fields ["completion_time" ]
359374
360375 def clean_reviewed_rev (self ):
361376 return clean_doc_revision (self .review_req .doc , self .cleaned_data .get ("reviewed_rev" ))
@@ -386,7 +401,9 @@ def require_field(f):
386401@login_required
387402def complete_review (request , name , request_id ):
388403 doc = get_object_or_404 (Document , name = name )
389- review_req = get_object_or_404 (ReviewRequest , pk = request_id , state__in = ["requested" , "accepted" ])
404+ review_req = get_object_or_404 (ReviewRequest , pk = request_id )
405+
406+ revising_review = review_req .state_id not in ["requested" , "accepted" ]
390407
391408 if not review_req .reviewer :
392409 return redirect (review_request , name = review_req .doc .name , request_id = review_req .pk )
@@ -402,30 +419,34 @@ def complete_review(request, name, request_id):
402419 if form .is_valid ():
403420 review_submission = form .cleaned_data ['review_submission' ]
404421
405- # create review doc
406- for i in range (1 , 100 ):
407- name_components = [
408- "review" ,
409- strip_prefix (review_req .doc .name , "draft-" ),
410- form .cleaned_data ["reviewed_rev" ],
411- review_req .team .acronym ,
412- review_req .type .slug ,
413- xslugify (review_req .reviewer .person .ascii_parts ()[3 ]),
414- datetime .date .today ().isoformat (),
415- ]
416- if i > 1 :
417- name_components .append (str (i ))
418-
419- name = "-" .join (c for c in name_components if c ).lower ()
420- if not Document .objects .filter (name = name ).exists ():
421- review = Document .objects .create (name = name )
422- DocAlias .objects .create (document = review , name = review .name )
423- break
424-
425- review .type = DocTypeName .objects .get (slug = "review" )
426- review .rev = "00"
422+ review = review_req .review
423+ if not review :
424+ # create review doc
425+ for i in range (1 , 100 ):
426+ name_components = [
427+ "review" ,
428+ strip_prefix (review_req .doc .name , "draft-" ),
429+ form .cleaned_data ["reviewed_rev" ],
430+ review_req .team .acronym ,
431+ review_req .type .slug ,
432+ xslugify (review_req .reviewer .person .ascii_parts ()[3 ]),
433+ datetime .date .today ().isoformat (),
434+ ]
435+ if i > 1 :
436+ name_components .append (str (i ))
437+
438+ name = "-" .join (c for c in name_components if c ).lower ()
439+ if not Document .objects .filter (name = name ).exists ():
440+ review = Document .objects .create (name = name )
441+ DocAlias .objects .create (document = review , name = review .name )
442+ break
443+
444+ review .type = DocTypeName .objects .get (slug = "review" )
445+ review .group = review_req .team
446+
447+ review .rev = "00" if not review .rev else "{:02}" .format (int (review .rev ) + 1 )
427448 review .title = "{} Review of {}-{}" .format (review_req .type .name , review_req .doc .name , form .cleaned_data ["reviewed_rev" ])
428- review .group = review_req . team
449+ review .time = datetime . datetime . now ()
429450 if review_submission == "link" :
430451 review .external_url = form .cleaned_data ['review_url' ]
431452
@@ -459,7 +480,7 @@ def complete_review(request, name, request_id):
459480 review_req .review = review
460481 review_req .save ()
461482
462- need_to_email_review = review_submission != "link" and review_req .team .list_email
483+ need_to_email_review = review_submission != "link" and review_req .team .list_email and not revising_review
463484
464485 desc = "Request for {} review by {} {}: {}. Reviewer: {}." .format (
465486 review_req .type .name ,
@@ -471,16 +492,22 @@ def complete_review(request, name, request_id):
471492 if need_to_email_review :
472493 desc += " " + "Sent review to list."
473494
474- close_event = ReviewRequestDocEvent .objects .create (
475- type = "closed_review_request" ,
476- doc = review_req .doc ,
477- by = request .user .person ,
478- desc = desc ,
479- review_request = review_req ,
480- state = review_req .state ,
481- )
495+ completion_datetime = datetime .datetime .now ()
496+ if "completion_date" in form .cleaned_data :
497+ completion_datetime = datetime .datetime .combine (form .cleaned_data ["completion_date" ], form .cleaned_data .get ("completion_time" ) or datetime .time .min )
498+
499+ close_event = ReviewRequestDocEvent .objects .filter (type = "closed_review_request" , review_request = review_req ).first ()
500+ if not close_event :
501+ close_event = ReviewRequestDocEvent (type = "closed_review_request" , review_request = review_req )
502+
503+ close_event .doc = review_req .doc
504+ close_event .by = request .user .person
505+ close_event .desc = desc
506+ close_event .state = review_req .state
507+ close_event .time = completion_datetime
508+ close_event .save ()
482509
483- if review_req .state_id == "part-completed" :
510+ if review_req .state_id == "part-completed" and not revising_review :
484511 existing_open_reqs = ReviewRequest .objects .filter (doc = review_req .doc , team = review_req .team , state__in = ("requested" , "accepted" ))
485512
486513 new_review_req_url = new_review_req = None
@@ -519,7 +546,10 @@ def complete_review(request, name, request_id):
519546
520547 return redirect ("doc_view" , name = review_req .review .name )
521548 else :
522- form = CompleteReviewForm (review_req )
549+ form = CompleteReviewForm (review_req , initial = {
550+ "reviewed_rev" : review_req .reviewed_rev ,
551+ "result" : review_req .result_id
552+ })
523553
524554 mail_archive_query_urls = mailarch .construct_query_urls (review_req )
525555
@@ -528,11 +558,12 @@ def complete_review(request, name, request_id):
528558 'review_req' : review_req ,
529559 'form' : form ,
530560 'mail_archive_query_urls' : mail_archive_query_urls ,
561+ 'revising_review' : revising_review ,
531562 })
532563
533564def search_mail_archive (request , name , request_id ):
534565 #doc = get_object_or_404(Document, name=name)
535- review_req = get_object_or_404 (ReviewRequest , pk = request_id , state__in = [ "requested" , "accepted" ] )
566+ review_req = get_object_or_404 (ReviewRequest , pk = request_id )
536567
537568 is_reviewer = user_is_person (request .user , review_req .reviewer .person )
538569 can_manage_request = can_manage_review_requests_for_team (request .user , review_req .team )
0 commit comments