diff --git a/engine/core/utils/commerce.py b/engine/core/utils/commerce.py index c5ca430d..48ec5add 100644 --- a/engine/core/utils/commerce.py +++ b/engine/core/utils/commerce.py @@ -1,9 +1,10 @@ from contextlib import suppress from datetime import date, timedelta +from decimal import Decimal from typing import Any from constance import config -from django.db.models import Count, F, QuerySet, Sum +from django.db.models import Count, DecimalField, F, QuerySet, Sum from django.db.models.functions import Coalesce, TruncDate from django.urls import reverse from django.utils.timezone import now @@ -28,7 +29,11 @@ def get_revenue(clear: bool = True, period: timedelta = timedelta(days=30)) -> f order_products = get_period_order_products(period) total: float = ( order_products.aggregate( - total=Coalesce(Sum(F("buy_price") * F("quantity")), 0.0) + total=Coalesce( + Sum(F("buy_price") * F("quantity")), + Decimal("0.00"), + output_field=DecimalField(), + ) ).get("total") or 0.0 ) @@ -78,7 +83,13 @@ def get_returns(period: timedelta = timedelta(days=30)) -> float: order__buy_time__lte=current, order__buy_time__gte=period_start, ) - .aggregate(total=Coalesce(Sum(F("buy_price") * F("quantity")), 0.0)) + .aggregate( + total=Coalesce( + Sum(F("buy_price") * F("quantity")), + Decimal("0.00"), + output_field=DecimalField(), + ) + ) .get("total") or 0.0 ) @@ -122,7 +133,13 @@ def get_daily_gross_revenue( get_period_order_products(period, ["FINISHED"]) # OrderProduct queryset .annotate(day=TruncDate("order__buy_time")) .values("day") - .annotate(total=Coalesce(Sum(F("buy_price") * F("quantity")), 0.0)) + .annotate( + total=Coalesce( + Sum(F("buy_price") * F("quantity")), + Decimal("0.00"), + output_field=DecimalField(), + ) + ) .order_by("day") ) result: dict[date, float] = {} @@ -158,7 +175,11 @@ def get_top_returned_products( .values("product") .annotate( returned_qty=Coalesce(Sum("quantity"), 0), - returned_amount=Coalesce(Sum(F("buy_price") * F("quantity")), 0.0), + returned_amount=Coalesce( + Sum(F("buy_price") * F("quantity")), + Decimal("0.00"), + output_field=DecimalField(), + ), ) .order_by("-returned_qty")[:limit] ) @@ -236,7 +257,11 @@ def get_top_categories_by_qty( .values("product__category") .annotate( qty=Coalesce(Sum("quantity"), 0), - gross=Coalesce(Sum(F("buy_price") * F("quantity")), 0.0), + gross=Coalesce( + Sum(F("buy_price") * F("quantity")), + Decimal("0.00"), + output_field=DecimalField(), + ), ) .order_by("-qty", "-gross")[:limit] ) @@ -277,7 +302,11 @@ def get_shipped_vs_digital_mix( .values("product__is_digital") .annotate( qty=Coalesce(Sum("quantity"), 0), - gross=Coalesce(Sum(F("buy_price") * F("quantity")), 0.0), + gross=Coalesce( + Sum(F("buy_price") * F("quantity")), + Decimal("0.00"), + output_field=DecimalField(), + ), ) )