Add a Payments & dues section to the Me page, matching the design's M5 row
Home already had the M1 dues card; Me's own "Payments & dues" row was explicitly stubbed out with nowhere to lead. Give it a real destination: a Payments screen (open balances for everyone managed, reusing Home's dues-card layout via a shared _dues_row.html partial) and a "N OPEN" pill on the Me row itself, only shown once something is actually owed. club.services.fees.open_dues_rows is factored out so Home and Payments can never drift apart on what counts as "still open". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
@@ -23,7 +23,7 @@ from django.views.generic import TemplateView
|
||||
|
||||
from club.models import ClubMembership
|
||||
from club.services.access import current_season, has_management_access, teams_managed_by
|
||||
from club.services.fees import remaining_balance
|
||||
from club.services.fees import open_dues_rows
|
||||
from club.services.onboarding import checklist_for
|
||||
from club.services.sponsors import active_sponsors
|
||||
from controlpanel.messages import notify
|
||||
@@ -229,16 +229,7 @@ class HomeView(PersonScopeMixin, LoginRequiredMixin, TemplateView):
|
||||
|
||||
season = current_season(self.request.club)
|
||||
if season is not None:
|
||||
memberships = (
|
||||
ClubMembership.objects.filter(club=self.request.club, member__in=people, season=season)
|
||||
.exclude(fee_status=ClubMembership.FeeStatus.WAIVED)
|
||||
.select_related("dues_invoice", "member")
|
||||
)
|
||||
for membership in memberships:
|
||||
balance = remaining_balance(membership)
|
||||
if balance > 0:
|
||||
dues_rows.append({"membership": membership, "balance": balance, "invoice": getattr(membership, "dues_invoice", None)})
|
||||
|
||||
dues_rows = open_dues_rows(self.request.club, people, season)
|
||||
team_ids = list(TeamMembership.objects.filter(member__in=people, season=season).values_list("team_id", flat=True))
|
||||
else:
|
||||
team_ids = []
|
||||
@@ -538,10 +529,12 @@ class MeView(PersonScopeMixin, LoginRequiredMixin, TemplateView):
|
||||
roster), and a settings-ish card linking into M6 (edit_profile) for
|
||||
``self.me`` and into M7 (notifications).
|
||||
|
||||
The mockup's "Household & contacts" and "Payments & dues" rows, and its
|
||||
"Coach mode" promo card, have nowhere to lead in this build (no dedicated
|
||||
screen, no Coach mode screens at all yet -- see base.html's own comment)
|
||||
and are deliberately omitted rather than built as dead or inert links.
|
||||
The mockup's "Household & contacts" row and its "Coach mode" promo card
|
||||
have nowhere to lead in this build (no dedicated screen, no Coach mode
|
||||
screens at all yet -- see base.html's own comment) and are deliberately
|
||||
omitted rather than built as dead or inert links. "Payments & dues" does
|
||||
lead somewhere -- PaymentsView below -- with its "N OPEN" pill only
|
||||
rendered once there's actually a balance owed.
|
||||
|
||||
There's no license/eligibility field on Member or ClubMembership to power
|
||||
the mockup's "licence OK" text, so each managed person's meta line is
|
||||
@@ -591,14 +584,36 @@ class MeView(PersonScopeMixin, LoginRequiredMixin, TemplateView):
|
||||
}
|
||||
people_rows = [{"person": person, "membership": memberships_by_member.get(person.pk)} for person in self.managed_people]
|
||||
|
||||
open_dues_count = len(open_dues_rows(club, self.managed_people, season))
|
||||
|
||||
return super().get_context_data(
|
||||
member_since=member_since,
|
||||
team_manager_label=team_manager_label,
|
||||
people_rows=people_rows,
|
||||
open_dues_count=open_dues_count,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
class PaymentsView(PersonScopeMixin, LoginRequiredMixin, TemplateView):
|
||||
"""M5's "Payments & dues" row -- every open season-dues balance across
|
||||
``self.managed_people``, one card per person owed, in the same €-badge /
|
||||
amount+due-date / Pay layout as Home's dues card (club.services.fees.
|
||||
open_dues_rows is the shared source for both). No online payment gateway
|
||||
exists yet, so "Pay" is the same non-functional stub as Home's -- this
|
||||
screen's job is visibility ("what do I owe, and when"), not collection.
|
||||
"""
|
||||
|
||||
template_name = "mobile/payments.html"
|
||||
screen_title = _("Payments & dues")
|
||||
active_tab = "me"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
season = current_season(self.request.club)
|
||||
dues_rows = open_dues_rows(self.request.club, self.managed_people, season)
|
||||
return super().get_context_data(dues_rows=dues_rows, **kwargs)
|
||||
|
||||
|
||||
class EditProfileView(PersonScopeMixin, LoginRequiredMixin, TemplateView):
|
||||
"""M6 -- design_handoff_rosterchief_platform/README.md's M6 section,
|
||||
"Edit personal info". The design mock also shows a "National register
|
||||
|
||||
Reference in New Issue
Block a user