consistently format prices everywhere
Django CI/CD / test (push) Successful in 1m7s Details
Django CI/CD / build-and-push (push) Successful in 2m10s Details

This commit is contained in:
Lukáš Kucharczyk 2024-11-15 18:03:08 +01:00
parent 8acc4f9c5b
commit fc0d8db8e8
Signed by: lukas
SSH Key Fingerprint: SHA256:vMuSwvwAvcT6htVAioMP7rzzwMQNi3roESyhv+nAxeg
6 changed files with 28 additions and 11 deletions

View File

@ -3,6 +3,7 @@ from string import ascii_lowercase
from typing import Any, Callable
from django.template import TemplateDoesNotExist
from django.template.defaultfilters import floatformat
from django.template.loader import render_to_string
from django.urls import NoReverseMatch, reverse
from django.utils.safestring import SafeText, mark_safe
@ -50,6 +51,7 @@ def randomid(seed: str = "", length: int = 10) -> str:
def Popover(
popover_content: str,
wrapped_content: str = "",
wrapped_classes: str = "",
children: list[HTMLTag] = [],
attributes: list[HTMLAttribute] = [],
) -> str:
@ -62,6 +64,7 @@ def Popover(
("id", id),
("wrapped_content", wrapped_content),
("popover_content", popover_content),
("wrapped_classes", wrapped_classes),
],
children=children,
template="cotton/popover.html",
@ -193,3 +196,11 @@ def NameWithPlatformIcon(name: str, platform: str) -> SafeText:
)
return mark_safe(content)
def PurchasePrice(purchase) -> str:
return Popover(
popover_content=f"{floatformat(purchase.price)} {purchase.price_currency}",
wrapped_content=f"{floatformat(purchase.converted_price)} {purchase.converted_currency}",
wrapped_classes="underline decoration-dotted",
)

View File

@ -2192,6 +2192,10 @@ input:checked + .toggle-bg {
text-decoration-color: #64748b;
}
.decoration-dotted {
text-decoration-style: dotted;
}
.opacity-0 {
opacity: 0;
}

View File

@ -1,8 +1,10 @@
<span data-popover-target={{ id }} class="{{ class }}">{{ wrapped_content|default:slot }}</span>
<span data-popover-target={{ id }} class="{{ wrapped_classes }}">{{ wrapped_content|default:slot }}</span>
<div data-popover
id="{{ id }}"
role="tooltip"
class="absolute z-10 invisible inline-block text-sm text-white transition-opacity duration-300 bg-white border border-purple-200 rounded-lg shadow-sm opacity-0 dark:text-white dark:border-purple-600 dark:bg-purple-800">
<div class="px-3 py-2">{{ popover_content }}</div>
<div data-popper-arrow></div>
<!-- for Tailwind CSS to generate decoration-dotted CSS from Python component -->
<span class="hidden decoration-dotted"></span>
</div>

View File

@ -142,7 +142,9 @@
</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 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 | floatformat }} ({{ spent_per_game | floatformat }}/game)
</td>
</tr>
</tbody>
</table>
@ -253,7 +255,7 @@
{% for purchase in purchased_unfinished %}
<tr>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{% partial purchase-name %}</td>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchase.converted_price }}</td>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchase.converted_price | floatformat }}</td>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchase.date_purchased | date:"d/m/Y" }}</td>
</tr>
{% endfor %}
@ -274,7 +276,7 @@
{% for purchase in all_purchased_this_year %}
<tr>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{% partial purchase-name %}</td>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchase.converted_price }}</td>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchase.converted_price | floatformat }}</td>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ purchase.date_purchased | date:"d/m/Y" }}</td>
</tr>
{% endfor %}

View File

@ -16,6 +16,7 @@ from common.components import (
NameWithPlatformIcon,
Popover,
PopoverTruncated,
PurchasePrice,
)
from common.time import (
dateformat,
@ -25,7 +26,7 @@ from common.time import (
local_strftime,
timeformat,
)
from common.utils import format_float_or_int, safe_division, truncate
from common.utils import safe_division, truncate
from games.forms import GameForm
from games.models import Edition, Game, Purchase, Session
from games.views.general import use_custom_redirect
@ -247,7 +248,7 @@ def view_game(request: HttpRequest, game_id: int) -> HttpResponse:
),
purchase.get_type_display(),
purchase.date_purchased.strftime(dateformat),
f"{format_float_or_int(purchase.price)} {purchase.price_currency}",
PurchasePrice(purchase),
render_to_string(
"cotton/button_group.html",
{

View File

@ -13,9 +13,8 @@ from django.template.loader import render_to_string
from django.urls import reverse
from django.utils import timezone
from common.components import A, Button, Icon, LinkedNameWithPlatformIcon
from common.components import A, Button, Icon, LinkedNameWithPlatformIcon, PurchasePrice
from common.time import dateformat
from common.utils import format_float_or_int
from games.forms import PurchaseForm
from games.models import Edition, Purchase
from games.views.general import use_custom_redirect
@ -49,7 +48,6 @@ def list_purchases(request: HttpRequest) -> HttpResponse:
"Name",
"Type",
"Price",
"Currency",
"Infinite",
"Purchased",
"Refunded",
@ -66,8 +64,7 @@ def list_purchases(request: HttpRequest) -> HttpResponse:
platform=purchase.platform,
),
purchase.get_type_display(),
format_float_or_int(purchase.price),
purchase.price_currency,
PurchasePrice(purchase),
purchase.infinite,
purchase.date_purchased.strftime(dateformat),
(