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,