Skip to content

Commit 408447b

Browse files
committed
Grant/Proposal pending status
1 parent e40e524 commit 408447b

File tree

5 files changed

+102
-71
lines changed

5 files changed

+102
-71
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Generated by Django 5.1.4 on 2025-01-20 00:57
2+
3+
from django.db import migrations, models
4+
5+
def copy_grant_status_to_pending_status(apps, schema_editor):
6+
Grant = apps.get_model('grants', 'Grant')
7+
for grant in Grant.objects.all():
8+
grant.pending_status = grant.status
9+
grant.save(update_fields=['pending_status'])
10+
11+
12+
class Migration(migrations.Migration):
13+
14+
dependencies = [
15+
('grants', '0025_alter_grant_approved_type'),
16+
]
17+
18+
operations = [
19+
migrations.AddField(
20+
model_name='grant',
21+
name='pending_status',
22+
field=models.CharField(blank=True, choices=[('pending', 'Pending'), ('rejected', 'Rejected'), ('approved', 'Approved'), ('waiting_list', 'Waiting List'), ('waiting_list_maybe', 'Waiting List, Maybe'), ('waiting_for_confirmation', 'Waiting for confirmation'), ('refused', 'Refused'), ('confirmed', 'Confirmed'), ('did_not_attend', 'Did Not Attend')], default='pending', max_length=30, verbose_name='pending status'),
23+
),
24+
migrations.RunPython(copy_grant_status_to_pending_status, reverse_code=migrations.RunPython.noop),
25+
]

backend/grants/models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ class ApprovedType(models.TextChoices):
145145
status = models.CharField(
146146
_("status"), choices=Status.choices, max_length=30, default=Status.pending
147147
)
148+
pending_status = models.CharField(
149+
_("pending status"),
150+
choices=Status.choices,
151+
max_length=30,
152+
default=Status.pending,
153+
blank=True,
154+
)
148155
approved_type = models.CharField(
149156
verbose_name=_("approved type"),
150157
choices=ApprovedType.choices,

backend/grants/summary.py

Lines changed: 48 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections import defaultdict
12
from django.db.models import Count, Sum
23
from conferences.models.conference import Conference
34
from helpers.constants import GENDERS
@@ -26,7 +27,7 @@ def calculate(self, conference_id):
2627
filtered_grants = Grant.objects.for_conference(conference)
2728

2829
grants_by_country = filtered_grants.values(
29-
"departure_country", "status"
30+
"departure_country", "pending_status"
3031
).annotate(total=Count("id"))
3132

3233
(
@@ -109,71 +110,65 @@ def _aggregate_data_by_country(self, grants_by_country, statuses):
109110
if key not in summary:
110111
summary[key] = {status[0]: 0 for status in statuses}
111112

112-
summary[key][data["status"]] += data["total"]
113-
status_totals[data["status"]] += data["total"]
113+
summary[key][data["pending_status"]] += data["total"]
114+
status_totals[data["pending_status"]] += data["total"]
114115

115116
# Update continent totals
116117
if continent not in totals_per_continent:
117118
totals_per_continent[continent] = {status[0]: 0 for status in statuses}
118-
totals_per_continent[continent][data["status"]] += data["total"]
119+
totals_per_continent[continent][data["pending_status"]] += data["total"]
119120

120121
return summary, status_totals, totals_per_continent
121122

122123
def _aggregate_data_by_country_type(self, filtered_grants, statuses):
123124
"""
124125
Aggregates grant data by country type and status.
125126
"""
126-
country_type_data = filtered_grants.values("country_type", "status").annotate(
127-
total=Count("id")
127+
country_type_data = filtered_grants.values(
128+
"country_type", "pending_status"
129+
).annotate(total=Count("id"))
130+
country_type_summary = defaultdict(
131+
lambda: {status[0]: 0 for status in statuses}
128132
)
129-
country_type_summary = {
130-
country_type: {status[0]: 0 for status in statuses}
131-
for country_type in Grant.CountryType.values
132-
}
133133

134134
for data in country_type_data:
135135
country_type = data["country_type"]
136-
status = data["status"]
136+
status = data["pending_status"]
137137
total = data["total"]
138138
country_type_summary[country_type][status] += total
139139

140-
return country_type_summary
140+
return dict(country_type_summary)
141141

142142
def _aggregate_data_by_gender(self, filtered_grants, statuses):
143143
"""
144144
Aggregates grant data by gender and status.
145145
"""
146-
gender_data = filtered_grants.values("gender", "status").annotate(
146+
gender_data = filtered_grants.values("gender", "pending_status").annotate(
147147
total=Count("id")
148148
)
149-
gender_summary = {
150-
gender: {status[0]: 0 for status in statuses} for gender, _ in GENDERS
151-
}
152-
gender_summary[""] = {
153-
status[0]: 0 for status in statuses
154-
} # For unspecified genders
149+
gender_summary = defaultdict(lambda: {status[0]: 0 for status in statuses})
155150

156151
for data in gender_data:
157152
gender = data["gender"] if data["gender"] else ""
158-
status = data["status"]
153+
status = data["pending_status"]
159154
total = data["total"]
160155
gender_summary[gender][status] += total
161156

162-
return gender_summary
157+
return dict(gender_summary)
163158

164159
def _aggregate_financial_data_by_status(self, filtered_grants, statuses):
165160
"""
166161
Aggregates financial data (total amounts) by grant status.
167162
"""
168-
financial_data = filtered_grants.values("status").annotate(
163+
financial_data = filtered_grants.values("pending_status").annotate(
169164
total_amount_sum=Sum("total_amount")
170165
)
171166
print(financial_data)
172167
financial_summary = {status[0]: 0 for status in statuses}
173168
overall_total = 0
174169

175170
for data in financial_data:
176-
status = data["status"]
171+
status = data["pending_status"]
177172
total_amount = data["total_amount_sum"] or 0
178173
financial_summary[status] += total_amount
179174
if status in self.BUDGET_STATUSES:
@@ -185,22 +180,19 @@ def _aggregate_data_by_grant_type(self, filtered_grants, statuses):
185180
"""
186181
Aggregates grant data by grant_type and status.
187182
"""
188-
grant_type_data = filtered_grants.values("grant_type", "status").annotate(
189-
total=Count("id")
190-
)
191-
grant_type_summary = {
192-
grant_type: {status[0]: 0 for status in statuses}
193-
for grant_type in Grant.GrantType.values
194-
}
183+
grant_type_data = filtered_grants.values(
184+
"grant_type", "pending_status"
185+
).annotate(total=Count("id"))
186+
grant_type_summary = defaultdict(lambda: {status[0]: 0 for status in statuses})
195187

196188
for data in grant_type_data:
197189
grant_types = data["grant_type"]
198-
status = data["status"]
190+
status = data["pending_status"]
199191
total = data["total"]
200192
for grant_type in grant_types:
201193
grant_type_summary[grant_type][status] += total
202194

203-
return grant_type_summary
195+
return dict(grant_type_summary)
204196

205197
def _aggregate_data_by_speaker_status(self, filtered_grants, statuses):
206198
"""
@@ -223,55 +215,54 @@ def _aggregate_data_by_speaker_status(self, filtered_grants, statuses):
223215

224216
proposed_speaker_data = (
225217
filtered_grants.filter(is_proposed_speaker=True)
226-
.values("status")
218+
.values("pending_status")
227219
.annotate(total=Count("id"))
228220
)
229221

230222
confirmed_speaker_data = (
231223
filtered_grants.filter(is_confirmed_speaker=True)
232-
.values("status")
224+
.values("pending_status")
233225
.annotate(total=Count("id"))
234226
)
235227

236-
speaker_status_summary = {
237-
"proposed_speaker": {status[0]: 0 for status in statuses},
238-
"confirmed_speaker": {status[0]: 0 for status in statuses},
239-
}
228+
speaker_status_summary = defaultdict(
229+
lambda: {status[0]: 0 for status in statuses}
230+
)
240231

241232
for data in proposed_speaker_data:
242-
status = data["status"]
233+
status = data["pending_status"]
243234
total = data["total"]
244235
speaker_status_summary["proposed_speaker"][status] += total
245236

246237
for data in confirmed_speaker_data:
247-
status = data["status"]
238+
status = data["pending_status"]
248239
total = data["total"]
249240
speaker_status_summary["confirmed_speaker"][status] += total
250241

251-
return speaker_status_summary
242+
return dict(speaker_status_summary)
252243

253244
def _aggregate_data_by_approved_type(self, filtered_grants, statuses):
254245
"""
255246
Aggregates grant data by approved type and status.
256247
"""
257-
approved_type_data = filtered_grants.values("approved_type", "status").annotate(
258-
total=Count("id")
259-
)
248+
approved_type_data = filtered_grants.values(
249+
"approved_type", "pending_status"
250+
).annotate(total=Count("id"))
260251
approved_type_summary = {
261252
approved_type: {status[0]: 0 for status in statuses}
262253
for approved_type in Grant.ApprovedType.values
263254
}
264-
approved_type_summary[None] = {
265-
status[0]: 0 for status in statuses
266-
} # For unspecified genders
255+
approved_type_summary = defaultdict(
256+
lambda: {status[0]: 0 for status in statuses}
257+
)
267258

268259
for data in approved_type_data:
269260
approved_type = data["approved_type"]
270-
status = data["status"]
261+
status = data["pending_status"]
271262
total = data["total"]
272263
approved_type_summary[approved_type][status] += total
273264

274-
return approved_type_summary
265+
return dict(approved_type_summary)
275266

276267
def _aggregate_data_by_requested_needs_summary(self, filtered_grants, statuses):
277268
"""
@@ -286,11 +277,11 @@ def _aggregate_data_by_requested_needs_summary(self, filtered_grants, statuses):
286277
for field in requested_needs_summary.keys():
287278
field_data = (
288279
filtered_grants.filter(**{field: True})
289-
.values("status")
280+
.values("pending_status")
290281
.annotate(total=Count("id"))
291282
)
292283
for data in field_data:
293-
status = data["status"]
284+
status = data["pending_status"]
294285
total = data["total"]
295286
requested_needs_summary[field][status] += total
296287

@@ -300,18 +291,15 @@ def _aggregate_data_by_occupation(self, filtered_grants, statuses):
300291
"""
301292
Aggregates grant data by occupation and status.
302293
"""
303-
occupation_data = filtered_grants.values("occupation", "status").annotate(
304-
total=Count("id")
305-
)
306-
occupation_summary = {
307-
occupation: {status[0]: 0 for status in statuses}
308-
for occupation in Grant.Occupation.values
309-
}
294+
occupation_data = filtered_grants.values(
295+
"occupation", "pending_status"
296+
).annotate(total=Count("id"))
297+
occupation_summary = defaultdict(lambda: {status[0]: 0 for status in statuses})
310298

311299
for data in occupation_data:
312300
occupation = data["occupation"]
313-
status = data["status"]
301+
status = data["pending_status"]
314302
total = data["total"]
315303
occupation_summary[occupation][status] += total
316304

317-
return occupation_summary
305+
return dict(occupation_summary)

backend/reviews/admin.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,15 +282,15 @@ def _review_grants_recap_view(self, request, review_session):
282282

283283
approved_type = approved_type_decisions.get(grant.id, "")
284284

285-
grant.status = decision
285+
grant.pending_status = decision
286286
grant.approved_type = (
287287
approved_type if decision == Grant.Status.approved else None
288288
)
289289

290290
for grant in grants:
291291
# save each to make sure we re-calculate the grants amounts
292292
# TODO: move the amount calculation in a separate function maybe?
293-
grant.save(update_fields=["status", "approved_type"])
293+
grant.save(update_fields=["pending_status", "approved_type"])
294294

295295
messages.success(
296296
request, "Decisions saved. Check the Grants Summary for more info."
@@ -406,11 +406,11 @@ def _review_proposals_recap_view(self, request, review_session):
406406

407407
for proposal in proposals:
408408
decision = decisions[proposal.id]
409-
proposal.status = decision
409+
proposal.pending_status = decision
410410

411411
Submission.objects.bulk_update(
412412
proposals,
413-
fields=["status"],
413+
fields=["pending_status"],
414414
)
415415

416416
return redirect(

backend/reviews/templates/grants-recap.html

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,12 @@ <h3>
444444
</div>
445445
<div class="clear"></div>
446446
</th>
447+
<th scope="col">
448+
<div class="text">
449+
<span>Pending Status</span>
450+
</div>
451+
<div class="clear"></div>
452+
</th>
447453
<th scope="col">
448454
<div class="text">
449455
<span>Decision</span>
@@ -463,13 +469,13 @@ <h3>
463469
<script>
464470
grantsById[{{item.id}}] = {
465471
id: {{item.id}},
466-
status: "{{ item.status }}",
467-
originalStatus: "{{ item.status }}",
472+
status: "{{ item.pending_status }}",
473+
originalStatus: "{{ item.pending_status }}",
468474
numOfVotes: {{item.userreview_set.count}},
469475
};
470476
</script>
471477
<tr
472-
data-original-status="{{ item.status }}"
478+
data-original-status="{{ item.pending_status }}"
473479
data-original-approved-type="{{ item.approved_type }}"
474480
class="grant-item"
475481
id="grant-{{ item.id }}"
@@ -593,15 +599,20 @@ <h3>
593599
<td>
594600
{{ item.get_status_display }}
595601
<br />
596-
{% if item.approved_type %}({{ item.get_approved_type_display }}){% endif %}
602+
{% if item.status == "approved" and item.approved_type %}({{ item.get_approved_type_display }}){% endif %}
603+
</td>
604+
<td>
605+
{{ item.get_pending_status_display }}
606+
<br />
607+
{% if item.pending_status == "approved" and item.approved_type %}({{ item.get_approved_type_display }}){% endif %}
597608
</td>
598609
<td>
599610
{% if perms.reviews.decision_reviewsession %}
600611
<ul class="status-choices">
601612
{% for status in all_review_statuses %}
602613
<li>
603614
<label>
604-
<input {% if item.status == status.0 %}checked{% endif %}
615+
<input {% if item.pending_status == status.0 %}checked{% endif %}
605616
type="radio"
606617
class="status-decision-radio"
607618
name="decision-{{item.id}}"
@@ -630,7 +641,7 @@ <h3>
630641
{% if perms.reviews.decision_reviewsession %}
631642
<ul
632643
data-item-id="{{ item.id }}"
633-
class="approved-type-choices {% if item.status != 'approved' %}hidden{% endif %}"
644+
class="approved-type-choices {% if item.pending_status != 'approved' %}hidden{% endif %}"
634645
>
635646
{% for approved_type in all_approved_types %}
636647
<li>
@@ -673,7 +684,7 @@ <h3>
673684
<table>
674685
<tbody>
675686
<tr>
676-
<td><h2>Pending status</h2></td>
687+
<td><h2>Changes</h2></td>
677688
{% for status in all_statuses %}
678689
<td>
679690
{% if status in all_review_statuses %}

0 commit comments

Comments
 (0)