From baf1f75d1cfd18a8f3f453241956598ac7b2ad48 Mon Sep 17 00:00:00 2001 From: Etty Date: Fri, 29 Dec 2023 23:34:24 +0100 Subject: [PATCH] Update template --- backend/grants/admin.py | 64 ++++--- .../templates/admin/grants/grant_summary.html | 172 +++++++++++------- 2 files changed, 153 insertions(+), 83 deletions(-) diff --git a/backend/grants/admin.py b/backend/grants/admin.py index e37bf64216..d47e3adfd0 100644 --- a/backend/grants/admin.py +++ b/backend/grants/admin.py @@ -5,7 +5,7 @@ from django.urls import path from django.template.response import TemplateResponse from django.db.models import Count - +from helpers.constants import GENDERS from django import forms from django.contrib import admin, messages from django.db.models.query import QuerySet @@ -566,8 +566,7 @@ def get_urls(self): def summary_view(self, request): """ Custom view for summarizing Grant data in the Django admin. - This view aggregates - grant data by country and status, applying filters from the request. + Aggregates data by country and status, and applies request filters. """ # Initialize statuses statuses = Grant.Status.choices @@ -582,32 +581,43 @@ def summary_view(self, request): ) # Process and aggregate data for display - summary, totals_by_status = self._process_grant_data(grants_data, statuses) + ( + summary, + totals_by_status, + totals_per_continent, + ) = self._aggregate_data_by_country(grants_data, statuses) + gender_summary = self._aggregate_data_by_gender(filtered_grants, statuses) human_readable_filters = self._format_filters_for_display(filter_params) + # Sort the summary data + sorted_summary = dict(sorted(summary.items(), key=lambda x: (x[0][0], x[0][2]))) context = { - "template_data": self._prepare_template_data(summary, statuses), + "summary": sorted_summary, "statuses": statuses, + "genders": {code: name for code, name in GENDERS}, "total": filtered_grants.count(), "totals_by_status": totals_by_status, + "totals_per_continent": totals_per_continent, + "gender_summary": gender_summary, "filters": human_readable_filters, **self.admin_site.each_context(request), } return TemplateResponse(request, "admin/grants/grant_summary.html", context) - def _process_grant_data(self, grants_data, statuses): + def _aggregate_data_by_country(self, grants_data, statuses): """ - Processes grant data for aggregation. + Aggregates grant data by country and status. """ summary = {} totals_by_status = {status[0]: 0 for status in statuses} + totals_per_continent = {} + for data in grants_data: country = countries.get(code=data["travelling_from"]) continent = country.continent.name if country else "Unknown" country_name = f"{country.name} {country.emoji}" if country else "Unknown" country_code = country.code if country else "Unknown" - key = (continent, country_name, country_code) # Initialize country summary @@ -617,24 +627,34 @@ def _process_grant_data(self, grants_data, statuses): summary[key][data["status"]] += data["total"] totals_by_status[data["status"]] += data["total"] - return summary, totals_by_status + # Update continent totals + if continent not in totals_per_continent: + totals_per_continent[continent] = {status[0]: 0 for status in statuses} + totals_per_continent[continent][data["status"]] += data["total"] + + return summary, totals_by_status, totals_per_continent - def _prepare_template_data(self, summary, statuses): + def _aggregate_data_by_gender(self, filtered_grants, statuses): """ - Prepares data for the summary view template. + Aggregates grant data by gender and status. """ - # Sort summary data - sorted_keys = sorted(summary.keys(), key=lambda x: (x[0], x[2])) + gender_data = filtered_grants.values("user__gender", "status").annotate( + total=Count("id") + ) + gender_summary = { + gender: {status[0]: 0 for status in statuses} for gender, _ in GENDERS + } + gender_summary[""] = { + status[0]: 0 for status in statuses + } # For unspecified genders - # Prepare data for template rendering - return [ - { - "continent": key[0], - "country": key[1], - "counts": [summary[key].get(status[0], 0) for status in statuses], - } - for key in sorted_keys - ] + for data in gender_data: + gender = data["user__gender"] if data["user__gender"] else "" + status = data["status"] + total = data["total"] + gender_summary[gender][status] += total + + return gender_summary def _format_filters_for_display(self, filter_params): """ diff --git a/backend/grants/templates/admin/grants/grant_summary.html b/backend/grants/templates/admin/grants/grant_summary.html index f0ec6bd12e..71fa9aa08f 100644 --- a/backend/grants/templates/admin/grants/grant_summary.html +++ b/backend/grants/templates/admin/grants/grant_summary.html @@ -2,50 +2,59 @@ {% load markdownify %} {% load localize countryname get_item %} {% load i18n admin_urls static admin_list %} +{% load get_item %} {% block extrastyle %} {{ block.super }} - - {% endblock %} {% block content %}
- Back to List + Back to List

Grant Summary

@@ -73,7 +82,8 @@

Toggle Status Columns

{% endfor %} - +

by Country

+
@@ -82,32 +92,72 @@

Toggle Status Columns

- {% for row in template_data %} + + {% for key, counts in summary.items %} + {% with continent=key.0 country=key.1 %} + {% ifchanged continent %} + + + {% for status in statuses %} + + {% endfor %} + + {% endifchanged %} + + + + {% for status in statuses %}{% endfor %} + + {% endwith %} + {% endfor %} + + - - - {% for count in row.counts %}{% endfor %} + + {% for count in totals_by_status.values %}{% endfor %} - {% endfor %} - - - - - {% for count in totals_by_status.values %}{% endfor %} - - -
Continent
+ Total for {{ continent }}: + + {{ totals_per_continent|get_item:continent|get_item:status.0|default:"0" }} +
{{ continent }}{{ country }}{{ counts|get_item:status.0|default:"0" }}
{{ row.continent }}{{ row.country }}{{ count }}Total Grants: {{ total }}{{ count }}
Total Grants: {{ total }}{{ count }}
- -{% endblock %} + + {% endblock %}