diff --git a/engine/core/templates/admin/index.html b/engine/core/templates/admin/index.html index e6cb458d..ea986a31 100644 --- a/engine/core/templates/admin/index.html +++ b/engine/core/templates/admin/index.html @@ -27,7 +27,7 @@ {% trans "Revenue (gross, 30d)" %} {% endcomponent %} {% component "unfold/components/title.html" %} - {{ revenue_gross_30|default:0 }} + {% if currency_symbol %}{{ currency_symbol }}{% endif %}{{ revenue_gross_30|default:0 }} {% endcomponent %} {% endcomponent %} @@ -36,7 +36,7 @@ {% trans "Revenue (net, 30d)" %} {% endcomponent %} {% component "unfold/components/title.html" %} - {{ revenue_net_30|default:0 }} + {% if currency_symbol %}{{ currency_symbol }}{% endif %}{{ revenue_net_30|default:0 }} {% endcomponent %} {% endcomponent %} @@ -45,7 +45,7 @@ {% trans "Returns (30d)" %} {% endcomponent %} {% component "unfold/components/title.html" %} - {{ returns_30|default:0 }} + {% if currency_symbol %}{{ currency_symbol }}{% endif %}{{ returns_30|default:0 }} {% endcomponent %} {% endcomponent %} @@ -83,13 +83,13 @@ {% trans "Gross" %}: - {{ gross }} + {% if currency_symbol %}{{ currency_symbol }}{% endif %}{{ gross }}
{% trans "Returns" %}: - {{ returns }} + {% if currency_symbol %}{{ currency_symbol }}{% endif %}{{ returns }}
diff --git a/engine/core/utils/commerce.py b/engine/core/utils/commerce.py index e8896396..1284d6ba 100644 --- a/engine/core/utils/commerce.py +++ b/engine/core/utils/commerce.py @@ -1,13 +1,16 @@ from datetime import timedelta -from django.db.models import F, Sum +from constance import config +from django.db.models import F, QuerySet, Sum from django.db.models.functions import Coalesce from django.utils.timezone import now -from constance import config + from engine.core.models import Order, OrderProduct -def get_period_order_products(period: timedelta = timedelta(days=30), statuses: list[str] | None = None): +def get_period_order_products( + period: timedelta = timedelta(days=30), statuses: list[str] | None = None +) -> QuerySet[OrderProduct]: if statuses is None: statuses = ["FINISHED"] current = now() @@ -16,7 +19,7 @@ def get_period_order_products(period: timedelta = timedelta(days=30), statuses: return OrderProduct.objects.filter(status__in=statuses, order__in=orders) -def get_revenue(clear: bool = True, period: timedelta = timedelta(days=30)): +def get_revenue(clear: bool = True, period: timedelta = timedelta(days=30)) -> float: order_products = get_period_order_products(period) total: float = ( order_products.aggregate(total=Coalesce(Sum(F("buy_price") * F("quantity")), 0.0)).get("total") or 0.0 @@ -37,7 +40,7 @@ def get_revenue(clear: bool = True, period: timedelta = timedelta(days=30)): return round(float(total), 2) -def get_returns(period: timedelta = timedelta(days=30)): +def get_returns(period: timedelta = timedelta(days=30)) -> float: order_products = get_period_order_products(period, ["RETURNED"]) total_returns: float = ( order_products.aggregate(total=Coalesce(Sum(F("buy_price") * F("quantity")), 0.0)).get("total") or 0.0 @@ -48,5 +51,5 @@ def get_returns(period: timedelta = timedelta(days=30)): return 0.0 -def get_total_processed_orders(period: timedelta = timedelta(days=30)): +def get_total_processed_orders(period: timedelta = timedelta(days=30)) -> int: return get_period_order_products(period, ["RETURNED", "FINISHED"]).count() diff --git a/engine/core/views.py b/engine/core/views.py index 0182b080..9e98f52b 100644 --- a/engine/core/views.py +++ b/engine/core/views.py @@ -13,6 +13,7 @@ from django.core.exceptions import BadRequest from django.db.models import Count, Sum from django.http import FileResponse, Http404, HttpRequest, HttpResponse, HttpResponseRedirect, JsonResponse from django.shortcuts import redirect +from django.template import Context from django.urls import reverse from django.utils.decorators import method_decorator from django.utils.http import urlsafe_base64_decode @@ -416,11 +417,16 @@ version.__doc__ = _( # type: ignore [assignment] ) -def dashboard_callback(request, context): - revenue_gross_30 = get_revenue(clear=False) - revenue_net_30 = get_revenue(clear=True) - returns_30 = get_returns() - processed_orders_30 = get_total_processed_orders() +def dashboard_callback(request: HttpRequest, context: Context) -> Context: + revenue_gross_30: float = get_revenue(clear=False) + revenue_net_30: float = get_revenue(clear=True) + returns_30: float = get_returns() + processed_orders_30: int = get_total_processed_orders() + currency_symbol: str = "" + with suppress(Exception): + currency_symbol = dict(getattr(settings, "CURRENCIES_WITH_SYMBOLS", ())).get( + getattr(settings, "CURRENCY_CODE", ""), "" + ) quick_links: list[dict[str, str]] = [] with suppress(Exception): @@ -454,7 +460,7 @@ def dashboard_callback(request, context): if wished_first and wished_first.get("products"): product = Product.objects.filter(pk=wished_first["products"]).first() if product: - img = product.images.first().image_url if product.images.exists() else "" + img = product.images.first().image_url if product.images.exists() else "" # type: ignore [union-attr] most_wished = { "name": product.name, "image": img, @@ -473,7 +479,7 @@ def dashboard_callback(request, context): if not pid or pid not in product_by_id: continue p = product_by_id[pid] - img = p.images.first().image_url if p.images.exists() else "" + img = p.images.first().image_url if p.images.exists() else "" # type: ignore [union-attr] most_wished_list.append( { "name": p.name, @@ -498,7 +504,7 @@ def dashboard_callback(request, context): if popular_first and popular_first.get("product"): product = Product.objects.filter(pk=popular_first["product"]).first() if product: - img = product.images.first().image_url if product.images.exists() else "" + img = product.images.first().image_url if product.images.exists() else "" # type: ignore [union-attr] most_popular = { "name": product.name, "image": img, @@ -515,7 +521,7 @@ def dashboard_callback(request, context): if not pid or pid not in product_by_id: continue p = product_by_id[pid] - img = p.images.first().image_url if p.images.exists() else "" + img = p.images.first().image_url if p.images.exists() else "" # type: ignore [union-attr] most_popular_list.append( { "name": p.name, @@ -538,6 +544,7 @@ def dashboard_callback(request, context): "most_popular_product": most_popular, "most_wished_products": most_wished_list, "most_popular_products": most_popular_list, + "currency_symbol": currency_symbol, } ) diff --git a/evibes/settings/unfold.py b/evibes/settings/unfold.py index 83e4979d..b0ffadc8 100644 --- a/evibes/settings/unfold.py +++ b/evibes/settings/unfold.py @@ -1,17 +1,21 @@ +from typing import Any + from django.templatetags.static import static from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from evibes.settings.base import ( + LANGUAGES as BASE_LANGUAGES, +) +from evibes.settings.base import ( + LANGUAGES_FLAGS, PROJECT_NAME, STOREFRONT_DOMAIN, SUPPORT_CONTACT, TASKBOARD_URL, - LANGUAGES as BASE_LANGUAGES, - LANGUAGES_FLAGS, ) -UNFOLD = { +UNFOLD: dict[str, Any] = { "SITE_URL": STOREFRONT_DOMAIN, "SITE_TITLE": f"{PROJECT_NAME} Dashboard", "SITE_HEADER": PROJECT_NAME,