diff --git a/games/templates/view_purchase.html b/games/templates/view_purchase.html
index aa3290f..a9a6aa6 100644
--- a/games/templates/view_purchase.html
+++ b/games/templates/view_purchase.html
@@ -3,7 +3,7 @@
- {% if purchase.name %}{{ purchase.name }}{% else %}Unnamed purchase{% endif %} ({{ purchase.editions.count }} games)
+ {% if purchase.name %}{{ purchase.name }}{% else %}Unnamed purchase{% endif %} ({{ purchase.games.count }} games)
-
Price: {{ purchase.converted_price | floatformat }} {{ purchase.converted_currency }} ({{ purchase.price | floatformat }} {{ purchase.price_currency }})
+
+ Price:
+ {% if purchase.converted_price %}
+ {{ purchase.converted_price | floatformat }} {{ purchase.converted_currency }}
+ {% else %}
+ None
+ {% endif %}
+ ({{ purchase.price | floatformat }} {{ purchase.price_currency }})
+
Items:
- {% for edition in purchase.editions.all %}
-
+ {% for game in purchase.games.all %}
+
{% endfor %}
diff --git a/games/urls.py b/games/urls.py
index ccb398f..a791dd8 100644
--- a/games/urls.py
+++ b/games/urls.py
@@ -1,6 +1,6 @@
from django.urls import path
-from games.views import device, edition, game, general, platform, purchase, session
+from games.views import device, game, general, platform, purchase, session
urlpatterns = [
path("", general.index, name="index"),
@@ -8,19 +8,6 @@ urlpatterns = [
path("device/delete/
", device.delete_device, name="delete_device"),
path("device/edit/", device.edit_device, name="edit_device"),
path("device/list", device.list_devices, name="list_devices"),
- path("edition/add", edition.add_edition, name="add_edition"),
- path(
- "edition/add/for-game/",
- edition.add_edition,
- name="add_edition_for_game",
- ),
- path("edition//edit", edition.edit_edition, name="edit_edition"),
- path("edition/list", edition.list_editions, name="list_editions"),
- path(
- "edition//delete",
- edition.delete_edition,
- name="delete_edition",
- ),
path("game/add", game.add_game, name="add_game"),
path("game//edit", game.edit_game, name="edit_game"),
path("game//view", game.view_game, name="view_game"),
@@ -39,6 +26,11 @@ urlpatterns = [
),
path("platform/list", platform.list_platforms, name="list_platforms"),
path("purchase/add", purchase.add_purchase, name="add_purchase"),
+ path(
+ "purchase/add/for-game/",
+ purchase.add_purchase,
+ name="add_purchase_for_game",
+ ),
path(
"purchase//edit",
purchase.edit_purchase,
@@ -75,20 +67,15 @@ urlpatterns = [
name="refund_purchase",
),
path(
- "purchase/related-purchase-by-edition",
- purchase.related_purchase_by_edition,
- name="related_purchase_by_edition",
- ),
- path(
- "purchase/add/for-edition/",
- purchase.add_purchase,
- name="add_purchase_for_edition",
+ "purchase/related-purchase-by-game",
+ purchase.related_purchase_by_game,
+ name="related_purchase_by_game",
),
path("session/add", session.add_session, name="add_session"),
path(
- "session/add/for-purchase/",
+ "session/add/for-game/",
session.add_session,
- name="add_session_for_purchase",
+ name="add_session_for_game",
),
path(
"session/add/from-game/",
diff --git a/games/views/edition.py b/games/views/edition.py
deleted file mode 100644
index ffb0039..0000000
--- a/games/views/edition.py
+++ /dev/null
@@ -1,150 +0,0 @@
-from typing import Any
-
-from django.contrib.auth.decorators import login_required
-from django.core.paginator import Paginator
-from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
-from django.shortcuts import get_object_or_404, redirect, render
-from django.template.loader import render_to_string
-from django.urls import reverse
-
-from common.components import (
- A,
- Button,
- Icon,
- NameWithIcon,
- PopoverTruncated,
-)
-from common.time import dateformat, local_strftime
-from games.forms import EditionForm
-from games.models import Edition, Game
-
-
-@login_required
-def list_editions(request: HttpRequest) -> HttpResponse:
- context: dict[Any, Any] = {}
- page_number = request.GET.get("page", 1)
- limit = request.GET.get("limit", 10)
- editions = Edition.objects.order_by("-created_at")
- page_obj = None
- if int(limit) != 0:
- paginator = Paginator(editions, limit)
- page_obj = paginator.get_page(page_number)
- editions = page_obj.object_list
-
- context = {
- "title": "Manage editions",
- "page_obj": page_obj or None,
- "elided_page_range": (
- page_obj.paginator.get_elided_page_range(
- page_number, on_each_side=1, on_ends=1
- )
- if page_obj
- else None
- ),
- "data": {
- "header_action": A([], Button([], "Add edition"), url="add_edition"),
- "columns": [
- "Game",
- "Name",
- "Sort Name",
- "Year",
- "Wikidata",
- "Created",
- "Actions",
- ],
- "rows": [
- [
- NameWithIcon(edition_id=edition.pk),
- PopoverTruncated(
- edition.name
- if edition.game.name != edition.name
- else "(identical)"
- ),
- PopoverTruncated(
- edition.sort_name
- if edition.sort_name is not None
- and edition.game.name != edition.sort_name
- else "(identical)"
- ),
- edition.year_released,
- edition.wikidata,
- local_strftime(edition.created_at, dateformat),
- render_to_string(
- "cotton/button_group.html",
- {
- "buttons": [
- {
- "href": reverse("edit_edition", args=[edition.pk]),
- "slot": Icon("edit"),
- "color": "gray",
- },
- {
- "href": reverse(
- "delete_edition", args=[edition.pk]
- ),
- "slot": Icon("delete"),
- "color": "red",
- },
- ]
- },
- ),
- ]
- for edition in editions
- ],
- },
- }
- return render(request, "list_purchases.html", context)
-
-
-@login_required
-def edit_edition(request: HttpRequest, edition_id: int = 0) -> HttpResponse:
- edition = get_object_or_404(Edition, id=edition_id)
- form = EditionForm(request.POST or None, instance=edition)
- if form.is_valid():
- form.save()
- return redirect("list_editions")
-
- context: dict[str, Any] = {"form": form, "title": "Edit edition"}
- return render(request, "add.html", context)
-
-
-@login_required
-def delete_edition(request: HttpRequest, edition_id: int) -> HttpResponse:
- edition = get_object_or_404(Edition, id=edition_id)
- edition.delete()
- return redirect("list_editions")
-
-
-@login_required
-def add_edition(request: HttpRequest, game_id: int = 0) -> HttpResponse:
- context: dict[str, Any] = {}
- if request.method == "POST":
- form = EditionForm(request.POST or None)
- if form.is_valid():
- edition = form.save()
- if "submit_and_redirect" in request.POST:
- return HttpResponseRedirect(
- reverse(
- "add_purchase_for_edition", kwargs={"edition_id": edition.id}
- )
- )
- else:
- return redirect("index")
- else:
- if game_id:
- game = get_object_or_404(Game, id=game_id)
- form = EditionForm(
- initial={
- "game": game,
- "name": game.name,
- "sort_name": game.sort_name,
- "year_released": game.year_released,
- }
- )
- else:
- form = EditionForm()
-
- context["form"] = form
- context["title"] = "Add New Edition"
- context["script_name"] = "add_edition.js"
- return render(request, "add_edition.html", context)
diff --git a/games/views/game.py b/games/views/game.py
index 2f99716..7d46938 100644
--- a/games/views/game.py
+++ b/games/views/game.py
@@ -29,7 +29,7 @@ from common.time import (
)
from common.utils import safe_division, truncate
from games.forms import GameForm
-from games.models import Edition, Game, Purchase, Session
+from games.models import Game, Purchase
from games.views.general import use_custom_redirect
@@ -109,7 +109,7 @@ def add_game(request: HttpRequest) -> HttpResponse:
game = form.save()
if "submit_and_redirect" in request.POST:
return HttpResponseRedirect(
- reverse("add_edition_for_game", kwargs={"game_id": game.id})
+ reverse("add_purchase_for_game", kwargs={"game_id": game.id})
)
else:
return redirect("list_games")
@@ -158,21 +158,12 @@ def view_game(request: HttpRequest, game_id: int) -> HttpResponse:
),
to_attr="game_purchases",
)
- editions = (
- Edition.objects.filter(game=game)
- .prefetch_related(game_purchases_prefetch)
- .order_by("year_released")
- )
- purchases = Purchase.objects.filter(editions__game=game).order_by("date_purchased")
+ purchases = game.purchases.order_by("date_purchased")
- sessions = Session.objects.prefetch_related("device").filter(
- purchase__editions__game=game
- )
+ sessions = game.sessions
session_count = sessions.count()
- session_count_without_manual = (
- Session.objects.without_manual().filter(purchase__editions__game=game).count()
- )
+ session_count_without_manual = game.sessions.without_manual().count()
if sessions:
playrange_start = local_strftime(sessions.earliest().timestamp_start, "%b %Y")
@@ -193,38 +184,6 @@ def view_game(request: HttpRequest, game_id: int) -> HttpResponse:
format_duration(sessions.calculated_duration_unformatted(), "%2.1H")
)
- edition_data: dict[str, Any] = {
- "columns": [
- "Name",
- "Year Released",
- "Actions",
- ],
- "rows": [
- [
- NameWithIcon(edition_id=edition.pk),
- edition.year_released,
- render_to_string(
- "cotton/button_group.html",
- {
- "buttons": [
- {
- "href": reverse("edit_edition", args=[edition.pk]),
- "slot": Icon("edit"),
- "color": "gray",
- },
- {
- "href": reverse("delete_edition", args=[edition.pk]),
- "slot": Icon("delete"),
- "color": "red",
- },
- ]
- },
- ),
- ]
- for edition in editions
- ],
- }
-
purchase_data: dict[str, Any] = {
"columns": ["Name", "Type", "Date", "Price", "Actions"],
"rows": [
@@ -255,9 +214,8 @@ def view_game(request: HttpRequest, game_id: int) -> HttpResponse:
],
}
- sessions_all = Session.objects.filter(purchase__editions__game=game).order_by(
- "-timestamp_start"
- )
+ sessions_all = game.sessions.order_by("-timestamp_start")
+
last_session = None
if sessions_all.exists():
last_session = sessions_all.latest()
@@ -284,7 +242,7 @@ def view_game(request: HttpRequest, game_id: int) -> HttpResponse:
args=[last_session.pk],
),
children=Popover(
- popover_content=last_session.purchase.first_edition.name,
+ popover_content=last_session.game.name,
children=[
Button(
icon=True,
@@ -292,9 +250,7 @@ def view_game(request: HttpRequest, game_id: int) -> HttpResponse:
size="xs",
children=[
Icon("play"),
- truncate(
- f"{last_session.purchase.first_edition.name}"
- ),
+ truncate(f"{last_session.game.name}"),
],
)
],
@@ -304,7 +260,7 @@ def view_game(request: HttpRequest, game_id: int) -> HttpResponse:
else "",
],
),
- "columns": ["Edition", "Date", "Duration", "Actions"],
+ "columns": ["Game", "Date", "Duration", "Actions"],
"rows": [
[
NameWithIcon(
@@ -354,11 +310,9 @@ def view_game(request: HttpRequest, game_id: int) -> HttpResponse:
}
context: dict[str, Any] = {
- "edition_count": editions.count(),
- "editions": editions,
"game": game,
"playrange": playrange,
- "purchase_count": Purchase.objects.filter(editions__game=game).count(),
+ "purchase_count": game.purchases.count(),
"session_average_without_manual": round(
safe_division(
total_hours_without_manual, int(session_count_without_manual)
@@ -369,7 +323,6 @@ def view_game(request: HttpRequest, game_id: int) -> HttpResponse:
"sessions": sessions,
"title": f"Game Overview - {game.name}",
"hours_sum": total_hours,
- "edition_data": edition_data,
"purchase_data": purchase_data,
"session_data": session_data,
"session_page_obj": session_page_obj,
diff --git a/games/views/general.py b/games/views/general.py
index 4834046..5607f98 100644
--- a/games/views/general.py
+++ b/games/views/general.py
@@ -11,13 +11,12 @@ from django.urls import reverse
from common.time import available_stats_year_range, dateformat, format_duration
from common.utils import safe_division
-from games.models import Edition, Game, Platform, Purchase, Session
+from games.models import Game, Platform, Purchase, Session
def model_counts(request: HttpRequest) -> dict[str, bool]:
return {
"game_available": Game.objects.exists(),
- "edition_available": Edition.objects.exists(),
"platform_available": Platform.objects.exists(),
"purchase_available": Purchase.objects.exists(),
"session_count": Session.objects.exists(),
@@ -49,9 +48,7 @@ def use_custom_redirect(
@login_required
def stats_alltime(request: HttpRequest) -> HttpResponse:
year = "Alltime"
- this_year_sessions = Session.objects.all().prefetch_related(
- Prefetch("purchase__editions")
- )
+ this_year_sessions = Session.objects.all().prefetch_related(Prefetch("game"))
this_year_sessions_with_durations = this_year_sessions.annotate(
duration=ExpressionWrapper(
F("timestamp_end") - F("timestamp_start"),
@@ -59,11 +56,9 @@ def stats_alltime(request: HttpRequest) -> HttpResponse:
)
)
longest_session = this_year_sessions_with_durations.order_by("-duration").first()
- this_year_games = Game.objects.filter(
- editions__purchase__session__in=this_year_sessions
- ).distinct()
+ this_year_games = Game.objects.filter(sessions__in=this_year_sessions).distinct()
this_year_games_with_session_counts = this_year_games.annotate(
- session_count=Count("editions__purchase__session"),
+ session_count=Count("sessions"),
)
game_highest_session_count = this_year_games_with_session_counts.order_by(
"-session_count"
@@ -76,11 +71,11 @@ def stats_alltime(request: HttpRequest) -> HttpResponse:
.aggregate(dates=Count("date"))
)
this_year_played_purchases = Purchase.objects.filter(
- session__in=this_year_sessions
+ games__sessions__in=this_year_sessions
).distinct()
this_year_purchases = Purchase.objects.all()
- this_year_purchases_with_currency = this_year_purchases.select_related("editions")
+ this_year_purchases_with_currency = this_year_purchases.select_related("games")
this_year_purchases_without_refunded = this_year_purchases_with_currency.filter(
date_refunded=None
)
@@ -129,11 +124,10 @@ def stats_alltime(request: HttpRequest) -> HttpResponse:
total_spent = this_year_spendings["total_spent"] or 0
games_with_playtime = (
- Game.objects.filter(editions__purchase__session__in=this_year_sessions)
+ Game.objects.filter(sessions__in=this_year_sessions)
.annotate(
total_playtime=Sum(
- F("editions__purchase__session__duration_calculated")
- + F("editions__purchase__session__duration_manual")
+ F("sessions__duration_calculated") + F("sessions__duration_manual")
)
)
.values("id", "name", "total_playtime")
@@ -148,10 +142,8 @@ def stats_alltime(request: HttpRequest) -> HttpResponse:
month["playtime"] = format_duration(month["playtime"], "%2.0H")
highest_session_average_game = (
- Game.objects.filter(editions__purchase__session__in=this_year_sessions)
- .annotate(
- session_average=Avg("editions__purchase__session__duration_calculated")
- )
+ Game.objects.filter(sessions__in=this_year_sessions)
+ .annotate(session_average=Avg("sessions__duration_calculated"))
.order_by("-session_average")
.first()
)
@@ -160,9 +152,9 @@ def stats_alltime(request: HttpRequest) -> HttpResponse:
game["formatted_playtime"] = format_duration(game["total_playtime"], "%2.0H")
total_playtime_per_platform = (
- this_year_sessions.values("purchase__platform__name")
+ this_year_sessions.values("game__platform__name")
.annotate(total_playtime=Sum(F("duration_calculated") + F("duration_manual")))
- .annotate(platform_name=F("purchase__platform__name"))
+ .annotate(platform_name=F("game__platform__name"))
.values("platform_name", "total_playtime")
.order_by("-total_playtime")
)
@@ -177,10 +169,10 @@ def stats_alltime(request: HttpRequest) -> HttpResponse:
last_play_date = "N/A"
if this_year_sessions:
first_session = this_year_sessions.earliest()
- first_play_game = first_session.purchase.first_edition.game
+ first_play_game = first_session.game
first_play_date = first_session.timestamp_start.strftime(dateformat)
last_session = this_year_sessions.latest()
- last_play_game = last_session.purchase.first_edition.game
+ last_play_game = last_session.game
last_play_date = last_session.timestamp_start.strftime(dateformat)
all_purchased_this_year_count = this_year_purchases_with_currency.count()
@@ -228,9 +220,7 @@ def stats_alltime(request: HttpRequest) -> HttpResponse:
if longest_session
else 0
),
- "longest_session_game": (
- longest_session.purchase.first_edition.game if longest_session else None
- ),
+ "longest_session_game": (longest_session.game if longest_session else None),
"highest_session_count": (
game_highest_session_count.session_count
if game_highest_session_count
@@ -268,7 +258,7 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
return HttpResponseRedirect(reverse("stats_alltime"))
this_year_sessions = Session.objects.filter(
timestamp_start__year=year
- ).prefetch_related("purchase__editions")
+ ).prefetch_related("game")
this_year_sessions_with_durations = this_year_sessions.annotate(
duration=ExpressionWrapper(
F("timestamp_end") - F("timestamp_start"),
@@ -276,13 +266,11 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
)
)
longest_session = this_year_sessions_with_durations.order_by("-duration").first()
- this_year_games = Game.objects.filter(
- edition__purchases__session__in=this_year_sessions
- ).distinct()
+ this_year_games = Game.objects.filter(sessions__in=this_year_sessions).distinct()
this_year_games_with_session_counts = this_year_games.annotate(
session_count=Count(
- "edition__purchases__session",
- filter=Q(edition__purchases__session__timestamp_start__year=year),
+ "sessions",
+ filter=Q(sessions__timestamp_start__year=year),
)
)
game_highest_session_count = this_year_games_with_session_counts.order_by(
@@ -296,11 +284,11 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
.aggregate(dates=Count("date"))
)
this_year_played_purchases = Purchase.objects.filter(
- session__in=this_year_sessions
+ games__sessions__in=this_year_sessions
).distinct()
this_year_purchases = Purchase.objects.filter(date_purchased__year=year)
- this_year_purchases_with_currency = this_year_purchases.prefetch_related("editions")
+ this_year_purchases_with_currency = this_year_purchases.prefetch_related("games")
this_year_purchases_without_refunded = this_year_purchases_with_currency.filter(
date_refunded=None
).exclude(ownership_type=Purchase.DEMO)
@@ -337,7 +325,7 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
purchases_finished_this_year = Purchase.objects.filter(date_finished__year=year)
purchases_finished_this_year_released_this_year = (
- purchases_finished_this_year.filter(editions__year_released=year).order_by(
+ purchases_finished_this_year.filter(games__year_released=year).order_by(
"date_finished"
)
)
@@ -351,11 +339,10 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
total_spent = this_year_spendings["total_spent"] or 0
games_with_playtime = (
- Game.objects.filter(edition__purchases__session__in=this_year_sessions)
+ Game.objects.filter(sessions__in=this_year_sessions)
.annotate(
total_playtime=Sum(
- F("edition__purchases__session__duration_calculated")
- + F("edition__purchases__session__duration_manual")
+ F("sessions__duration_calculated") + F("sessions__duration_manual")
)
)
.values("id", "name", "total_playtime")
@@ -370,10 +357,8 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
month["playtime"] = format_duration(month["playtime"], "%2.0H")
highest_session_average_game = (
- Game.objects.filter(edition__purchases__session__in=this_year_sessions)
- .annotate(
- session_average=Avg("edition__purchases__session__duration_calculated")
- )
+ Game.objects.filter(sessions__in=this_year_sessions)
+ .annotate(session_average=Avg("sessions__duration_calculated"))
.order_by("-session_average")
.first()
)
@@ -382,9 +367,9 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
game["formatted_playtime"] = format_duration(game["total_playtime"], "%2.0H")
total_playtime_per_platform = (
- this_year_sessions.values("purchase__platform__name")
+ this_year_sessions.values("game__platform__name")
.annotate(total_playtime=Sum(F("duration_calculated") + F("duration_manual")))
- .annotate(platform_name=F("purchase__platform__name"))
+ .annotate(platform_name=F("game__platform__name"))
.values("platform_name", "total_playtime")
.order_by("-total_playtime")
)
@@ -403,10 +388,10 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
last_play_game = None
if this_year_sessions:
first_session = this_year_sessions.earliest()
- first_play_game = first_session.purchase.first_edition.game
+ first_play_game = first_session.game
first_play_date = first_session.timestamp_start.strftime(dateformat)
last_session = this_year_sessions.latest()
- last_play_game = last_session.purchase.first_edition.game
+ last_play_game = last_session.game
last_play_date = last_session.timestamp_start.strftime(dateformat)
all_purchased_this_year_count = this_year_purchases_with_currency.count()
@@ -423,7 +408,7 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
),
"total_games": this_year_played_purchases.count(),
"total_2023_games": this_year_played_purchases.filter(
- editions__year_released=year
+ games__year_released=year
).count(),
"top_10_games_by_playtime": top_10_games_by_playtime,
"year": year,
@@ -435,15 +420,15 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
safe_division(total_spent, this_year_purchases_without_refunded_count)
),
"all_finished_this_year": purchases_finished_this_year.prefetch_related(
- "editions"
+ "games"
).order_by("date_finished"),
"all_finished_this_year_count": purchases_finished_this_year.count(),
"this_year_finished_this_year": purchases_finished_this_year_released_this_year.prefetch_related(
- "editions"
+ "games"
).order_by("date_finished"),
"this_year_finished_this_year_count": purchases_finished_this_year_released_this_year.count(),
"purchased_this_year_finished_this_year": purchased_this_year_finished_this_year.prefetch_related(
- "editions"
+ "games"
).order_by("date_finished"),
"total_sessions": this_year_sessions.count(),
"unique_days": unique_days["dates"],
@@ -472,9 +457,7 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse:
if longest_session
else 0
),
- "longest_session_game": (
- longest_session.purchase.first_edition.game if longest_session else None
- ),
+ "longest_session_game": (longest_session.game if longest_session else None),
"highest_session_count": (
game_highest_session_count.session_count
if game_highest_session_count
diff --git a/games/views/purchase.py b/games/views/purchase.py
index daa6424..c7962b7 100644
--- a/games/views/purchase.py
+++ b/games/views/purchase.py
@@ -16,7 +16,7 @@ from django.utils import timezone
from common.components import A, Button, Icon, LinkedPurchase, PurchasePrice
from common.time import dateformat
from games.forms import PurchaseForm
-from games.models import Edition, Purchase
+from games.models import Game, Purchase
from games.views.general import use_custom_redirect
@@ -138,7 +138,7 @@ def list_purchases(request: HttpRequest) -> HttpResponse:
@login_required
-def add_purchase(request: HttpRequest, edition_id: int = 0) -> HttpResponse:
+def add_purchase(request: HttpRequest, game_id: int = 0) -> HttpResponse:
context: dict[str, Any] = {}
initial = {"date_purchased": timezone.now()}
@@ -149,19 +149,20 @@ def add_purchase(request: HttpRequest, edition_id: int = 0) -> HttpResponse:
if "submit_and_redirect" in request.POST:
return HttpResponseRedirect(
reverse(
- "add_session_for_purchase", kwargs={"purchase_id": purchase.id}
+ "add_session_for_game",
+ kwargs={"game_id": purchase.first_game.id},
)
)
else:
return redirect("list_purchases")
else:
- if edition_id:
- edition = Edition.objects.get(id=edition_id)
+ if game_id:
+ game = Game.objects.get(id=game_id)
form = PurchaseForm(
initial={
**initial,
- "edition": edition,
- "platform": edition.platform,
+ "games": [game],
+ "platform": game.platform,
}
)
else:
@@ -226,12 +227,14 @@ def finish_purchase(request: HttpRequest, purchase_id: int) -> HttpResponse:
return redirect("list_purchases")
-def related_purchase_by_edition(request: HttpRequest) -> HttpResponse:
- edition_id = request.GET.get("edition")
- if not edition_id:
- return HttpResponseBadRequest("Invalid edition_id")
+def related_purchase_by_game(request: HttpRequest) -> HttpResponse:
+ games = request.GET.getlist("games")
+ if not games:
+ return HttpResponseBadRequest("Invalid game_id")
+ if isinstance(games, int) or isinstance(games, str):
+ games = [games]
form = PurchaseForm()
form.fields["related_purchase"].queryset = Purchase.objects.filter(
- edition_id=edition_id, type=Purchase.GAME
- ).order_by("edition__sort_name")
+ games__in=games, type=Purchase.GAME
+ ).order_by("games__sort_name")
return render(request, "partials/related_purchase_field.html", {"form": form})
diff --git a/games/views/session.py b/games/views/session.py
index b84e032..6f2f107 100644
--- a/games/views/session.py
+++ b/games/views/session.py
@@ -28,7 +28,7 @@ from common.time import (
)
from common.utils import truncate
from games.forms import SessionForm
-from games.models import Purchase, Session
+from games.models import Game, Session
from games.views.general import use_custom_redirect
@@ -37,13 +37,13 @@ def list_sessions(request: HttpRequest, search_string: str = "") -> HttpResponse
context: dict[Any, Any] = {}
page_number = request.GET.get("page", 1)
limit = request.GET.get("limit", 10)
- sessions = Session.objects.order_by("-timestamp_start")
+ sessions = Session.objects.order_by("-timestamp_start", "created_at")
search_string = request.GET.get("search_string", search_string)
if search_string != "":
sessions = sessions.filter(
- Q(purchase__edition__name__icontains=search_string)
- | Q(purchase__edition__game__name__icontains=search_string)
- | Q(purchase__platform__name__icontains=search_string)
+ Q(game__name__icontains=search_string)
+ | Q(game__name__icontains=search_string)
+ | Q(game__platform__name__icontains=search_string)
| Q(device__name__icontains=search_string)
| Q(device__type__icontains=search_string)
)
@@ -97,7 +97,7 @@ def list_sessions(request: HttpRequest, search_string: str = "") -> HttpResponse
args=[last_session.pk],
),
children=Popover(
- popover_content=last_session.purchase.first_edition.name,
+ popover_content=last_session.game.name,
children=[
Button(
icon=True,
@@ -105,9 +105,7 @@ def list_sessions(request: HttpRequest, search_string: str = "") -> HttpResponse
size="xs",
children=[
Icon("play"),
- truncate(
- f"{last_session.purchase.first_edition.name}"
- ),
+ truncate(f"{last_session.game.name}"),
],
)
],
@@ -191,13 +189,13 @@ def search_sessions(request: HttpRequest) -> HttpResponse:
@login_required
-def add_session(request: HttpRequest, purchase_id: int = 0) -> HttpResponse:
+def add_session(request: HttpRequest, game_id: int = 0) -> HttpResponse:
context = {}
initial: dict[str, Any] = {"timestamp_start": timezone.now()}
last = Session.objects.last()
if last != None:
- initial["purchase"] = last.purchase
+ initial["game"] = last.game
if request.method == "POST":
form = SessionForm(request.POST or None, initial=initial)
@@ -205,12 +203,12 @@ def add_session(request: HttpRequest, purchase_id: int = 0) -> HttpResponse:
form.save()
return redirect("list_sessions")
else:
- if purchase_id:
- purchase = Purchase.objects.get(id=purchase_id)
+ if game_id:
+ game = Game.objects.get(id=game_id)
form = SessionForm(
initial={
**initial,
- "purchase": purchase,
+ "game": game,
}
)
else:
diff --git a/tests/test_paths_return_200.py b/tests/test_paths_return_200.py
index 08bfd53..a4927a0 100644
--- a/tests/test_paths_return_200.py
+++ b/tests/test_paths_return_200.py
@@ -10,7 +10,7 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "timetracker.settings")
django.setup()
from django.conf import settings
-from games.models import Edition, Game, Platform, Purchase, Session
+from games.models import Game, Platform, Purchase, Session
ZONEINFO = ZoneInfo(settings.TIME_ZONE)
@@ -21,10 +21,8 @@ class PathWorksTest(TestCase):
pl.save()
g = Game(name="The Test Game")
g.save()
- e = Edition(game=g, name="The Test Game Edition", platform=pl)
- e.save()
p = Purchase(
- edition=e,
+ games=[e],
platform=pl,
date_purchased=datetime(2022, 9, 26, 14, 58, tzinfo=ZONEINFO),
)
@@ -53,11 +51,6 @@ class PathWorksTest(TestCase):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
- def test_add_edition_returns_200(self):
- url = reverse("add_edition")
- response = self.client.get(url)
- self.assertEqual(response.status_code, 200)
-
def test_add_purchase_returns_200(self):
url = reverse("add_purchase")
response = self.client.get(url)
diff --git a/tests/test_session_formatting.py b/tests/test_session_formatting.py
index 4bc345e..df4de41 100644
--- a/tests/test_session_formatting.py
+++ b/tests/test_session_formatting.py
@@ -3,14 +3,13 @@ from datetime import datetime
from zoneinfo import ZoneInfo
import django
-from django.db import models
from django.test import TestCase
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "timetracker.settings")
django.setup()
from django.conf import settings
-from games.models import Edition, Game, Purchase, Session
+from games.models import Game, Purchase, Session
ZONEINFO = ZoneInfo(settings.TIME_ZONE)
@@ -22,10 +21,8 @@ class FormatDurationTest(TestCase):
def test_duration_format(self):
g = Game(name="The Test Game")
g.save()
- e = Edition(game=g, name="The Test Game Edition")
- e.save()
p = Purchase(
- edition=e, date_purchased=datetime(2022, 9, 26, 14, 58, tzinfo=ZONEINFO)
+ game=g, date_purchased=datetime(2022, 9, 26, 14, 58, tzinfo=ZONEINFO)
)
p.save()
s = Session(