diff --git a/ws/api_views.py b/ws/api_views.py index b45271b5..ff2b782c 100644 --- a/ws/api_views.py +++ b/ws/api_views.py @@ -639,7 +639,7 @@ def dispatch(self, request, *args, **kwargs): class RawMembershipStatsView(View): @staticmethod - def _all_members_info() -> Iterator[dict[str, str | int]]: + def _all_members_info() -> Iterator[dict[str, str | int | bool]]: for info in geardb_utils.membership_information().values(): flat_info: dict[str, str | int] = { "last_known_affiliation": info.last_known_affiliation, diff --git a/ws/templates/stats/membership.html b/ws/templates/stats/membership.html index 4f12f748..a5ef82fc 100644 --- a/ws/templates/stats/membership.html +++ b/ws/templates/stats/membership.html @@ -198,6 +198,9 @@ var justLeaders = _.filter(allMembers, 'num_trips_led'); renderChart("#leaders", justLeaders); + var ratedLeaders = _.filter(allMembers, 'is_leader'); + renderChart("#rated_leaders", ratedLeaders); + var justDiscounts = _.filter(allMembers, function(info) { return (info.num_discounts && !info.num_rentals && !info.num_trips_attended); }); @@ -239,11 +242,14 @@
Affiliation of people who hold a leader rating, even if they never lead trips.
+ +Current affiliation of people who have ever led a trip.
+Current affiliation of people who have ever led a trip (even if they're not currently rated).
-This is a count of all MITOCers who've paid their dues (but may not have rented gear, participated on trips, or otherwise made use of the club). diff --git a/ws/utils/geardb.py b/ws/utils/geardb.py index fdea792f..f4652484 100644 --- a/ws/utils/geardb.py +++ b/ws/utils/geardb.py @@ -15,7 +15,7 @@ import requests from allauth.account.models import EmailAddress from django.contrib.auth.models import User -from django.db.models import Case, Count, IntegerField, Sum, When +from django.db.models import Case, Count, IntegerField, Q, Sum, When from django.db.models.functions import Lower from ws import models, settings @@ -53,6 +53,7 @@ class Rental(NamedTuple): class TripsInformation(NamedTuple): + is_leader: bool num_trips_attended: int num_trips_led: int num_discounts: int @@ -328,11 +329,13 @@ def trips_information() -> dict[int, TripsInformation]: additional_stats = models.Participant.objects.all().annotate( num_discounts=Count("discounts", distinct=True), num_trips_led=Count("trips_led", distinct=True), + num_leader_ratings=Count("leaderrating", filter=Q(leaderrating__active=True)), ) return { par.user_id: TripsInformation( email=par.email, + is_leader=bool(par.num_leader_ratings), num_trips_attended=trips_per_participant[par.pk], num_trips_led=par.num_trips_led, num_discounts=par.num_discounts,