schon/payments/managers.py
Egor fureunoir Gorbunov 3fe3d571bb Features: 1) Add GatewayManager and GatewayQuerySet to handle advanced gateway filtering and usage checks; 2) Integrate GatewayManager with Gateway model for automatic query filtering; 3) Introduce can_be_used query annotation for gateway availability.
Fixes: 1) Default to a usable `Gateway` when processing new transactions if none is specified.

Extra: 1) Add missing import for `GatewayManager` in `payments.models`; 2) Refactor gateway availability logic into the manager and query set for cleaner code organization.
2025-10-22 11:12:30 +03:00

44 lines
1.7 KiB
Python

from django.db.models import BooleanField, Case, F, Manager, Q, QuerySet, Sum, Value, When
from django.db.models.functions import Coalesce
from django.utils.timezone import now
class GatewayQuerySet(QuerySet):
def with_usage_sums(self) -> QuerySet:
today = now().date()
current_month_start = today.replace(day=1)
return self.annotate(
daily_sum=Coalesce(Sum("transactions__amount", filter=Q(transactions__created__date=today)), Value(0.0)),
monthly_sum=Coalesce(
Sum("transactions__amount", filter=Q(transactions__created__gte=current_month_start)), Value(0.0)
),
)
def can_be_used(self) -> QuerySet:
qs = self.with_usage_sums()
qs = qs.annotate(
daily_ok=Case(
When(daily_limit=0, then=Value(True)),
When(daily_sum__lt=F("daily_limit"), then=Value(True)),
default=Value(False),
output_field=BooleanField(),
),
monthly_ok=Case(
When(monthly_limit=0, then=Value(True)),
When(monthly_sum__lt=F("monthly_limit"), then=Value(True)),
default=Value(False),
output_field=BooleanField(),
),
)
return qs.annotate(
can_be_used=Case(
When(daily_ok=True, monthly_ok=True, is_active=True, then=Value(True)),
default=Value(False),
output_field=BooleanField(),
)
).order_by("-priority")
class GatewayManager(Manager.from_queryset(GatewayQuerySet)):
def get_queryset(self) -> QuerySet:
return super().get_queryset().can_be_used()