diff --git a/src/camps/models.py b/src/camps/models.py index 2e5a67662..b6f1c5eb1 100644 --- a/src/camps/models.py +++ b/src/camps/models.py @@ -356,132 +356,45 @@ def event_slots(self): EventSlot = apps.get_model("program", "EventSlot") return EventSlot.objects.filter(event_session__in=self.event_sessions.all()) - @property - def checked_in_full_week_adults(self) -> int: - """Return the count of full week adult tickets checked in""" - shop_tickets = ( - ShopTicket.objects.filter( - ticket_type=self.ticket_type_full_week_adult, - ).exclude(used_at=None) - ).count() - - sponsor_tickets = ( - SponsorTicket.objects.filter( - ticket_type=self.ticket_type_full_week_adult, - ).exclude(used_at=None) - ).count() - - prize_tickets = ( - PrizeTicket.objects.filter( - ticket_type=self.ticket_type_full_week_adult, - ).exclude(used_at=None) - ).count() - - return shop_tickets + sponsor_tickets + prize_tickets - - @property - def checked_in_full_week_children(self) -> int: - """Return the count of full week children tickets checked in""" - shop_tickets = ( - ShopTicket.objects.filter( - ticket_type=self.ticket_type_full_week_child, - ).exclude(used_at=None) - ).count() - - sponsor_tickets = ( - SponsorTicket.objects.filter( - ticket_type=self.ticket_type_full_week_child, - ).exclude(used_at=None) - ).count() - - prize_tickets = ( - PrizeTicket.objects.filter( - ticket_type=self.ticket_type_full_week_child, - ).exclude(used_at=None) - ).count() - - return shop_tickets + sponsor_tickets + prize_tickets - - @property - def checked_in_one_day_adults(self) -> int: - """Return the count of todays one day adult tickets checked in. - - Count tickets with a checked in timestamp from 0600-0600 next day. - Reason being early arriving participants might get checked in before 10. + def checked_in_tickets(self, ticket_type, used_before=None, used_after=None) -> list: + """Get a concatenated list with all tickets of the specified type + and support for filtering before/after time for when a ticket was used. """ - now = timezone.localtime() - today_06_hour = now.replace(hour=6, minute=0, second=0) - if now < today_06_hour: - start = today_06_hour - timezone.timedelta(days=1) - end = today_06_hour - else: - start = today_06_hour - end = today_06_hour + timezone.timedelta(days=1) + shop_tickets = ShopTicket.objects.filter(ticket_type=ticket_type).exclude(used_at=None) + sponsor_tickets = SponsorTicket.objects.filter(ticket_type=ticket_type).exclude(used_at=None) + prize_tickets = PrizeTicket.objects.filter(ticket_type=ticket_type).exclude(used_at=None) - shop_tickets = ( - ShopTicket.objects.filter( - ticket_type=self.ticket_type_one_day_adult, - ).filter(used_at__gte=start, used_at__lt=end) - ).count() + if used_before: + shop_tickets = shop_tickets.filter(used_at__lte=used_before) + sponsor_tickets = sponsor_tickets.filter(used_at__lte=used_before) + prize_tickets = prize_tickets.filter(used_at__lte=used_before) + if used_after: + shop_tickets = shop_tickets.filter(used_at__gte=used_after) + sponsor_tickets = sponsor_tickets.filter(used_at__gte=used_after) + prize_tickets = prize_tickets.filter(used_at__gte=used_after) - sponsor_tickets = ( - SponsorTicket.objects.filter( - ticket_type=self.ticket_type_one_day_adult, - ).filter(used_at__gte=start, used_at__lt=end) - ).count() - - prize_tickets = ( - PrizeTicket.objects.filter( - ticket_type=self.ticket_type_one_day_adult, - ).filter(used_at__gte=start, used_at__lt=end) - ).count() - - return shop_tickets + sponsor_tickets + prize_tickets + return list(shop_tickets) + list(sponsor_tickets) + list(prize_tickets) @property - def checked_in_one_day_children(self) -> int: - """Return the count of todays one day children tickets checked in. + def todays_participant_count(self) -> int: + """Calculate todays participant count from all used 'full week' tickets + and todays used 'one day' tickets. Count tickets with a checked in timestamp from 0600-0600 next day. Reason being early arriving participants might get checked in before 10. """ now = timezone.localtime() - today_06_hour = now.replace(hour=6, minute=0, second=0) - if now < today_06_hour: - start = today_06_hour - timezone.timedelta(days=1) - end = today_06_hour + limit = now.replace(hour=6, minute=0, second=0) + if now < limit: + used_after = limit - timezone.timedelta(days=1) + used_before = limit else: - start = today_06_hour - end = today_06_hour + timezone.timedelta(days=1) - - shop_tickets = ( - ShopTicket.objects.filter( - ticket_type=self.ticket_type_one_day_child, - ).filter(used_at__gte=start, used_at__lt=end) - ).count() - - sponsor_tickets = ( - SponsorTicket.objects.filter( - ticket_type=self.ticket_type_one_day_child, - ).filter(used_at__gte=start, used_at__lt=end) - ).count() + used_after = limit + used_before = limit + timezone.timedelta(days=1) - prize_tickets = ( - PrizeTicket.objects.filter( - ticket_type=self.ticket_type_one_day_child, - ).filter(used_at__gte=start, used_at__lt=end) - ).count() - - return shop_tickets + sponsor_tickets + prize_tickets - - @property - def participant_count(self) -> int: - """Retrieve the participant count for all used 'full week' tickets - and todays used 'one day' tickets. - """ return ( - self.checked_in_full_week_adults - + self.checked_in_full_week_children - + self.checked_in_one_day_adults - + self.checked_in_one_day_children + len(self.checked_in_tickets(self.ticket_type_full_week_adult)) + + len(self.checked_in_tickets(self.ticket_type_full_week_child)) + + len(self.checked_in_tickets(self.ticket_type_one_day_adult, used_before, used_after)) + + len(self.checked_in_tickets(self.ticket_type_one_day_child, used_before, used_after)) ) diff --git a/src/camps/tests.py b/src/camps/tests.py index 9ed6370e1..569d6adbc 100644 --- a/src/camps/tests.py +++ b/src/camps/tests.py @@ -69,18 +69,24 @@ def test_checked_in_full_week_adults_all_ticket_types(self) -> None: self.full_week_adults["sponsor_tickets"][0], self.full_week_adults["prize_tickets"][0], ] + for ticket in tickets: ticket.used_at = self.camp.camp.lower ticket.save() - assert self.camp.checked_in_full_week_adults == 3 + result = self.camp.checked_in_tickets(self.camp.ticket_type_full_week_adult) + + assert len(result) == len(tickets) def test_checked_in_full_week_children_shop_tickets(self) -> None: """Test the return value of checked in full week children with shop ticket""" ticket = self.full_week_children[0] ticket.used_at = self.camp.camp.lower ticket.save() - assert self.camp.checked_in_full_week_children == 1 + + result = self.camp.checked_in_tickets(self.camp.ticket_type_full_week_child) + + assert len(result) == 1 def test_checked_in_full_week_children_with_sponsor_ticket(self) -> None: """Test the return value of checked in full week children with sponsor ticket""" @@ -90,7 +96,10 @@ def test_checked_in_full_week_children_with_sponsor_ticket(self) -> None: ticket_type=self.camp.ticket_type_full_week_child, used_at=self.camp.camp.lower, ) - assert self.camp.checked_in_full_week_children == 1 + + result = self.camp.checked_in_tickets(self.camp.ticket_type_full_week_child) + + assert len(result) == 1 def test_checked_in_full_week_children_with_prize_ticket(self) -> None: """Test the return value of checked in full week children with prize ticket""" @@ -100,7 +109,10 @@ def test_checked_in_full_week_children_with_prize_ticket(self) -> None: comment="Prize winner", used_at=self.camp.camp.lower, ) - assert self.camp.checked_in_full_week_children == 1 + + result = self.camp.checked_in_tickets(self.camp.ticket_type_full_week_child) + + assert len(result) == 1 def test_checked_in_one_day_adults(self) -> None: """Test the return value of checked in one day adults today""" @@ -108,7 +120,9 @@ def test_checked_in_one_day_adults(self) -> None: ticket.used_at = timezone.localtime() ticket.save() - assert self.camp.checked_in_one_day_adults == 2 + result = self.camp.checked_in_tickets(self.camp.ticket_type_one_day_adult) + + assert len(result) == 2 def test_checked_in_one_day_adults_with_sponsor_ticket(self) -> None: """Test the return value of checked in one day adults @@ -121,7 +135,9 @@ def test_checked_in_one_day_adults_with_sponsor_ticket(self) -> None: used_at=timezone.localtime(), ) - assert self.camp.checked_in_one_day_adults == 1 + result = self.camp.checked_in_tickets(self.camp.ticket_type_one_day_adult) + + assert len(result) == 1 def test_checked_in_one_day_adults_with_prize_ticket(self) -> None: """Test the return value of checked in one day adults @@ -134,7 +150,9 @@ def test_checked_in_one_day_adults_with_prize_ticket(self) -> None: used_at=timezone.localtime(), ) - assert self.camp.checked_in_one_day_adults == 1 + result = self.camp.checked_in_tickets(self.camp.ticket_type_one_day_adult) + + assert len(result) == 1 def test_checked_in_one_day_adults_timing(self) -> None: """Test check in before 06 yesterday don't count""" @@ -146,7 +164,12 @@ def test_checked_in_one_day_adults_timing(self) -> None: not_valid.used_at = timezone.localtime() - timezone.timedelta(days=2) not_valid.save() - assert self.camp.checked_in_one_day_adults == 1 + result = self.camp.checked_in_tickets( + self.camp.ticket_type_one_day_adult, + used_after=timezone.localtime().replace(hour=6, minute=0, second=0) + ) + + assert len(result) == 1 def test_checked_in_one_day_children(self) -> None: """Test the return value of checked in one day children today""" @@ -154,7 +177,9 @@ def test_checked_in_one_day_children(self) -> None: ticket.used_at = timezone.localtime() ticket.save() - assert self.camp.checked_in_one_day_children == 2 + result = self.camp.checked_in_tickets(self.camp.ticket_type_one_day_child) + + assert len(result) == 2 def test_checked_in_one_day_children_with_sponsor_ticket(self) -> None: """Test the return value of checked in one day children @@ -167,7 +192,9 @@ def test_checked_in_one_day_children_with_sponsor_ticket(self) -> None: used_at=timezone.localtime(), ) - assert self.camp.checked_in_one_day_children == 1 + result = self.camp.checked_in_tickets(self.camp.ticket_type_one_day_child) + + assert len(result) == 1 def test_checked_in_one_day_children_with_prize_ticket(self) -> None: """Test the return value of checked in one day children @@ -180,7 +207,9 @@ def test_checked_in_one_day_children_with_prize_ticket(self) -> None: used_at=timezone.localtime(), ) - assert self.camp.checked_in_one_day_children == 1 + result = self.camp.checked_in_tickets(self.camp.ticket_type_one_day_child) + + assert len(result) == 1 def test_checked_in_one_day_children_timing(self) -> None: """Test check in before 06 yesterday don't count""" @@ -192,9 +221,14 @@ def test_checked_in_one_day_children_timing(self) -> None: not_valid.used_at = timezone.localtime() - timezone.timedelta(days=2) not_valid.save() - assert self.camp.checked_in_one_day_children == 1 + result = self.camp.checked_in_tickets( + self.camp.ticket_type_one_day_child, + used_after=timezone.localtime().replace(hour=6, minute=0, second=0) + ) + + assert len(result) == 1 - def test_participant_count(self) -> None: + def test_todays_participant_count(self) -> None: """Test the count of all participants""" adult_full_week = self.full_week_adults["shop_tickets"][0] adult_full_week.used_at = self.camp.camp.lower @@ -212,7 +246,7 @@ def test_participant_count(self) -> None: child_one_day.used_at = timezone.localtime() child_one_day.save() - assert self.camp.participant_count == 4 + assert self.camp.todays_participant_count == 4 def test_year_of_camp(self) -> None: """Test the property `year` return current year of camp.""" diff --git a/src/tokens/views.py b/src/tokens/views.py index 363163968..10d434fa1 100644 --- a/src/tokens/views.py +++ b/src/tokens/views.py @@ -99,7 +99,7 @@ def get_total_players_metrics(self, camp_finds: QuerySet) -> dict: .last() ) unique_player_count = camp_finds.distinct("user").count() - non_player_count = self.request.camp.participant_count + non_player_count = self.request.camp.todays_participant_count if non_player_count: # Avoid ZeroDivisionError players_pct = unique_player_count / (unique_player_count + non_player_count) * 100