Compare commits

..

2 Commits

Author SHA1 Message Date
Lukáš Kucharczyk ce3c4b55f0 Order devices alphabetically on new session form
continuous-integration/drone/push Build is passing Details
2023-11-09 10:09:32 +01:00
Lukáš Kucharczyk c52cd822ae Use safe_division in more places 2023-11-09 10:06:14 +01:00
4 changed files with 24 additions and 13 deletions

View File

@ -25,6 +25,7 @@
### Improved ### Improved
* game overview: simplify playtime range display * game overview: simplify playtime range display
* new session: order devices alphabetically
## 1.3.0 / 2023-11-05 15:09+01:00 ## 1.3.0 / 2023-11-05 15:09+01:00

9
common/utils.py Normal file
View File

@ -0,0 +1,9 @@
def safe_division(numerator: int | float, denominator: int | float) -> int | float:
"""
Divides without triggering division by zero exception.
Returns 0 if denominator is 0.
"""
try:
return numerator / denominator
except ZeroDivisionError:
return 0

View File

@ -19,6 +19,8 @@ class SessionForm(forms.ModelForm):
widget=autofocus_select_widget, widget=autofocus_select_widget,
) )
device = forms.ModelChoiceField(queryset=Device.objects.order_by("name"))
class Meta: class Meta:
widgets = { widgets = {
"timestamp_start": custom_datetime_widget, "timestamp_start": custom_datetime_widget,

View File

@ -1,4 +1,5 @@
from common.time import format_duration, now as now_with_tz from common.time import format_duration, now as now_with_tz
from common.utils import safe_division
from datetime import datetime, timedelta from datetime import datetime, timedelta
from django.conf import settings from django.conf import settings
from django.db.models import Sum, F, Count from django.db.models import Sum, F, Count
@ -304,15 +305,11 @@ def stats(request, year: int = 0):
purchased_unfinished = all_purchased_without_refunded_this_year.filter( purchased_unfinished = all_purchased_without_refunded_this_year.filter(
date_finished__isnull=True date_finished__isnull=True
) )
if (
purchased_unfinished.count() == 0
or all_purchased_refunded_this_year.count() == 0
):
unfinished_purchases_percent = 0
else:
unfinished_purchases_percent = int( unfinished_purchases_percent = int(
purchased_unfinished.count() safe_division(
/ all_purchased_refunded_this_year.count() purchased_unfinished.count(), all_purchased_refunded_this_year.count()
)
* 100 * 100
) )
@ -374,7 +371,7 @@ def stats(request, year: int = 0):
"total_spent_currency": selected_currency, "total_spent_currency": selected_currency,
"all_purchased_this_year": all_purchased_without_refunded_this_year, "all_purchased_this_year": all_purchased_without_refunded_this_year,
"spent_per_game": int( "spent_per_game": int(
total_spent / all_purchased_without_refunded_this_year.count() safe_division(total_spent, all_purchased_without_refunded_this_year.count())
), ),
"all_finished_this_year": all_finished_this_year, "all_finished_this_year": all_finished_this_year,
"this_year_finished_this_year": this_year_finished_this_year, "this_year_finished_this_year": this_year_finished_this_year,
@ -385,8 +382,10 @@ def stats(request, year: int = 0):
"purchased_unfinished": purchased_unfinished, "purchased_unfinished": purchased_unfinished,
"unfinished_purchases_percent": unfinished_purchases_percent, "unfinished_purchases_percent": unfinished_purchases_percent,
"refunded_percent": int( "refunded_percent": int(
all_purchased_refunded_this_year.count() safe_division(
/ all_purchased_this_year.count() all_purchased_refunded_this_year.count(),
all_purchased_this_year.count(),
)
* 100 * 100
), ),
"all_purchased_refunded_this_year": all_purchased_refunded_this_year, "all_purchased_refunded_this_year": all_purchased_refunded_this_year,