Skip to content

Commit

Permalink
Give the admin an indication of how revenue for sponsorships in this …
Browse files Browse the repository at this point in the history
…package will be divvied up
  • Loading branch information
indepndnt committed Sep 11, 2024
1 parent f72533b commit 7e768fd
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
35 changes: 33 additions & 2 deletions sponsors/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class ProvidedFileAssetConfigurationInline(StackedPolymorphicInline.Child):
ProvidedFileAssetConfigurationInline,
]


@admin.register(SponsorshipBenefit)
class SponsorshipBenefitAdmin(PolymorphicInlineSupportMixin, OrderedModelAdmin):
change_form_template = "sponsors/admin/sponsorshipbenefit_change_form.html"
Expand Down Expand Up @@ -179,12 +180,12 @@ def update_related_sponsorships(self, *args, **kwargs):
@admin.register(SponsorshipPackage)
class SponsorshipPackageAdmin(OrderedModelAdmin):
ordering = ("-year", "order",)
list_display = ["name", "year", "advertise", "allow_a_la_carte", "move_up_down_links"]
list_display = ["name", "year", "advertise", "allow_a_la_carte", "get_benefit_split", "move_up_down_links"]
list_filter = ["advertise", "year", "allow_a_la_carte"]
search_fields = ["name"]

def get_readonly_fields(self, request, obj=None):
readonly = []
readonly = ["get_benefit_split"]
if obj:
readonly.append("slug")
if not request.user.is_superuser:
Expand All @@ -196,6 +197,36 @@ def get_prepopulated_fields(self, request, obj=None):
return {'slug': ['name']}
return {}

def get_benefit_split(self, obj: SponsorshipPackage) -> str:
# colors selected from defined css variables in order to look like they fit in the theme
colors = [
"secondary", # blue
"admin-interface-header-background-color", # dark green
"admin-interface-title-color", # yellow
"admin-interface-header-text-color", # light green
"admin-interface-delete-button-background-hover-color", # red
"admin-interface-save-button-background-hover-color", # darker green
"admin-interface-module-background-selected-color", # light yellow
"admin-interface-generic-link-hover-color", # medium green
]
split = obj.get_default_revenue_split()
# I hope there's never more than 8 things in the split, but just in case...
if len(split) > len(colors):
colors = colors * (1 + (len(split) // len(colors)))
# build some span elements to show the percentages and have the program name in the title (to show on hover)
widths, spans = [], []
for i, (name, pct) in enumerate(split):
pct_str = f"{pct:.0f}%"
widths.append(pct_str)
spans.append(f"<span title='{name}' style='background-color:var(--{colors[i]})'>{pct_str}</span>")
# define a style that will show our span elements like a single horizontal stacked bar chart
style = f'color:#fff;text-align:center;cursor:pointer;display:grid;grid-template-columns:{" ".join(widths)}'
# wrap it all up and put a bow on it
html = f"<div style='{style}'>{''.join(spans)}</div>"
return mark_safe(html)

get_benefit_split.short_description = "Revenue split"


class SponsorContactInline(admin.TabularInline):
model = SponsorContact
Expand Down
12 changes: 12 additions & 0 deletions sponsors/models/sponsorship.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ def clone(self, year: int):
slug=self.slug, year=year, defaults=defaults
)

def get_default_revenue_split(self) -> list[tuple[str, float]]:
"""
Give the admin an indication of how revenue for sponsorships in this package will be divvied up
"""
values, key = {}, "program__description"
for benefit in self.benefits.values(key).annotate(amount=Sum("internal_value", default=0)).order_by("-amount"):
values[benefit[key]] = values.get(benefit[key], 0) + (benefit["amount"] or 0)
total = sum(values.values())
if not total:
return [] # nothing to split!
return [(k, round(v / total * 100, 3)) for k, v in values.items()]


class SponsorshipProgram(OrderedModel):
"""
Expand Down
9 changes: 9 additions & 0 deletions sponsors/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,15 @@ def test_clone_does_not_repeate_already_cloned_package(self):
self.assertFalse(created)
self.assertEqual(pkg_2023.pk, repeated_pkg_2023.pk)

def test_get_default_revenue_split(self):
for i in range(3):
self.package_benefits[i].internal_value = 1000
self.package_benefits[i].save()
split = self.package.get_default_revenue_split()
total = sum((pct for _, pct in split))
self.assertEqual(total, 100)


class SponsorContactModelTests(TestCase):
def test_get_primary_contact_for_sponsor(self):
sponsor = baker.make(Sponsor)
Expand Down

0 comments on commit 7e768fd

Please sign in to comment.