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.
This commit is contained in:
parent
149b7c8a54
commit
87ecc83314
3 changed files with 36 additions and 12 deletions
|
@ -34,7 +34,11 @@
|
||||||
<p class="badge-success">Not withdrawn</p>
|
<p class="badge-success">Not withdrawn</p>
|
||||||
{% endif %}</td>
|
{% endif %}</td>
|
||||||
<td>{{ proposal.get_target_audience_display }}</td>
|
<td>{{ proposal.get_target_audience_display }}</td>
|
||||||
|
{% if proposal.talk_format %}
|
||||||
<td>{{ proposal.get_talk_format_display }}</td>
|
<td>{{ proposal.get_talk_format_display }}</td>
|
||||||
|
{% else %}
|
||||||
|
<td>{{ proposal.kind.name|capfirst }}</td>
|
||||||
|
{% endif %}
|
||||||
<td>{{ proposal.total_votes }}</td>
|
<td>{{ proposal.total_votes }}</td>
|
||||||
<td>{{ proposal.score }}</td>
|
<td>{{ proposal.score }}</td>
|
||||||
<td>{{ proposal.plus_two }}</td>
|
<td>{{ proposal.plus_two }}</td>
|
||||||
|
|
7
vendor/symposion/reviews/urls.py
vendored
7
vendor/symposion/reviews/urls.py
vendored
|
@ -14,7 +14,7 @@ from .views import (
|
||||||
review_delete,
|
review_delete,
|
||||||
review_assignments,
|
review_assignments,
|
||||||
review_assignment_opt_out,
|
review_assignment_opt_out,
|
||||||
review_all_proposals_csv,
|
review_proposals_csv,
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
@ -32,7 +32,7 @@ urlpatterns = [
|
||||||
url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/$", result_notification, name="result_notification"),
|
url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/$", result_notification, name="result_notification"),
|
||||||
url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/prepare/$", result_notification_prepare, name="result_notification_prepare"),
|
url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/prepare/$", result_notification_prepare, name="result_notification_prepare"),
|
||||||
url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/send/$", result_notification_send, name="result_notification_send"),
|
url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/send/$", result_notification_send, name="result_notification_send"),
|
||||||
|
url(r"^section/(?P<section_slug>[\w\-]+)/csv$", review_proposals_csv, name="review_proposals_csv"),
|
||||||
|
|
||||||
url(r"^review/(?P<pk>\d+)/$", review_detail, name="review_detail"),
|
url(r"^review/(?P<pk>\d+)/$", review_detail, name="review_detail"),
|
||||||
|
|
||||||
|
@ -40,6 +40,5 @@ urlpatterns = [
|
||||||
url(r"^assignments/$", review_assignments, name="review_assignments"),
|
url(r"^assignments/$", review_assignments, name="review_assignments"),
|
||||||
url(r"^assignment/(?P<pk>\d+)/opt-out/$", review_assignment_opt_out, name="review_assignment_opt_out"),
|
url(r"^assignment/(?P<pk>\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"),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
37
vendor/symposion/reviews/views.py
vendored
37
vendor/symposion/reviews/views.py
vendored
|
@ -143,34 +143,47 @@ def review_section(request, section_slug, assigned=False, reviewed="all"):
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@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
|
''' Returns a CSV representation of all of the proposals this user has
|
||||||
permisison to review. '''
|
permisison to review. '''
|
||||||
|
|
||||||
response = HttpResponse("text/csv")
|
filename = "proposals.csv"
|
||||||
response['Content-Disposition'] = 'attachment; 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)
|
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
|
# The fields from each proposal object to report in the csv
|
||||||
fields = [
|
fields = [
|
||||||
"id", "proposal_type", "speaker_name", "speaker_email", "title",
|
"id", "proposal_type", "speaker_name", "speaker_email", "title",
|
||||||
"submitted", "other_speakers", "speaker_travel",
|
"audience", "submitted", "other_speakers", "speaker_travel",
|
||||||
"speaker_accommodation", "cancelled", "status", "score", "total_votes",
|
"speaker_accommodation", "cancelled", "status", "suggested_status",
|
||||||
"minus_two", "minus_one", "plus_one", "plus_two",
|
"score", "total_votes", "minus_two", "minus_one", "plus_one", "plus_two",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Fields are the heading
|
# Fields are the heading
|
||||||
writer.writerow(fields)
|
writer.writerow(fields)
|
||||||
|
|
||||||
for proposal in proposals_generator(request, queryset, check_speaker=False):
|
for proposal in proposals:
|
||||||
|
|
||||||
proposal.speaker_name = proposal.speaker.name
|
proposal.speaker_name = proposal.speaker.name
|
||||||
section_slug = proposal.kind.section.slug
|
section_slug = proposal.kind.section.slug
|
||||||
kind_slug = proposal.kind.slug
|
kind_slug = proposal.kind.slug
|
||||||
proposal.proposal_type = 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(
|
proposal.other_speakers = ", ".join(
|
||||||
speaker.name
|
speaker.name
|
||||||
for speaker in proposal.additional_speakers.all()
|
for speaker in proposal.additional_speakers.all()
|
||||||
|
@ -186,6 +199,14 @@ def review_all_proposals_csv(request):
|
||||||
for speaker in proposal.speakers()
|
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):
|
if not request.user.has_perm("reviews.can_review_%s" % section_slug):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue