Features: 1) Add LimitsType GraphQL object and payments_limits query to expose deposit limits; 2) Introduce LimitsSerializer and LimitsAPIView for retrieving minimal and maximal deposit amounts; 3) Implement get_limits utility to calculate deposit boundaries dynamically;
Fixes: 1) Add missing `LimitsSerializer` import in `drf.views` module; Extra: 1) Update `.gitignore` to exclude `queries`; 2) Refactor schema and views to integrate new limits functionality.
This commit is contained in:
parent
5b3a8aedbe
commit
87ba06ff0c
8 changed files with 67 additions and 5 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -167,4 +167,5 @@ cypress/screenshots/
|
|||
test.ipynb
|
||||
|
||||
# Production stuff
|
||||
.initialized
|
||||
.initialized
|
||||
queries
|
||||
|
|
@ -83,6 +83,8 @@ from engine.core.utils import get_project_parameters
|
|||
from engine.core.utils.languages import get_flag_by_language
|
||||
from engine.core.utils.messages import permission_denied_message
|
||||
from engine.payments.graphene.mutations import Deposit
|
||||
from engine.payments.graphene.object_types import LimitsType
|
||||
from engine.payments.utils.gateways import get_limits
|
||||
from engine.vibes_auth.filters import UserFilter
|
||||
from engine.vibes_auth.graphene.mutations import (
|
||||
ActivateUser,
|
||||
|
|
@ -105,6 +107,7 @@ logger = logging.getLogger(__name__)
|
|||
class Query(ObjectType):
|
||||
parameters = Field(ConfigType)
|
||||
languages = List(LanguageType)
|
||||
payments_limits = Field(LimitsType)
|
||||
products = DjangoFilterConnectionField(ProductType, filterset_class=ProductFilter)
|
||||
orders = DjangoFilterConnectionField(OrderType, filterset_class=OrderFilter)
|
||||
users = DjangoFilterConnectionField(UserType, filterset_class=UserFilter)
|
||||
|
|
@ -140,6 +143,11 @@ class Query(ObjectType):
|
|||
|
||||
return languages
|
||||
|
||||
@staticmethod
|
||||
def resolve_payments_limits(_parent, _info):
|
||||
min_amount, max_amount = get_limits()
|
||||
return {"min_amount": min_amount, "max_amount": max_amount}
|
||||
|
||||
@staticmethod
|
||||
def resolve_products(_parent, info, **kwargs):
|
||||
if info.context.user.is_authenticated and kwargs.get("uuid"):
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from drf_spectacular.utils import extend_schema
|
|||
from rest_framework import status
|
||||
|
||||
from engine.core.docs.drf import error
|
||||
from engine.payments.serializers import DepositSerializer, TransactionProcessSerializer
|
||||
from engine.payments.serializers import DepositSerializer, TransactionProcessSerializer, LimitsSerializer
|
||||
|
||||
DEPOSIT_SCHEMA = {
|
||||
"post": extend_schema(
|
||||
|
|
@ -20,3 +20,17 @@ DEPOSIT_SCHEMA = {
|
|||
},
|
||||
),
|
||||
}
|
||||
|
||||
LIMITS_SCHEMA = {
|
||||
"get": extend_schema(
|
||||
tags=[
|
||||
"payments",
|
||||
],
|
||||
summary=_("payment limits"),
|
||||
description=_("retrieve minimal and maximal allowed deposit amounts across available gateways"),
|
||||
responses={
|
||||
status.HTTP_200_OK: LimitsSerializer,
|
||||
status.HTTP_401_UNAUTHORIZED: error,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ from graphene_django import DjangoObjectType
|
|||
from engine.payments.models import Balance, Transaction
|
||||
|
||||
|
||||
class LimitsType(graphene.ObjectType):
|
||||
min_amount = graphene.Float()
|
||||
max_amount = graphene.Float()
|
||||
|
||||
|
||||
class TransactionType(DjangoObjectType):
|
||||
process = GenericScalar()
|
||||
|
||||
|
|
|
|||
|
|
@ -29,3 +29,8 @@ class TransactionProcessSerializer(ModelSerializer): # type: ignore [type-arg]
|
|||
model = Transaction
|
||||
fields = ("process", "order_hr_id", "order_uuid")
|
||||
read_only_fields = ("process", "order_hr_id", "order_uuid")
|
||||
|
||||
|
||||
class LimitsSerializer(Serializer): # type: ignore [type-arg]
|
||||
min_amount = FloatField(read_only=True)
|
||||
max_amount = FloatField(read_only=True)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from django.urls import include, path
|
||||
from rest_framework.routers import DefaultRouter
|
||||
|
||||
from engine.payments.views import CallbackAPIView, DepositView
|
||||
from engine.payments.views import CallbackAPIView, DepositView, LimitsAPIView
|
||||
from engine.payments.viewsets import TransactionViewSet
|
||||
|
||||
app_name = "payments"
|
||||
|
|
@ -12,5 +12,6 @@ payment_router.register(prefix=r"transactions", viewset=TransactionViewSet, base
|
|||
urlpatterns = [
|
||||
path(r"", include(payment_router.urls)),
|
||||
path(r"deposit/", DepositView.as_view()),
|
||||
path(r"limits/", LimitsAPIView.as_view()),
|
||||
path(r"<str:uuid>/callback/", CallbackAPIView.as_view()),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -14,3 +14,18 @@ def get_gateways_integrations(name: str | None = None) -> list[Type[AbstractGate
|
|||
class_name = gateway.integration_path.split(".")[-1]
|
||||
gateways_integrations.append(create_object(module_name, class_name))
|
||||
return gateways_integrations
|
||||
|
||||
|
||||
def get_limits() -> tuple[float, float]:
|
||||
from django.db.models import Min, Max
|
||||
|
||||
qs = Gateway.objects.can_be_used().filter(can_be_used=True)
|
||||
|
||||
if not qs.exists():
|
||||
return 0.0, 0.0
|
||||
|
||||
agg = qs.aggregate(min_limit=Min("minimum_transaction_amount"), max_limit=Max("maximum_transaction_amount"))
|
||||
|
||||
min_limit = float(agg.get("min_limit") or 0.0)
|
||||
max_limit = float(agg.get("max_limit") or 0.0)
|
||||
return min_limit, max_limit
|
||||
|
|
|
|||
|
|
@ -9,10 +9,11 @@ from rest_framework.request import Request
|
|||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from engine.payments.docs.drf.views import DEPOSIT_SCHEMA
|
||||
from engine.payments.docs.drf.views import DEPOSIT_SCHEMA, LIMITS_SCHEMA
|
||||
from engine.payments.gateways import UnknownGatewayError
|
||||
from engine.payments.models import Transaction
|
||||
from engine.payments.serializers import DepositSerializer, TransactionProcessSerializer
|
||||
from engine.payments.serializers import DepositSerializer, TransactionProcessSerializer, LimitsSerializer
|
||||
from engine.payments.utils.gateways import get_limits
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -67,3 +68,15 @@ class CallbackAPIView(APIView):
|
|||
return Response(
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR, data={"error": str(e), "detail": traceback.format_exc()}
|
||||
)
|
||||
|
||||
|
||||
@extend_schema_view(**LIMITS_SCHEMA)
|
||||
class LimitsAPIView(APIView):
|
||||
__doc__ = _( # type: ignore [assignment]
|
||||
"This endpoint returns minimal and maximal allowed deposit amounts across available gateways."
|
||||
)
|
||||
|
||||
def get(self, request: Request, *args: list[Any], **kwargs: dict[Any, Any]) -> Response:
|
||||
min_amount, max_amount = get_limits()
|
||||
data = {"min_amount": min_amount, "max_amount": max_amount}
|
||||
return Response(LimitsSerializer(data).data, status=status.HTTP_200_OK)
|
||||
|
|
|
|||
Loading…
Reference in a new issue