@login_required
@user_passes_test(is_apply_staff_or_reviewer_required)
def submissions_all(
request: HttpRequest, template_name="submissions/all.html"
) -> HttpResponse:
search_query = request.GET.get("query") or ""
parsed_query = parse_search_query(search_query)
search_term, search_filters = parsed_query["text"], parsed_query["filters"]
show_archived = request.GET.get("archived", False) == "on"
show_drafts = request.GET.get("drafts", False) == "on"
selected_funds = request.GET.getlist("fund")
selected_rounds = request.GET.getlist("round")
selected_leads = request.GET.getlist("lead")
selected_applicants = request.GET.getlist("applicants")
selected_statuses = request.GET.getlist("status")
selected_screening_statuses = request.GET.getlist("screening_statuses")
selected_reviewers = request.GET.getlist("reviewers")
selected_meta_terms = request.GET.getlist("meta_terms")
selected_category_options = request.GET.getlist("category_options")
selected_sort = request.GET.get("sort")
page = request.GET.get("page", 1)
can_view_archives = permissions.can_view_archived_submissions(request.user)
can_access_drafts = permissions.can_access_drafts(request.user)
selected_fund_objects = (
Page.objects.filter(id__in=selected_funds) if selected_funds else []
)
selected_round_objects = (
Round.objects.filter(id__in=selected_rounds) if selected_rounds else []
)
if request.htmx and not request.htmx.boosted:
base_template = "includes/_partial-main.html"
else:
base_template = "funds/base_submissions_table.html"
start = time.time()
if can_view_archives and show_archived:
qs = ApplicationSubmission.objects.include_archive().for_table(request.user)
else:
qs = ApplicationSubmission.objects.current().for_table(request.user)
# Reviewers also have access to this view but should only see a subset of submissions.
if request.user.is_reviewer:
reviewer_settings = ReviewerSettings.for_request(request)
if reviewer_settings.use_settings:
qs = qs.for_reviewer_settings(request.user, reviewer_settings)
else:
qs = qs.filter(reviewers=request.user)
if not can_access_drafts or not show_drafts:
qs = qs.exclude_draft()
if "submitted" in search_filters:
qs = apply_date_filter(
qs=qs, field="submit_time", values=search_filters["submitted"]
)
if "updated" in search_filters:
qs = apply_date_filter(
qs=qs, field="last_update", values=search_filters["updated"]
)
if "flagged" in search_filters:
if "@me" in search_filters["flagged"]:
qs = qs.flagged_by(request.user)
if "@staff" in search_filters["flagged"]:
qs = qs.flagged_staff()
if "lead" in search_filters:
if "@me" in search_filters["lead"]:
qs = qs.filter(lead=request.user).active().current()
if "reviewer" in search_filters:
if "@me" in search_filters["reviewer"]:
qs = qs.in_review_for(request.user)
if "reviewed-by" in search_filters:
if "@me" in search_filters["reviewed-by"]:
qs = qs.reviewed_by(request.user)
if "id" in search_filters:
qs = qs.filter(id__in=search_filters["id"])
if "is" in search_filters:
if "archived" in search_filters["is"]:
qs = qs.filter(is_archive=True)
if "open" in search_filters["is"]:
qs = qs.active().current()
if search_term:
query = SearchQuery(search_term, search_type="websearch")
rank_annotation = SearchRank(models.F("search_document"), query)
qs = qs.filter(search_document=query)
qs = qs.annotate(rank=rank_annotation)
filter_extras = {
"exclude": settings.SUBMISSIONS_TABLE_EXCLUDED_FIELDS,
}
if selected_funds:
qs = qs.filter(page__in=selected_funds)
if selected_applicants:
qs = qs.filter(user__in=selected_applicants)
status_count_raw = {}
# year_counts_raw = {}
# month_counts_raw = {}
# Status Filter Options
STATUS_MAP = dict(PHASES)
for row in qs.order_by().values("status").annotate(n=models.Count("status")):
phase = STATUS_MAP[row["status"]]
display_name = phase.display_name
try:
count = status_count_raw[display_name]["count"]
except KeyError:
count = 0
status_count_raw[display_name] = {
"count": count + row["n"],
"title": display_name,
"bg_color": phase.bg_color,
"slug": phase.display_slug,
"selected": phase.display_slug in selected_statuses,
}
status_counts = sorted(
status_count_raw.values(),
key=lambda t: (t["selected"], t["count"]),
reverse=True,
)
filter_kwargs = {**request.GET, **filter_extras}
filters = SubmissionFilter(filter_kwargs, queryset=qs)
is_filtered = any(
[
selected_fund_objects,
selected_statuses,
selected_round_objects,
selected_leads,
selected_applicants,
selected_reviewers,
selected_meta_terms,
selected_category_options,
selected_screening_statuses,
selected_sort,
search_query,
request.GET.get("archived"),
request.GET.get("drafts"),
]
)
qs = filters.qs
qs = qs.prefetch_related("meta_terms")
sort_options_raw = {
"submitted-desc": ("-submit_time", _("Newest")),
"submitted-asc": ("submit_time", _("Oldest")),
"comments-desc": ("-comment_count", _("Most Commented")),
"comments-asc": ("comment_count", _("Least Commented")),
"updated-desc": ("-last_update", _("Recently Updated")),
"updated-asc": ("last_update", _("Least Recently Updated")),
"relevance-desc": ("-rank", _("Best Match")),
}
sort_options = [
{"name": v[1], "param": k, "selected": selected_sort == k}
for k, v in sort_options_raw.items()
]
if selected_sort and selected_sort in sort_options_raw.keys():
if not search_query and selected_sort == "relevance-desc":
qs = qs.order_by("-submit_time")
else:
qs = qs.order_by(sort_options_raw[selected_sort][0])
elif selected_sort in ["title-asc", "title-desc"]:
qs = qs.order_by(f"{'-' if selected_sort == 'title-desc' else ''}title")
elif search_term:
qs = qs.order_by("-rank")
else:
qs = qs.order_by("-submit_time")
end = time.time()
page = Paginator(qs, per_page=60, orphans=20).page(page)
# Pair the category ID with it's respective label
selected_category_options = Option.objects.filter(
pk__in=selected_category_options
).values("id", "value")
if request.GET.get("format") == "csv" and permissions.can_export_submissions(
request.user
):
csv_data = export_submissions_to_csv(page.object_list)
response = HttpResponse(csv_data.readlines(), content_type="text/csv")
response["Content-Disposition"] = "attachment; filename=submissions.csv"
return response
ctx = {
"base_template": base_template,
"search_query": search_query,
"filters": filters,
"page": page,
"submissions": page.object_list,
"submission_ids": [x.id for x in page.object_list],
"show_archived": show_archived,
"show_drafts": show_drafts,
"selected_funds": selected_funds,
"selected_fund_objects": selected_fund_objects,
"selected_rounds": selected_rounds,
"selected_round_objects": selected_round_objects,
"selected_leads": selected_leads,
"selected_applicants": selected_applicants,
"selected_reviewers": selected_reviewers,
"selected_meta_terms": selected_meta_terms,
"selected_category_options": selected_category_options,
"status_counts": status_counts,
"sort_options": sort_options,
"selected_sort": selected_sort,
"selected_statuses": selected_statuses,
"is_filtered": is_filtered,
"duration": end - start,
"can_view_archive": can_view_archives,
"can_access_drafts": can_access_drafts,
"can_bulk_archive": permissions.can_bulk_archive_submissions(request.user),
"can_bulk_delete": permissions.can_bulk_delete_submissions(request.user),
"can_export_submissions": permissions.can_export_submissions(request.user),
"enable_selection": permissions.can_bulk_update_submissions(request.user),
} | screening_decision_context(selected_screening_statuses)
return render(request, template_name, ctx)