From 87ecc83314c6d3a8e2b1ca4573c4863a1c7e6da6 Mon Sep 17 00:00:00 2001 From: Joel Addison Date: Thu, 29 Aug 2019 22:05:00 +1000 Subject: [PATCH] Improve proposal reviews Display talk format or proposal kind on review tables and in CSV. Add suggested status to CSV output, for auto-accept and auto-reject. Add endpoint to download CSV of proposals for section. --- .../symposion/reviews/_review_table.html | 4 ++ vendor/symposion/reviews/urls.py | 7 ++-- vendor/symposion/reviews/views.py | 37 +++++++++++++++---- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/pinaxcon/templates/symposion/reviews/_review_table.html b/pinaxcon/templates/symposion/reviews/_review_table.html index 27dc2bf1..577a8a6c 100644 --- a/pinaxcon/templates/symposion/reviews/_review_table.html +++ b/pinaxcon/templates/symposion/reviews/_review_table.html @@ -34,7 +34,11 @@

Not withdrawn

{% endif %} {{ proposal.get_target_audience_display }} + {% if proposal.talk_format %} {{ proposal.get_talk_format_display }} + {% else %} + {{ proposal.kind.name|capfirst }} + {% endif %} {{ proposal.total_votes }} {{ proposal.score }} {{ proposal.plus_two }} diff --git a/vendor/symposion/reviews/urls.py b/vendor/symposion/reviews/urls.py index e3437756..4f5492df 100644 --- a/vendor/symposion/reviews/urls.py +++ b/vendor/symposion/reviews/urls.py @@ -14,7 +14,7 @@ from .views import ( review_delete, review_assignments, review_assignment_opt_out, - review_all_proposals_csv, + review_proposals_csv, ) urlpatterns = [ @@ -32,7 +32,7 @@ urlpatterns = [ url(r"^section/(?P[\w\-]+)/notification/(?P\w+)/$", result_notification, name="result_notification"), url(r"^section/(?P[\w\-]+)/notification/(?P\w+)/prepare/$", result_notification_prepare, name="result_notification_prepare"), url(r"^section/(?P[\w\-]+)/notification/(?P\w+)/send/$", result_notification_send, name="result_notification_send"), - + url(r"^section/(?P[\w\-]+)/csv$", review_proposals_csv, name="review_proposals_csv"), url(r"^review/(?P\d+)/$", review_detail, name="review_detail"), @@ -40,6 +40,5 @@ urlpatterns = [ url(r"^assignments/$", review_assignments, name="review_assignments"), url(r"^assignment/(?P\d+)/opt-out/$", review_assignment_opt_out, name="review_assignment_opt_out"), - url(r"^csv$", review_all_proposals_csv, name="review_all_proposals_csv"), - + url(r"^csv$", review_proposals_csv, name="review_all_proposals_csv"), ] diff --git a/vendor/symposion/reviews/views.py b/vendor/symposion/reviews/views.py index 11b4a526..d09cb393 100644 --- a/vendor/symposion/reviews/views.py +++ b/vendor/symposion/reviews/views.py @@ -143,34 +143,47 @@ def review_section(request, section_slug, assigned=False, reviewed="all"): @login_required -def review_all_proposals_csv(request): +def review_proposals_csv(request, section_slug=None): ''' Returns a CSV representation of all of the proposals this user has permisison to review. ''' - response = HttpResponse("text/csv") - response['Content-Disposition'] = 'attachment; filename="proposals.csv"' + filename = "proposals.csv" + if section_slug: + filename = "proposals_{}.csv".format(section_slug) + response = HttpResponse(content_type="text/csv") + response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename) writer = csv.writer(response, quoting=csv.QUOTE_NONNUMERIC) - queryset = ProposalBase.objects.filter() + queryset = ProposalBase.objects.select_related("speaker__user", "result").select_subclasses() + if section_slug: + queryset = queryset.filter(kind__section__slug=section_slug) + queryset = queryset.order_by("submitted") + + proposals = proposals_generator(request, queryset, check_speaker=False) # The fields from each proposal object to report in the csv fields = [ "id", "proposal_type", "speaker_name", "speaker_email", "title", - "submitted", "other_speakers", "speaker_travel", - "speaker_accommodation", "cancelled", "status", "score", "total_votes", - "minus_two", "minus_one", "plus_one", "plus_two", + "audience", "submitted", "other_speakers", "speaker_travel", + "speaker_accommodation", "cancelled", "status", "suggested_status", + "score", "total_votes", "minus_two", "minus_one", "plus_one", "plus_two", ] # Fields are the heading writer.writerow(fields) - for proposal in proposals_generator(request, queryset, check_speaker=False): + for proposal in proposals: proposal.speaker_name = proposal.speaker.name section_slug = proposal.kind.section.slug kind_slug = proposal.kind.slug proposal.proposal_type = kind_slug + if hasattr(proposal, "target_audience"): + proposal.audience = proposal.get_target_audience_display() + else: + proposal.audience = "Unknown" + proposal.other_speakers = ", ".join( speaker.name for speaker in proposal.additional_speakers.all() @@ -186,6 +199,14 @@ def review_all_proposals_csv(request): for speaker in proposal.speakers() ) + suggested_status = proposal.status + if suggested_status == "undecided": + if proposal.score >= 1.5: + suggested_status = "auto-accept" + elif proposal.score <= -1.5: + suggested_status = "auto-reject" + proposal.suggested_status = suggested_status + if not request.user.has_perm("reviews.can_review_%s" % section_slug): continue