2024-08-08 18:17:43 +00:00
|
|
|
from typing import Any
|
|
|
|
|
|
|
|
from django.contrib.auth.decorators import login_required
|
2024-08-08 20:54:15 +00:00
|
|
|
from django.core.paginator import Paginator
|
2024-08-12 19:42:34 +00:00
|
|
|
from django.http import (
|
|
|
|
HttpRequest,
|
|
|
|
HttpResponse,
|
|
|
|
HttpResponseBadRequest,
|
|
|
|
HttpResponseRedirect,
|
|
|
|
)
|
|
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
2024-08-08 18:17:43 +00:00
|
|
|
from django.template.loader import render_to_string
|
|
|
|
from django.urls import reverse
|
2024-08-12 19:42:34 +00:00
|
|
|
from django.utils import timezone
|
2024-08-08 18:17:43 +00:00
|
|
|
|
2024-09-08 19:03:37 +00:00
|
|
|
from common.components import A, Button, Icon
|
|
|
|
from common.time import dateformat
|
|
|
|
from common.utils import truncate_with_popover
|
2024-08-12 19:42:34 +00:00
|
|
|
from games.forms import PurchaseForm
|
|
|
|
from games.models import Edition, Purchase
|
2024-09-04 19:55:22 +00:00
|
|
|
from games.views.general import use_custom_redirect
|
2024-08-08 18:17:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def list_purchases(request: HttpRequest) -> HttpResponse:
|
|
|
|
context: dict[Any, Any] = {}
|
2024-08-08 20:54:15 +00:00
|
|
|
page_number = request.GET.get("page", 1)
|
2024-08-09 10:23:22 +00:00
|
|
|
limit = request.GET.get("limit", 10)
|
|
|
|
purchases = Purchase.objects.order_by("-date_purchased")
|
|
|
|
page_obj = None
|
|
|
|
if int(limit) != 0:
|
2024-08-09 11:59:14 +00:00
|
|
|
paginator = Paginator(purchases, limit)
|
2024-08-09 10:23:22 +00:00
|
|
|
page_obj = paginator.get_page(page_number)
|
|
|
|
purchases = page_obj.object_list
|
|
|
|
|
2024-08-08 18:17:43 +00:00
|
|
|
context = {
|
|
|
|
"title": "Manage purchases",
|
2024-08-09 10:23:22 +00:00
|
|
|
"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
|
2024-08-08 20:54:15 +00:00
|
|
|
),
|
2024-08-08 18:17:43 +00:00
|
|
|
"data": {
|
2024-09-03 13:25:14 +00:00
|
|
|
"header_action": A([], Button([], "Add purchase"), url="add_purchase"),
|
2024-08-08 18:17:43 +00:00
|
|
|
"columns": [
|
|
|
|
"Name",
|
2024-09-02 21:52:28 +00:00
|
|
|
"Type",
|
2024-08-08 18:17:43 +00:00
|
|
|
"Platform",
|
|
|
|
"Price",
|
|
|
|
"Currency",
|
|
|
|
"Infinite",
|
|
|
|
"Purchased",
|
|
|
|
"Refunded",
|
|
|
|
"Finished",
|
|
|
|
"Dropped",
|
|
|
|
"Created",
|
|
|
|
"Actions",
|
|
|
|
],
|
|
|
|
"rows": [
|
|
|
|
[
|
2024-09-02 18:04:21 +00:00
|
|
|
A(
|
|
|
|
[
|
|
|
|
(
|
|
|
|
"href",
|
|
|
|
reverse(
|
|
|
|
"view_game",
|
|
|
|
args=[purchase.edition.game.pk],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
2024-09-02 21:52:28 +00:00
|
|
|
truncate_with_popover(
|
|
|
|
purchase.edition.game.name
|
|
|
|
if purchase.type == "game"
|
|
|
|
else f"{purchase.edition.game.name} ({purchase.name})"
|
|
|
|
),
|
2024-09-02 18:04:21 +00:00
|
|
|
),
|
2024-09-02 21:52:28 +00:00
|
|
|
purchase.get_type_display(),
|
2024-08-08 18:17:43 +00:00
|
|
|
purchase.platform,
|
|
|
|
purchase.price,
|
|
|
|
purchase.price_currency,
|
|
|
|
purchase.infinite,
|
2024-09-08 19:03:37 +00:00
|
|
|
purchase.date_purchased.strftime(dateformat),
|
2024-08-08 18:17:43 +00:00
|
|
|
(
|
2024-09-08 19:03:37 +00:00
|
|
|
purchase.date_refunded.strftime(dateformat)
|
2024-08-08 18:17:43 +00:00
|
|
|
if purchase.date_refunded
|
|
|
|
else "-"
|
|
|
|
),
|
|
|
|
(
|
2024-09-08 19:03:37 +00:00
|
|
|
purchase.date_finished.strftime(dateformat)
|
2024-08-08 18:17:43 +00:00
|
|
|
if purchase.date_finished
|
|
|
|
else "-"
|
|
|
|
),
|
|
|
|
(
|
2024-09-08 19:03:37 +00:00
|
|
|
purchase.date_dropped.strftime(dateformat)
|
2024-08-08 18:17:43 +00:00
|
|
|
if purchase.date_dropped
|
|
|
|
else "-"
|
|
|
|
),
|
2024-09-08 19:03:37 +00:00
|
|
|
purchase.created_at.strftime(dateformat),
|
2024-08-08 18:17:43 +00:00
|
|
|
render_to_string(
|
2024-09-08 19:03:37 +00:00
|
|
|
"cotton/button_group.html",
|
2024-08-08 18:17:43 +00:00
|
|
|
{
|
|
|
|
"buttons": [
|
2024-09-10 13:04:18 +00:00
|
|
|
{
|
|
|
|
"href": reverse(
|
|
|
|
"finish_purchase", args=[purchase.pk]
|
|
|
|
),
|
|
|
|
"slot": Icon("checkmark"),
|
|
|
|
"title": "Mark as finished",
|
|
|
|
}
|
|
|
|
if not purchase.date_finished
|
|
|
|
else {},
|
2024-09-10 12:46:50 +00:00
|
|
|
{
|
|
|
|
"href": reverse(
|
|
|
|
"drop_purchase", args=[purchase.pk]
|
|
|
|
),
|
|
|
|
"slot": Icon("eject"),
|
|
|
|
"title": "Mark as dropped",
|
|
|
|
}
|
|
|
|
if not purchase.date_dropped
|
|
|
|
else {},
|
2024-09-10 12:50:02 +00:00
|
|
|
{
|
|
|
|
"href": reverse(
|
|
|
|
"refund_purchase", args=[purchase.pk]
|
|
|
|
),
|
|
|
|
"slot": Icon("refund"),
|
|
|
|
"title": "Mark as refunded",
|
|
|
|
}
|
|
|
|
if not purchase.date_refunded
|
|
|
|
else {},
|
2024-08-08 18:17:43 +00:00
|
|
|
{
|
|
|
|
"href": reverse(
|
|
|
|
"edit_purchase", args=[purchase.pk]
|
|
|
|
),
|
2024-09-08 19:03:37 +00:00
|
|
|
"slot": Icon("edit"),
|
2024-09-10 12:46:10 +00:00
|
|
|
"title": "Edit",
|
2024-09-02 15:43:41 +00:00
|
|
|
"color": "gray",
|
2024-08-08 18:17:43 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"href": reverse(
|
|
|
|
"delete_purchase", args=[purchase.pk]
|
|
|
|
),
|
2024-09-08 19:03:37 +00:00
|
|
|
"slot": Icon("delete"),
|
2024-09-10 12:46:10 +00:00
|
|
|
"title": "Delete",
|
2024-08-08 18:17:43 +00:00
|
|
|
"color": "red",
|
|
|
|
},
|
|
|
|
]
|
|
|
|
},
|
|
|
|
),
|
|
|
|
]
|
|
|
|
for purchase in purchases
|
|
|
|
],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
return render(request, "list_purchases.html", context)
|
2024-08-12 19:42:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def add_purchase(request: HttpRequest, edition_id: int = 0) -> HttpResponse:
|
|
|
|
context: dict[str, Any] = {}
|
|
|
|
initial = {"date_purchased": timezone.now()}
|
|
|
|
|
|
|
|
if request.method == "POST":
|
|
|
|
form = PurchaseForm(request.POST or None, initial=initial)
|
|
|
|
if form.is_valid():
|
|
|
|
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("list_purchases")
|
|
|
|
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["title"] = "Add New Purchase"
|
|
|
|
context["script_name"] = "add_purchase.js"
|
|
|
|
return render(request, "add_purchase.html", context)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
@use_custom_redirect
|
|
|
|
def edit_purchase(request: HttpRequest, purchase_id: int) -> HttpResponse:
|
|
|
|
context = {}
|
|
|
|
purchase = get_object_or_404(Purchase, id=purchase_id)
|
|
|
|
form = PurchaseForm(request.POST or None, instance=purchase)
|
|
|
|
if form.is_valid():
|
|
|
|
form.save()
|
|
|
|
return redirect("list_sessions")
|
|
|
|
context["title"] = "Edit Purchase"
|
|
|
|
context["form"] = form
|
|
|
|
context["purchase_id"] = str(purchase_id)
|
|
|
|
context["script_name"] = "add_purchase.js"
|
|
|
|
return render(request, "add_purchase.html", context)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def delete_purchase(request: HttpRequest, purchase_id: int) -> HttpResponse:
|
|
|
|
purchase = get_object_or_404(Purchase, id=purchase_id)
|
|
|
|
purchase.delete()
|
2024-09-10 12:50:49 +00:00
|
|
|
return redirect("list_purchases")
|
2024-08-12 19:42:34 +00:00
|
|
|
|
|
|
|
|
2024-09-10 12:46:50 +00:00
|
|
|
@login_required
|
|
|
|
def drop_purchase(request: HttpRequest, purchase_id: int) -> HttpResponse:
|
|
|
|
purchase = get_object_or_404(Purchase, id=purchase_id)
|
|
|
|
purchase.date_dropped = timezone.now()
|
|
|
|
purchase.save()
|
2024-09-10 12:50:49 +00:00
|
|
|
return redirect("list_purchases")
|
2024-09-10 12:46:50 +00:00
|
|
|
|
|
|
|
|
2024-09-10 12:50:02 +00:00
|
|
|
@login_required
|
|
|
|
def refund_purchase(request: HttpRequest, purchase_id: int) -> HttpResponse:
|
|
|
|
purchase = get_object_or_404(Purchase, id=purchase_id)
|
|
|
|
purchase.date_refunded = timezone.now()
|
|
|
|
purchase.save()
|
2024-09-10 12:50:49 +00:00
|
|
|
return redirect("list_purchases")
|
2024-09-10 12:50:02 +00:00
|
|
|
|
|
|
|
|
2024-09-10 13:04:18 +00:00
|
|
|
@login_required
|
|
|
|
def finish_purchase(request: HttpRequest, purchase_id: int) -> HttpResponse:
|
|
|
|
purchase = get_object_or_404(Purchase, id=purchase_id)
|
|
|
|
purchase.date_finished = timezone.now()
|
|
|
|
purchase.save()
|
|
|
|
return redirect("list_purchases")
|
|
|
|
|
|
|
|
|
2024-08-12 19:42:34 +00:00
|
|
|
def related_purchase_by_edition(request: HttpRequest) -> HttpResponse:
|
|
|
|
edition_id = request.GET.get("edition")
|
|
|
|
if not edition_id:
|
|
|
|
return HttpResponseBadRequest("Invalid edition_id")
|
|
|
|
form = PurchaseForm()
|
|
|
|
form.fields["related_purchase"].queryset = Purchase.objects.filter(
|
|
|
|
edition_id=edition_id, type=Purchase.GAME
|
|
|
|
).order_by("edition__sort_name")
|
|
|
|
return render(request, "partials/related_purchase_field.html", {"form": form})
|