Compare commits
4 Commits
d1b9202337
...
purchase_s
Author | SHA1 | Date | |
---|---|---|---|
a30c54ef44
|
|||
d9fbb4b896
|
|||
4ff3692606
|
|||
8289c48896
|
2
.github/workflows/build-docker.yml
vendored
2
.github/workflows/build-docker.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
poetry install
|
||||
poetry env info
|
||||
poetry run python manage.py migrate
|
||||
poetry run pytest
|
||||
PROD=1 poetry run pytest
|
||||
build-and-push:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -91,6 +91,7 @@ class PurchaseForm(forms.ModelForm):
|
||||
"date_purchased",
|
||||
"date_refunded",
|
||||
"date_finished",
|
||||
"status",
|
||||
"price",
|
||||
"price_currency",
|
||||
"ownership_type",
|
||||
|
26
games/migrations/0034_purchase_status.py
Normal file
26
games/migrations/0034_purchase_status.py
Normal file
@ -0,0 +1,26 @@
|
||||
# Generated by Django 4.2.7 on 2023-12-22 10:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("games", "0033_alter_edition_unique_together"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="purchase",
|
||||
name="status",
|
||||
field=models.IntegerField(
|
||||
choices=[
|
||||
(0, "Unplayed"),
|
||||
(1, "Playing"),
|
||||
(2, "Dropped"),
|
||||
(3, "Finished"),
|
||||
],
|
||||
default=0,
|
||||
),
|
||||
),
|
||||
]
|
22
games/migrations/0035_auto_20231222_1109.py
Normal file
22
games/migrations/0035_auto_20231222_1109.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Generated by Django 4.2.7 on 2023-12-22 10:09
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
from games.models import Purchase
|
||||
|
||||
|
||||
def set_default_state(apps, schema_editor):
|
||||
Purchase.objects.filter(session__isnull=False).update(
|
||||
status=Purchase.PurchaseState.PLAYING
|
||||
)
|
||||
Purchase.objects.filter(date_finished__isnull=False).update(
|
||||
status=Purchase.PurchaseState.FINISHED
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("games", "0034_purchase_status"),
|
||||
]
|
||||
|
||||
operations = [migrations.RunPython(set_default_state)]
|
@ -133,6 +133,25 @@ class Purchase(models.Model):
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class PurchaseState(models.IntegerChoices):
|
||||
UNPLAYED = (
|
||||
0,
|
||||
"Unplayed",
|
||||
)
|
||||
PLAYING = (1, "Playing")
|
||||
DROPPED = (
|
||||
2,
|
||||
"Dropped",
|
||||
)
|
||||
FINISHED = (
|
||||
3,
|
||||
"Finished",
|
||||
)
|
||||
|
||||
status = models.IntegerField(
|
||||
choices=PurchaseState.choices, default=PurchaseState.UNPLAYED
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
additional_info = [
|
||||
self.get_type_display() if self.type != Purchase.GAME else "",
|
||||
|
@ -75,10 +75,6 @@ function syncSelectInputUntilChanged(syncData, parentSelector = document) {
|
||||
* @param {string} property - The property to retrieve the value from.
|
||||
*/
|
||||
function getValueFromProperty(sourceElement, property) {
|
||||
let source =
|
||||
sourceElement instanceof HTMLSelectElement
|
||||
? sourceElement.selectedOptions[0]
|
||||
: sourceElement;
|
||||
let source =
|
||||
sourceElement instanceof HTMLSelectElement
|
||||
? sourceElement.selectedOptions[0]
|
||||
|
@ -137,6 +137,7 @@
|
||||
<tr>
|
||||
<th class="px-2 sm:px-4 md:px-6 md:py-2 purchase-name truncate max-w-20char">Name</th>
|
||||
<th class="px-2 sm:px-4 md:px-6 md:py-2">Date</th>
|
||||
<th class="px-2 sm:px-4 md:px-6 md:py-2">Playtime</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -153,6 +154,7 @@
|
||||
</a>
|
||||
</td>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchase.date_finished | date:"d/m/Y" }}</td>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchase.formatted_playtime }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -371,6 +371,16 @@ def stats(request, year: int = 0):
|
||||
)
|
||||
|
||||
purchases_finished_this_year = Purchase.objects.filter(date_finished__year=year)
|
||||
purchases_finished_this_year_with_playtime = purchases_finished_this_year.annotate(
|
||||
total_playtime=Sum(
|
||||
F("session__duration_calculated") + F("session__duration_manual")
|
||||
)
|
||||
)
|
||||
|
||||
for purchase in purchases_finished_this_year_with_playtime:
|
||||
formatted_playtime = format_duration(purchase.total_playtime, "%2.0H")
|
||||
setattr(purchase, "formatted_playtime", formatted_playtime)
|
||||
|
||||
purchases_finished_this_year_released_this_year = (
|
||||
purchases_finished_this_year.filter(edition__year_released=year).order_by(
|
||||
"date_finished"
|
||||
@ -442,7 +452,7 @@ def stats(request, year: int = 0):
|
||||
"spent_per_game": int(
|
||||
safe_division(total_spent, this_year_purchases_without_refunded.count())
|
||||
),
|
||||
"all_finished_this_year": purchases_finished_this_year.order_by(
|
||||
"all_finished_this_year": purchases_finished_this_year_with_playtime.order_by(
|
||||
"date_finished"
|
||||
),
|
||||
"this_year_finished_this_year": purchases_finished_this_year_released_this_year.order_by(
|
||||
@ -479,6 +489,7 @@ def stats(request, year: int = 0):
|
||||
highest_session_average_game.session_average, "%2.0Hh %2.0mm"
|
||||
),
|
||||
"highest_session_average_game": highest_session_average_game,
|
||||
"title": f"{year} Stats",
|
||||
}
|
||||
|
||||
request.session["return_path"] = request.path
|
||||
|
Reference in New Issue
Block a user