Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 28 additions & 115 deletions src/camps/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
)
62 changes: 48 additions & 14 deletions src/camps/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand All @@ -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"""
Expand All @@ -100,15 +109,20 @@ 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"""
for ticket in self.one_day_adults[:2]:
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
Expand All @@ -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
Expand All @@ -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"""
Expand All @@ -146,15 +164,22 @@ 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"""
for ticket in self.one_day_children[:2]:
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
Expand All @@ -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
Expand All @@ -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"""
Expand All @@ -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
Expand All @@ -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."""
Expand Down
2 changes: 1 addition & 1 deletion src/tokens/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading