fix - custom APIExceptions for quota stats

This commit is contained in:
2025-11-18 09:11:35 +03:30
parent d8f6eaf243
commit 4e5319b625
3 changed files with 67 additions and 11 deletions

View File

@@ -2,6 +2,44 @@ from rest_framework import status
from rest_framework.exceptions import APIException from rest_framework.exceptions import APIException
class QuotaException(APIException):
""" if quota is not available """
status_code = status.HTTP_400_BAD_REQUEST
default_detail = "خطا در اطلاعات سهمیه" # noqa
default_code = 'error'
def __init__(self, message=None, status_code=None, code=None):
if status_code is not None:
self.status_code = status_code
detail = {
"message": message,
"status_code": status_code
}
super().__init__(detail)
class DistributionException(APIException):
""" if distribution is not available """
status_code = status.HTTP_400_BAD_REQUEST
default_detail = "خطا در اطلاعات توزیع." # noqa
default_code = 'error'
def __init__(self, message=None, status_code=None, code=None):
if status_code is not None:
self.status_code = status_code
detail = {
"message": message,
"status_code": status_code
}
super().__init__(detail)
class QuotaWeightException(APIException): class QuotaWeightException(APIException):
""" if quota distributions weight is more """ """ if quota distributions weight is more """

View File

@@ -1,6 +1,8 @@
from django.apps import apps from django.apps import apps
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from rest_framework.exceptions import APIException from rest_framework import status
from apps.product.exceptions import DistributionException
def get_model(app_label, model_name): def get_model(app_label, model_name):
@@ -15,28 +17,41 @@ class QuotaStatsValidator:
@staticmethod @staticmethod
def _get_stat(quota, organization): def _get_stat(quota, organization):
organization_quota_stats = get_model("product", "OrganizationQuotaStats") organization_quota_stats = get_model("product", "OrganizationQuotaStats")
return organization_quota_stats.objects.filter(quota=quota, organization=organization).first() return organization_quota_stats.objects.filter(quota=quota, organization=organization).first() # noqa
@staticmethod @staticmethod
def validate_assigner_has_enough(assigner_org, quota, amount, allow_zero=False): def validate_assigner_has_enough(assigner_org, quota, amount, allow_zero=False, update_operation=None):
""" """
if organization has enough remaining weight if organization has enough remaining weight
""" """
stat = QuotaStatsValidator._get_stat(quota, assigner_org) stat = QuotaStatsValidator._get_stat(quota, assigner_org)
if not stat: if not stat:
raise APIException(f"Organization {assigner_org} has no quota record for quota {quota}.") raise DistributionException(
f"سازمان {assigner_org.name} هیچ مدل میانی برای این سهمیه {quota} ندارد .", # noqa
status.HTTP_403_FORBIDDEN
)
remaining = getattr(stat, "remaining_amount", None) remaining = getattr(stat, "remaining_amount", None)
if remaining is None: if remaining is None:
# fallback to quota.remaining_weight subtraction from totals # fallback to quota.remaining_weight subtraction from totals
raise APIException("remaining_amount field missing in OrganizationQuotaStats.") raise DistributionException(
"فیلد باقی مانده در مدل میانی وجود ندارد", # noqa
status.HTTP_403_FORBIDDEN
)
if amount < 0: if amount < 0:
raise APIException("Amount must be non-negative.") raise DistributionException("مقدار وزن نباید منفی باشد", status.HTTP_403_FORBIDDEN) # noqa
if remaining < amount and not allow_zero: if remaining < amount and not allow_zero:
raise APIException( if update_operation:
f"Assigning {amount} exceeds remaining amount {remaining} for organization {assigner_org}." raise DistributionException(
"مقدار وزن ویرایش شده از وزن باقیمانده بیشتر است", # noqa
status.HTTP_403_FORBIDDEN
)
raise DistributionException(
f"تخصیص مقدار {amount} بیشتر از مقدار باقیمانده {remaining} برای سازمان {assigner_org.name} میباشد.",
# noqa
status.HTTP_403_FORBIDDEN
) )
@staticmethod @staticmethod

View File

@@ -1,8 +1,8 @@
from rest_framework import serializers from rest_framework import serializers, status
from rest_framework.exceptions import APIException
from apps.livestock.web.api.v1.serializers import LiveStockTypeSerializer from apps.livestock.web.api.v1.serializers import LiveStockTypeSerializer
from apps.product import models as product_models from apps.product import models as product_models
from apps.product.exceptions import QuotaException
from apps.product.web.api.v1.serializers import product_serializers from apps.product.web.api.v1.serializers import product_serializers
@@ -15,7 +15,10 @@ class QuotaSerializer(serializers.ModelSerializer):
weight = attrs['quota_weight'] weight = attrs['quota_weight']
if self.instance: if self.instance:
if self.instance.quota_distributed < weight: if self.instance.quota_distributed < weight:
raise APIException("Quota weight cannot be less than distributed weight.") raise QuotaException(
"وزن سهمیه نمیتواند کمتر از وزن توزیع شده باشد", # noqa
status.HTTP_403_FORBIDDEN
)
return attrs return attrs
def to_representation(self, instance: product_models.Quota): def to_representation(self, instance: product_models.Quota):