Compare commits
4 Commits
b0be7b5887
...
394dd4f9f8
Author | SHA1 | Date |
---|---|---|
Lukáš Kucharczyk | 394dd4f9f8 | |
Lukáš Kucharczyk | c358b1aaa0 | |
Lukáš Kucharczyk | 1bc3ca057b | |
Lukáš Kucharczyk | c2c0886451 |
|
@ -1,4 +1,4 @@
|
||||||
## Unreleased
|
## 1.4.0 / 2023-11-09 21:01+01:00
|
||||||
|
|
||||||
### New
|
### New
|
||||||
* More fields are now optional. This is to make it easier to add new items in bulk.
|
* More fields are now optional. This is to make it easier to add new items in bulk.
|
||||||
|
@ -22,6 +22,9 @@
|
||||||
* Finished (count)
|
* Finished (count)
|
||||||
* Unfinished (count)
|
* Unfinished (count)
|
||||||
* Refunded (count)
|
* Refunded (count)
|
||||||
|
* Backlog Decrease (count)
|
||||||
|
* New workflow:
|
||||||
|
* Adding Game, Edition, Purchase, and Session in a row is now much faster
|
||||||
|
|
||||||
### Improved
|
### Improved
|
||||||
* game overview: simplify playtime range display
|
* game overview: simplify playtime range display
|
||||||
|
|
|
@ -6,7 +6,7 @@ RUN npm install && \
|
||||||
|
|
||||||
FROM python:3.10.9-slim-bullseye
|
FROM python:3.10.9-slim-bullseye
|
||||||
|
|
||||||
ENV VERSION_NUMBER 1.3.0
|
ENV VERSION_NUMBER 1.4.0
|
||||||
ENV PROD 1
|
ENV PROD 1
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}{{ title }}{% endblock title %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
<table class="mx-auto">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
{{ form.as_table }}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td><input type="submit" name="submit" value="Submit"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td><input type="submit" name="submit_and_redirect" value="Submit & Create Purchase"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{% if script_name %}
|
||||||
|
<script type="module" src="{% static 'js/'|add:script_name %}"></script>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock scripts %}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}{{ title }}{% endblock title %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
<table class="mx-auto">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
{{ form.as_table }}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td><input type="submit" name="submit" value="Submit"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td><input type="submit" name="submit_and_redirect" value="Submit & Create Edition"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{% if script_name %}
|
||||||
|
<script type="module" src="{% static 'js/'|add:script_name %}"></script>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock scripts %}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}{{ title }}{% endblock title %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
<table class="mx-auto">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
{{ form.as_table }}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td><input type="submit" name="submit" value="Submit"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td><input type="submit" name="submit_and_redirect" value="Submit & Create Session"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{% if script_name %}
|
||||||
|
<script type="module" src="{% static 'js/'|add:script_name %}"></script>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock scripts %}
|
||||||
|
|
|
@ -64,6 +64,10 @@
|
||||||
<td class="px-2 sm:px-4 md:px-6 md:py-2">Unfinished</td>
|
<td class="px-2 sm:px-4 md:px-6 md:py-2">Unfinished</td>
|
||||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchased_unfinished.count }} ({{ unfinished_purchases_percent }}%)</td>
|
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchased_unfinished.count }} ({{ unfinished_purchases_percent }}%)</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="px-2 sm:px-4 md:px-6 md:py-2">Backlog Decrease</td>
|
||||||
|
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ backlog_decrease_count }}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="px-2 sm:px-4 md:px-6 md:py-2">Spendings ({{ total_spent_currency }})</td>
|
<td class="px-2 sm:px-4 md:px-6 md:py-2">Spendings ({{ total_spent_currency }})</td>
|
||||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ total_spent }} ({{ spent_per_game }}/game)</td>
|
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ total_spent }} ({{ spent_per_game }}/game)</td>
|
||||||
|
|
|
@ -11,8 +11,14 @@ urlpatterns = [
|
||||||
name="list_sessions_recent",
|
name="list_sessions_recent",
|
||||||
),
|
),
|
||||||
path("add-game/", views.add_game, name="add_game"),
|
path("add-game/", views.add_game, name="add_game"),
|
||||||
|
path("add-game-unified/", views.add_game_unified, name="add_game_unified"),
|
||||||
path("add-platform/", views.add_platform, name="add_platform"),
|
path("add-platform/", views.add_platform, name="add_platform"),
|
||||||
path("add-session/", views.add_session, name="add_session"),
|
path("add-session/", views.add_session, name="add_session"),
|
||||||
|
path(
|
||||||
|
"add-session-for-purchase/<int:purchase_id>",
|
||||||
|
views.add_session,
|
||||||
|
name="add_session_for_purchase",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"update-session/by-session/<int:session_id>",
|
"update-session/by-session/<int:session_id>",
|
||||||
views.update_session,
|
views.update_session,
|
||||||
|
@ -34,7 +40,17 @@ urlpatterns = [
|
||||||
# name="delete_session",
|
# name="delete_session",
|
||||||
# ),
|
# ),
|
||||||
path("add-purchase/", views.add_purchase, name="add_purchase"),
|
path("add-purchase/", views.add_purchase, name="add_purchase"),
|
||||||
|
path(
|
||||||
|
"add-purchase-for-edition/<int:edition_id>",
|
||||||
|
views.add_purchase,
|
||||||
|
name="add_purchase_for_edition",
|
||||||
|
),
|
||||||
path("add-edition/", views.add_edition, name="add_edition"),
|
path("add-edition/", views.add_edition, name="add_edition"),
|
||||||
|
path(
|
||||||
|
"add-edition-for-game/<int:game_id>",
|
||||||
|
views.add_edition,
|
||||||
|
name="add_edition_for_game",
|
||||||
|
),
|
||||||
path("edit-edition/<int:edition_id>", views.edit_edition, name="edit_edition"),
|
path("edit-edition/<int:edition_id>", views.edit_edition, name="edit_edition"),
|
||||||
path("game/<int:game_id>/view", views.view_game, name="view_game"),
|
path("game/<int:game_id>/view", views.view_game, name="view_game"),
|
||||||
path("game/<int:game_id>/edit", views.edit_game, name="edit_game"),
|
path("game/<int:game_id>/edit", views.edit_game, name="edit_game"),
|
||||||
|
|
195
games/views.py
195
games/views.py
|
@ -35,21 +35,30 @@ def stats_dropdown_year_range(request):
|
||||||
return {"stats_dropdown_year_range": range(2018, 2024)}
|
return {"stats_dropdown_year_range": range(2018, 2024)}
|
||||||
|
|
||||||
|
|
||||||
def add_session(request):
|
def add_session(request, purchase_id=None):
|
||||||
context = {}
|
context = {}
|
||||||
initial = {}
|
initial = {"timestamp_start": now_with_tz()}
|
||||||
|
|
||||||
now = now_with_tz()
|
|
||||||
initial["timestamp_start"] = now
|
|
||||||
|
|
||||||
last = Session.objects.all().last()
|
last = Session.objects.all().last()
|
||||||
if last != None:
|
if last != None:
|
||||||
initial["purchase"] = last.purchase
|
initial["purchase"] = last.purchase
|
||||||
|
|
||||||
form = SessionForm(request.POST or None, initial=initial)
|
if request.method == "POST":
|
||||||
if form.is_valid():
|
form = SessionForm(request.POST or None, initial=initial)
|
||||||
form.save()
|
if form.is_valid():
|
||||||
return redirect("list_sessions")
|
form.save()
|
||||||
|
return redirect("list_sessions")
|
||||||
|
else:
|
||||||
|
if purchase_id:
|
||||||
|
purchase = Purchase.objects.get(id=purchase_id)
|
||||||
|
form = SessionForm(
|
||||||
|
initial={
|
||||||
|
**initial,
|
||||||
|
"purchase": purchase,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
form = SessionForm(initial=initial)
|
||||||
|
|
||||||
context["title"] = "Add New Session"
|
context["title"] = "Add New Session"
|
||||||
context["form"] = form
|
context["form"] = form
|
||||||
|
@ -275,65 +284,57 @@ def stats(request, year: int = 0):
|
||||||
return HttpResponseRedirect(reverse("stats_by_year", args=[selected_year]))
|
return HttpResponseRedirect(reverse("stats_by_year", args=[selected_year]))
|
||||||
if year == 0:
|
if year == 0:
|
||||||
year = now_with_tz().year
|
year = now_with_tz().year
|
||||||
first_day_of_year = datetime(year, 1, 1)
|
this_year_sessions = Session.objects.filter(timestamp_start__year=year)
|
||||||
last_day_of_year = datetime(year + 1, 1, 1)
|
selected_currency = "CZK"
|
||||||
year_sessions = Session.objects.filter(timestamp_start__year=year)
|
|
||||||
unique_days = (
|
unique_days = (
|
||||||
year_sessions.annotate(date=TruncDate("timestamp_start"))
|
this_year_sessions.annotate(date=TruncDate("timestamp_start"))
|
||||||
.values("date")
|
.values("date")
|
||||||
.distinct()
|
.distinct()
|
||||||
.aggregate(dates=Count("date"))
|
.aggregate(dates=Count("date"))
|
||||||
)
|
)
|
||||||
year_played_purchases = Purchase.objects.filter(
|
this_year_played_purchases = Purchase.objects.filter(
|
||||||
session__in=year_sessions
|
session__in=this_year_sessions
|
||||||
).distinct()
|
).distinct()
|
||||||
|
|
||||||
selected_currency = "CZK"
|
this_year_purchases = Purchase.objects.filter(date_purchased__year=year)
|
||||||
all_purchased_this_year = (
|
this_year_purchases_with_currency = this_year_purchases.filter(
|
||||||
Purchase.objects.filter(date_purchased__year=year)
|
price_currency__exact=selected_currency
|
||||||
.filter(price_currency__exact=selected_currency)
|
|
||||||
.order_by("date_purchased")
|
|
||||||
)
|
)
|
||||||
all_purchased_without_refunded_this_year = all_purchased_this_year.not_refunded()
|
this_year_purchases_without_refunded = this_year_purchases_with_currency.filter(
|
||||||
all_purchased_refunded_this_year = (
|
date_refunded=None
|
||||||
Purchase.objects.filter(date_purchased__year=year)
|
|
||||||
.filter(price_currency__exact=selected_currency)
|
|
||||||
.refunded()
|
|
||||||
.order_by("date_purchased")
|
|
||||||
)
|
)
|
||||||
|
this_year_purchases_refunded = this_year_purchases_with_currency.refunded()
|
||||||
|
|
||||||
purchased_unfinished = all_purchased_without_refunded_this_year.filter(
|
this_year_purchases_unfinished = this_year_purchases_without_refunded.filter(
|
||||||
date_finished__isnull=True
|
date_finished__isnull=True
|
||||||
)
|
)
|
||||||
|
|
||||||
unfinished_purchases_percent = int(
|
this_year_purchases_unfinished_percent = int(
|
||||||
safe_division(
|
safe_division(
|
||||||
purchased_unfinished.count(), all_purchased_refunded_this_year.count()
|
this_year_purchases_unfinished.count(), this_year_purchases_refunded.count()
|
||||||
)
|
)
|
||||||
* 100
|
* 100
|
||||||
)
|
)
|
||||||
|
|
||||||
all_finished_this_year = Purchase.objects.filter(date_finished__year=year).order_by(
|
purchases_finished_this_year = Purchase.objects.filter(date_finished__year=year)
|
||||||
"date_finished"
|
purchases_finished_this_year_released_this_year = (
|
||||||
)
|
purchases_finished_this_year.filter(edition__year_released=year).order_by(
|
||||||
this_year_finished_this_year = (
|
"date_finished"
|
||||||
Purchase.objects.filter(date_finished__year=year)
|
)
|
||||||
.filter(edition__year_released=year)
|
|
||||||
.order_by("date_finished")
|
|
||||||
)
|
)
|
||||||
purchased_this_year_finished_this_year = (
|
purchased_this_year_finished_this_year = (
|
||||||
all_purchased_without_refunded_this_year.filter(
|
this_year_purchases_without_refunded.intersection(
|
||||||
date_finished__year=year
|
purchases_finished_this_year
|
||||||
).order_by("date_finished")
|
).order_by("date_finished")
|
||||||
)
|
)
|
||||||
|
|
||||||
this_year_spendings = all_purchased_without_refunded_this_year.aggregate(
|
this_year_spendings = this_year_purchases_without_refunded.aggregate(
|
||||||
total_spent=Sum(F("price"))
|
total_spent=Sum(F("price"))
|
||||||
)
|
)
|
||||||
total_spent = this_year_spendings["total_spent"]
|
total_spent = this_year_spendings["total_spent"]
|
||||||
|
|
||||||
games_with_playtime = (
|
games_with_playtime = (
|
||||||
Game.objects.filter(edition__purchase__session__in=year_sessions)
|
Game.objects.filter(edition__purchase__session__in=this_year_sessions)
|
||||||
.annotate(
|
.annotate(
|
||||||
total_playtime=Sum(
|
total_playtime=Sum(
|
||||||
F("edition__purchase__session__duration_calculated")
|
F("edition__purchase__session__duration_calculated")
|
||||||
|
@ -347,7 +348,7 @@ def stats(request, year: int = 0):
|
||||||
game["formatted_playtime"] = format_duration(game["total_playtime"], "%2.0H")
|
game["formatted_playtime"] = format_duration(game["total_playtime"], "%2.0H")
|
||||||
|
|
||||||
total_playtime_per_platform = (
|
total_playtime_per_platform = (
|
||||||
year_sessions.values("purchase__platform__name")
|
this_year_sessions.values("purchase__platform__name")
|
||||||
.annotate(total_playtime=Sum(F("duration_calculated") + F("duration_manual")))
|
.annotate(total_playtime=Sum(F("duration_calculated") + F("duration_manual")))
|
||||||
.annotate(platform_name=F("purchase__platform__name"))
|
.annotate(platform_name=F("purchase__platform__name"))
|
||||||
.values("platform_name", "total_playtime")
|
.values("platform_name", "total_playtime")
|
||||||
|
@ -356,12 +357,18 @@ def stats(request, year: int = 0):
|
||||||
for item in total_playtime_per_platform:
|
for item in total_playtime_per_platform:
|
||||||
item["formatted_playtime"] = format_duration(item["total_playtime"], "%2.0H")
|
item["formatted_playtime"] = format_duration(item["total_playtime"], "%2.0H")
|
||||||
|
|
||||||
|
backlog_decrease_count = (
|
||||||
|
Purchase.objects.filter(date_purchased__year__lt=year)
|
||||||
|
.intersection(purchases_finished_this_year)
|
||||||
|
.count()
|
||||||
|
)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"total_hours": format_duration(
|
"total_hours": format_duration(
|
||||||
year_sessions.total_duration_unformatted(), "%2.0H"
|
this_year_sessions.total_duration_unformatted(), "%2.0H"
|
||||||
),
|
),
|
||||||
"total_games": year_played_purchases.count(),
|
"total_games": this_year_played_purchases.count(),
|
||||||
"total_2023_games": year_played_purchases.filter(
|
"total_2023_games": this_year_played_purchases.filter(
|
||||||
edition__year_released=year
|
edition__year_released=year
|
||||||
).count(),
|
).count(),
|
||||||
"top_10_games_by_playtime": top_10_games_by_playtime,
|
"top_10_games_by_playtime": top_10_games_by_playtime,
|
||||||
|
@ -369,72 +376,116 @@ def stats(request, year: int = 0):
|
||||||
"total_playtime_per_platform": total_playtime_per_platform,
|
"total_playtime_per_platform": total_playtime_per_platform,
|
||||||
"total_spent": total_spent,
|
"total_spent": total_spent,
|
||||||
"total_spent_currency": selected_currency,
|
"total_spent_currency": selected_currency,
|
||||||
"all_purchased_this_year": all_purchased_without_refunded_this_year,
|
"all_purchased_this_year": this_year_purchases_without_refunded,
|
||||||
"spent_per_game": int(
|
"spent_per_game": int(
|
||||||
safe_division(total_spent, all_purchased_without_refunded_this_year.count())
|
safe_division(total_spent, this_year_purchases_without_refunded.count())
|
||||||
),
|
),
|
||||||
"all_finished_this_year": all_finished_this_year,
|
"all_finished_this_year": purchases_finished_this_year,
|
||||||
"this_year_finished_this_year": this_year_finished_this_year,
|
"this_year_finished_this_year": purchases_finished_this_year_released_this_year,
|
||||||
"purchased_this_year_finished_this_year": purchased_this_year_finished_this_year,
|
"purchased_this_year_finished_this_year": purchased_this_year_finished_this_year,
|
||||||
"total_sessions": year_sessions.count(),
|
"total_sessions": this_year_sessions.count(),
|
||||||
"unique_days": unique_days["dates"],
|
"unique_days": unique_days["dates"],
|
||||||
"unique_days_percent": int(unique_days["dates"] / 365 * 100),
|
"unique_days_percent": int(unique_days["dates"] / 365 * 100),
|
||||||
"purchased_unfinished": purchased_unfinished,
|
"purchased_unfinished": this_year_purchases_unfinished,
|
||||||
"unfinished_purchases_percent": unfinished_purchases_percent,
|
"unfinished_purchases_percent": this_year_purchases_unfinished_percent,
|
||||||
"refunded_percent": int(
|
"refunded_percent": int(
|
||||||
safe_division(
|
safe_division(
|
||||||
all_purchased_refunded_this_year.count(),
|
this_year_purchases_refunded.count(),
|
||||||
all_purchased_this_year.count(),
|
this_year_purchases_with_currency.count(),
|
||||||
)
|
)
|
||||||
* 100
|
* 100
|
||||||
),
|
),
|
||||||
"all_purchased_refunded_this_year": all_purchased_refunded_this_year,
|
"all_purchased_refunded_this_year": this_year_purchases_refunded,
|
||||||
"all_purchased_this_year": all_purchased_this_year,
|
"all_purchased_this_year": this_year_purchases_with_currency.order_by(
|
||||||
|
"date_purchased"
|
||||||
|
),
|
||||||
|
"backlog_decrease_count": backlog_decrease_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
request.session["return_path"] = request.path
|
request.session["return_path"] = request.path
|
||||||
return render(request, "stats.html", context)
|
return render(request, "stats.html", context)
|
||||||
|
|
||||||
|
|
||||||
def add_purchase(request):
|
def add_purchase(request, edition_id=None):
|
||||||
context = {}
|
context = {}
|
||||||
now = datetime.now()
|
initial = {"date_purchased": now_with_tz()}
|
||||||
initial = {"date_purchased": now}
|
|
||||||
form = PurchaseForm(request.POST or None, initial=initial)
|
if request.method == "POST":
|
||||||
if form.is_valid():
|
form = PurchaseForm(request.POST or None, initial=initial)
|
||||||
form.save()
|
if form.is_valid():
|
||||||
return redirect("index")
|
purchase = form.save()
|
||||||
|
if "submit_and_redirect" in request.POST:
|
||||||
|
return HttpResponseRedirect(
|
||||||
|
reverse(
|
||||||
|
"add_session_for_purchase", kwargs={"purchase_id": purchase.id}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return redirect("index")
|
||||||
|
else:
|
||||||
|
if edition_id:
|
||||||
|
edition = Edition.objects.get(id=edition_id)
|
||||||
|
form = PurchaseForm(
|
||||||
|
initial={
|
||||||
|
**initial,
|
||||||
|
"edition": edition,
|
||||||
|
"platform": edition.platform,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
form = PurchaseForm(initial=initial)
|
||||||
|
|
||||||
context["form"] = form
|
context["form"] = form
|
||||||
context["title"] = "Add New Purchase"
|
context["title"] = "Add New Purchase"
|
||||||
context["script_name"] = "add_purchase.js"
|
context["script_name"] = "add_purchase.js"
|
||||||
return render(request, "add.html", context)
|
return render(request, "add_purchase.html", context)
|
||||||
|
|
||||||
|
|
||||||
def add_game(request):
|
def add_game(request):
|
||||||
context = {}
|
context = {}
|
||||||
form = GameForm(request.POST or None)
|
form = GameForm(request.POST or None)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
game = form.save()
|
||||||
return redirect("index")
|
if "submit_and_redirect" in request.POST:
|
||||||
|
return HttpResponseRedirect(
|
||||||
|
reverse("add_edition_for_game", kwargs={"game_id": game.id})
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return redirect("index")
|
||||||
|
|
||||||
context["form"] = form
|
context["form"] = form
|
||||||
context["title"] = "Add New Game"
|
context["title"] = "Add New Game"
|
||||||
context["script_name"] = "add_game.js"
|
context["script_name"] = "add_game.js"
|
||||||
return render(request, "add.html", context)
|
return render(request, "add_game.html", context)
|
||||||
|
|
||||||
|
|
||||||
def add_edition(request):
|
def add_edition(request, game_id=None):
|
||||||
context = {}
|
context = {}
|
||||||
form = EditionForm(request.POST or None)
|
if request.method == "POST":
|
||||||
if form.is_valid():
|
form = EditionForm(request.POST or None)
|
||||||
form.save()
|
if form.is_valid():
|
||||||
return redirect("index")
|
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 = Game.objects.get(id=game_id)
|
||||||
|
form = EditionForm(
|
||||||
|
initial={"game": game, "name": game.name, "sort_name": game.sort_name}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
form = EditionForm()
|
||||||
|
|
||||||
context["form"] = form
|
context["form"] = form
|
||||||
context["title"] = "Add New Edition"
|
context["title"] = "Add New Edition"
|
||||||
context["script_name"] = "add_edition.js"
|
context["script_name"] = "add_edition.js"
|
||||||
return render(request, "add.html", context)
|
return render(request, "add_edition.html", context)
|
||||||
|
|
||||||
|
|
||||||
def add_platform(request):
|
def add_platform(request):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "timetracker"
|
name = "timetracker"
|
||||||
version = "1.3.0"
|
version = "1.4.0"
|
||||||
description = "A simple time tracker."
|
description = "A simple time tracker."
|
||||||
authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"]
|
authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"]
|
||||||
license = "GPL"
|
license = "GPL"
|
||||||
|
|
Loading…
Reference in New Issue