Skip to content

Commit 2158bf3

Browse files
committed
WIP
1 parent e173050 commit 2158bf3

File tree

9 files changed

+745
-195
lines changed

9 files changed

+745
-195
lines changed

backend/conferences/admin/conference.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,6 @@ class ConferenceAdmin(
184184
)
185185
},
186186
),
187-
(
188-
"Grants",
189-
{
190-
"fields": (
191-
"grants_default_ticket_amount",
192-
"grants_default_accommodation_amount",
193-
"grants_default_travel_from_italy_amount",
194-
"grants_default_travel_from_europe_amount",
195-
"grants_default_travel_from_extra_eu_amount",
196-
)
197-
},
198-
),
199187
("YouTube", {"fields": ("video_title_template", "video_description_template")}),
200188
)
201189
inlines = [DeadlineInline, DurationInline, SponsorLevelInline, IncludedEventInline]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Generated by Django 5.1.4 on 2025-07-27 14:30
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('conferences', '0054_conference_frontend_revalidate_secret_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name='conference',
15+
name='grants_default_accommodation_amount',
16+
),
17+
migrations.RemoveField(
18+
model_name='conference',
19+
name='grants_default_ticket_amount',
20+
),
21+
migrations.RemoveField(
22+
model_name='conference',
23+
name='grants_default_travel_from_europe_amount',
24+
),
25+
migrations.RemoveField(
26+
model_name='conference',
27+
name='grants_default_travel_from_extra_eu_amount',
28+
),
29+
migrations.RemoveField(
30+
model_name='conference',
31+
name='grants_default_travel_from_italy_amount',
32+
),
33+
]

backend/conferences/models/conference.py

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -93,47 +93,6 @@ class Conference(GeoLocalizedModel, TimeFramedModel, TimeStampedModel):
9393
default="",
9494
)
9595

96-
grants_default_ticket_amount = models.DecimalField(
97-
verbose_name=_("grants default ticket amount"),
98-
null=True,
99-
blank=True,
100-
max_digits=6,
101-
decimal_places=2,
102-
default=None,
103-
)
104-
grants_default_accommodation_amount = models.DecimalField(
105-
verbose_name=_("grants default accommodation amount"),
106-
null=True,
107-
blank=True,
108-
max_digits=6,
109-
decimal_places=2,
110-
default=None,
111-
)
112-
grants_default_travel_from_italy_amount = models.DecimalField(
113-
verbose_name=_("grants default travel from Italy amount"),
114-
null=True,
115-
blank=True,
116-
max_digits=6,
117-
decimal_places=2,
118-
default=None,
119-
)
120-
grants_default_travel_from_europe_amount = models.DecimalField(
121-
verbose_name=_("grants default travel from Europe amount"),
122-
null=True,
123-
blank=True,
124-
max_digits=6,
125-
decimal_places=2,
126-
default=None,
127-
)
128-
grants_default_travel_from_extra_eu_amount = models.DecimalField(
129-
verbose_name=_("grants default travel from Extra EU amount"),
130-
null=True,
131-
blank=True,
132-
max_digits=6,
133-
decimal_places=2,
134-
default=None,
135-
)
136-
13796
video_title_template = models.TextField(
13897
default="",
13998
blank=True,

backend/grants/admin.py

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
create_addition_admin_log_entry,
55
create_change_admin_log_entry,
66
)
7+
from django.db.models import Value, IntegerField
8+
9+
from django.db.models import Sum
10+
from django.db.models.functions import Coalesce
711
from conferences.models.conference_voucher import ConferenceVoucher
812
from pycon.constants import UTC
913
from custom_admin.admin import (
@@ -30,7 +34,12 @@
3034
)
3135
from schedule.models import ScheduleItem
3236
from submissions.models import Submission
33-
from .models import Grant, GrantConfirmPendingStatusProxy
37+
from .models import (
38+
Grant,
39+
GrantConfirmPendingStatusProxy,
40+
GrantReimbursementCategory,
41+
GrantReimbursement,
42+
)
3443
from django.db.models import Exists, OuterRef, F
3544
from pretix import user_has_admission_ticket
3645

@@ -393,6 +402,32 @@ def queryset(self, request, queryset):
393402
return queryset
394403

395404

405+
@admin.register(GrantReimbursementCategory)
406+
class GrantReimbursementCategoryAdmin(ConferencePermissionMixin, admin.ModelAdmin):
407+
list_display = ("__str__", "max_amount", "category", "included_by_default")
408+
list_filter = ("conference", "category", "included_by_default")
409+
search_fields = ("category", "name")
410+
411+
412+
@admin.register(GrantReimbursement)
413+
class GrantReimbursementAdmin(ConferencePermissionMixin, admin.ModelAdmin):
414+
list_display = (
415+
"grant",
416+
"category",
417+
"granted_amount",
418+
)
419+
list_filter = ("grant__conference", "category")
420+
search_fields = ("grant__full_name", "grant__email")
421+
autocomplete_fields = ("grant",)
422+
423+
424+
class GrantReimbursementInline(admin.TabularInline):
425+
model = GrantReimbursement
426+
extra = 0
427+
autocomplete_fields = ["category"]
428+
fields = ["category", "granted_amount"]
429+
430+
396431
@admin.register(Grant)
397432
class GrantAdmin(ExportMixin, ConferencePermissionMixin, admin.ModelAdmin):
398433
change_list_template = "admin/grants/grant/change_list.html"
@@ -405,11 +440,7 @@ class GrantAdmin(ExportMixin, ConferencePermissionMixin, admin.ModelAdmin):
405440
"emoji_gender",
406441
"conference",
407442
"status",
408-
"approved_type",
409-
"ticket_amount",
410-
"travel_amount",
411-
"accommodation_amount",
412-
"total_amount",
443+
"total_amount_display",
413444
"country_type",
414445
"user_has_ticket",
415446
"has_voucher",
@@ -423,7 +454,6 @@ class GrantAdmin(ExportMixin, ConferencePermissionMixin, admin.ModelAdmin):
423454
"pending_status",
424455
"country_type",
425456
"occupation",
426-
"approved_type",
427457
"needs_funds_for_travel",
428458
"need_visa",
429459
"need_accommodation",
@@ -449,6 +479,7 @@ class GrantAdmin(ExportMixin, ConferencePermissionMixin, admin.ModelAdmin):
449479
"delete_selected",
450480
]
451481
autocomplete_fields = ("user",)
482+
inlines = [GrantReimbursementInline]
452483

453484
fieldsets = (
454485
(
@@ -457,12 +488,7 @@ class GrantAdmin(ExportMixin, ConferencePermissionMixin, admin.ModelAdmin):
457488
"fields": (
458489
"status",
459490
"pending_status",
460-
"approved_type",
461491
"country_type",
462-
"ticket_amount",
463-
"travel_amount",
464-
"accommodation_amount",
465-
"total_amount",
466492
"applicant_reply_sent_at",
467493
"applicant_reply_deadline",
468494
"internal_notes",
@@ -584,10 +610,22 @@ def user_has_ticket(self, obj: Grant) -> bool:
584610
def has_voucher(self, obj: Grant) -> bool:
585611
return obj.has_voucher
586612

613+
@admin.display(description="Total")
614+
def total_amount_display(self, obj):
615+
return f"{obj.total_allocated:.2f}"
616+
617+
@admin.display(description="Approved Reimbursements")
618+
def approved_amounts_display(self, obj):
619+
return ", ".join(
620+
f"{r.category.name}: {r.granted_amount}" for r in obj.reimbursements.all()
621+
)
622+
587623
def get_queryset(self, request):
588624
qs = (
589625
super()
590626
.get_queryset(request)
627+
.select_related("user")
628+
.prefetch_related("reimbursements__category")
591629
.annotate(
592630
is_proposed_speaker=Exists(
593631
Submission.objects.non_cancelled().filter(
@@ -608,6 +646,11 @@ def get_queryset(self, request):
608646
user_id=OuterRef("user_id"),
609647
)
610648
),
649+
total_allocated=Coalesce(
650+
Sum("reimbursements__granted_amount"),
651+
Value(0),
652+
output_field=IntegerField(),
653+
),
611654
)
612655
)
613656

0 commit comments

Comments
 (0)