Skip to content

Commit a97b322

Browse files
committed
Fix summary to handle pending status properly
1 parent 585bb96 commit a97b322

1 file changed

Lines changed: 38 additions & 30 deletions

File tree

backend/grants/summary.py

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from collections import defaultdict
22

33
from django.db.models import Count, Exists, OuterRef, Sum
4+
from django.db.models.functions import Coalesce
45

56
from conferences.models.conference import Conference
67
from countries import countries
@@ -26,10 +27,12 @@ def calculate(self, conference_id):
2627
"""
2728
statuses = Grant.Status.choices
2829
conference = Conference.objects.get(id=conference_id)
29-
filtered_grants = Grant.objects.for_conference(conference)
30+
filtered_grants = Grant.objects.for_conference(conference).annotate(
31+
effective_status=Coalesce("pending_status", "status")
32+
)
3033

3134
grants_by_country = filtered_grants.values(
32-
"departure_country", "pending_status"
35+
"departure_country", "effective_status"
3336
).annotate(total=Count("id"))
3437

3538
(
@@ -99,6 +102,7 @@ def _aggregate_data_by_country(self, grants_by_country, statuses):
99102
totals_per_continent = {}
100103

101104
for data in grants_by_country:
105+
effective_status: str = data["effective_status"]
102106
country = countries.get(code=data["departure_country"])
103107
continent = country.continent.name if country else "Unknown"
104108
country_name = f"{country.name} {country.emoji}" if country else "Unknown"
@@ -108,13 +112,13 @@ def _aggregate_data_by_country(self, grants_by_country, statuses):
108112
if key not in summary:
109113
summary[key] = {status[0]: 0 for status in statuses}
110114

111-
summary[key][data["pending_status"]] += data["total"]
112-
status_totals[data["pending_status"]] += data["total"]
115+
summary[key][effective_status] += data["total"]
116+
status_totals[effective_status] += data["total"]
113117

114118
# Update continent totals
115119
if continent not in totals_per_continent:
116120
totals_per_continent[continent] = {status[0]: 0 for status in statuses}
117-
totals_per_continent[continent][data["pending_status"]] += data["total"]
121+
totals_per_continent[continent][effective_status] += data["total"]
118122

119123
return summary, status_totals, totals_per_continent
120124

@@ -123,34 +127,34 @@ def _aggregate_data_by_country_type(self, filtered_grants, statuses):
123127
Aggregates grant data by country type and status.
124128
"""
125129
country_type_data = filtered_grants.values(
126-
"country_type", "pending_status"
130+
"country_type", "effective_status"
127131
).annotate(total=Count("id"))
128132
country_type_summary = defaultdict(
129133
lambda: {status[0]: 0 for status in statuses}
130134
)
131135

132136
for data in country_type_data:
133137
country_type = data["country_type"]
134-
pending_status = data["pending_status"]
138+
effective_status: str = data["effective_status"]
135139
total = data["total"]
136-
country_type_summary[country_type][pending_status] += total
140+
country_type_summary[country_type][effective_status] += total
137141

138142
return dict(country_type_summary)
139143

140144
def _aggregate_data_by_gender(self, filtered_grants, statuses):
141145
"""
142146
Aggregates grant data by gender and status.
143147
"""
144-
gender_data = filtered_grants.values("gender", "pending_status").annotate(
148+
gender_data = filtered_grants.values("gender", "effective_status").annotate(
145149
total=Count("id")
146150
)
147151
gender_summary = defaultdict(lambda: {status[0]: 0 for status in statuses})
148152

149153
for data in gender_data:
150154
gender = data["gender"] if data["gender"] else ""
151-
pending_status = data["pending_status"]
155+
effective_status: str = data["effective_status"]
152156
total = data["total"]
153-
gender_summary[gender][pending_status] += total
157+
gender_summary[gender][effective_status] += total
154158

155159
return dict(gender_summary)
156160

@@ -162,7 +166,7 @@ def _aggregate_financial_data_by_status(self, filtered_grants, statuses):
162166
overall_total = 0
163167

164168
for status in statuses:
165-
grants_for_status = filtered_grants.filter(pending_status=status[0])
169+
grants_for_status = filtered_grants.filter(effective_status=status[0])
166170
reimbursements = GrantReimbursement.objects.filter(
167171
grant__in=grants_for_status
168172
)
@@ -178,28 +182,30 @@ def _aggregate_data_by_reimbursement_category(self, filtered_grants, statuses):
178182
Aggregates grant data by reimbursement category and status.
179183
"""
180184
category_summary = defaultdict(lambda: {status[0]: 0 for status in statuses})
181-
reimbursements = GrantReimbursement.objects.filter(grant__in=filtered_grants)
185+
reimbursements = GrantReimbursement.objects.filter(
186+
grant__in=filtered_grants
187+
).select_related("grant", "category")
182188
for r in reimbursements:
189+
effective_status: str = r.grant.current_or_pending_status
183190
category = r.category.category
184-
status = r.grant.pending_status
185-
category_summary[category][status] += 1
191+
category_summary[category][effective_status] += 1
186192
return dict(category_summary)
187193

188194
def _aggregate_data_by_grant_type(self, filtered_grants, statuses):
189195
"""
190196
Aggregates grant data by grant_type and status.
191197
"""
192198
grant_type_data = filtered_grants.values(
193-
"grant_type", "pending_status"
199+
"grant_type", "effective_status"
194200
).annotate(total=Count("id"))
195201
grant_type_summary = defaultdict(lambda: {status[0]: 0 for status in statuses})
196202

197203
for data in grant_type_data:
198204
grant_types = data["grant_type"]
199-
pending_status = data["pending_status"]
205+
effective_status: str = data["effective_status"]
200206
total = data["total"]
201207
for grant_type in grant_types:
202-
grant_type_summary[grant_type][pending_status] += total
208+
grant_type_summary[grant_type][effective_status] += total
203209

204210
return dict(grant_type_summary)
205211

@@ -224,13 +230,13 @@ def _aggregate_data_by_speaker_status(self, filtered_grants, statuses):
224230

225231
proposed_speaker_data = (
226232
filtered_grants.filter(is_proposed_speaker=True)
227-
.values("pending_status")
233+
.values("effective_status")
228234
.annotate(total=Count("id"))
229235
)
230236

231237
confirmed_speaker_data = (
232238
filtered_grants.filter(is_confirmed_speaker=True)
233-
.values("pending_status")
239+
.values("effective_status")
234240
.annotate(total=Count("id"))
235241
)
236242

@@ -239,14 +245,16 @@ def _aggregate_data_by_speaker_status(self, filtered_grants, statuses):
239245
)
240246

241247
for data in proposed_speaker_data:
242-
pending_status = data["pending_status"]
248+
effective_status: str = data["effective_status"]
243249
total = data["total"]
244-
speaker_status_summary["proposed_speaker"][pending_status] += total
250+
speaker_status_summary["proposed_speaker"][effective_status] += total
245251

246252
for data in confirmed_speaker_data:
247-
pending_status = data["pending_status"]
253+
effective_status_confirmed: str = data["effective_status"]
248254
total = data["total"]
249-
speaker_status_summary["confirmed_speaker"][pending_status] += total
255+
speaker_status_summary["confirmed_speaker"][effective_status_confirmed] += (
256+
total
257+
)
250258

251259
return dict(speaker_status_summary)
252260

@@ -263,13 +271,13 @@ def _aggregate_data_by_requested_needs_summary(self, filtered_grants, statuses):
263271
for field in requested_needs_summary.keys():
264272
field_data = (
265273
filtered_grants.filter(**{field: True})
266-
.values("pending_status")
274+
.values("effective_status")
267275
.annotate(total=Count("id"))
268276
)
269277
for data in field_data:
270-
pending_status = data["pending_status"]
278+
effective_status: str = data["effective_status"]
271279
total = data["total"]
272-
requested_needs_summary[field][pending_status] += total
280+
requested_needs_summary[field][effective_status] += total
273281

274282
return requested_needs_summary
275283

@@ -278,14 +286,14 @@ def _aggregate_data_by_occupation(self, filtered_grants, statuses):
278286
Aggregates grant data by occupation and status.
279287
"""
280288
occupation_data = filtered_grants.values(
281-
"occupation", "pending_status"
289+
"occupation", "effective_status"
282290
).annotate(total=Count("id"))
283291
occupation_summary = defaultdict(lambda: {status[0]: 0 for status in statuses})
284292

285293
for data in occupation_data:
286294
occupation = data["occupation"]
287-
pending_status = data["pending_status"]
295+
effective_status: str = data["effective_status"]
288296
total = data["total"]
289-
occupation_summary[occupation][pending_status] += total
297+
occupation_summary[occupation][effective_status] += total
290298

291299
return dict(occupation_summary)

0 commit comments

Comments
 (0)