From e63c6b9b8d4f9ce4fb36d46769eaddc69fd26bb2 Mon Sep 17 00:00:00 2001 From: Mojtaba-z Date: Tue, 2 Dec 2025 09:58:30 +0330 Subject: [PATCH] add - new pricing attr system --- ..._attributevalue_org_quota_stat_and_more.py | 24 +++++++++++++++++++ apps/product/models.py | 12 ++++++++++ apps/product/services/quota_stat_service.py | 5 ++-- apps/product/signals.py | 8 ------- .../validators/quota_stats_validator.py | 6 +++-- .../api/v1/viewsets/quota_distribution_api.py | 9 +++++++ 6 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 apps/product/migrations/0100_attributevalue_org_quota_stat_and_more.py diff --git a/apps/product/migrations/0100_attributevalue_org_quota_stat_and_more.py b/apps/product/migrations/0100_attributevalue_org_quota_stat_and_more.py new file mode 100644 index 0000000..a4be5a8 --- /dev/null +++ b/apps/product/migrations/0100_attributevalue_org_quota_stat_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 5.0 on 2025-12-01 12:13 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('product', '0099_organizationquotastats_free_sale_balance_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='attributevalue', + name='org_quota_stat', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='attribute_values', to='product.organizationquotastats'), + ), + migrations.AddField( + model_name='quotabrokervalue', + name='org_quota_stat', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='broker_values', to='product.organizationquotastats'), + ), + ] diff --git a/apps/product/models.py b/apps/product/models.py index 8e47dfc..db3cf33 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -215,6 +215,12 @@ class AttributeValue(BaseModel): related_name='attribute_values', null=True ) + org_quota_stat = models.ForeignKey( + 'OrganizationQuotaStats', + on_delete=models.CASCADE, + related_name='attribute_values', + null=True + ) attribute = models.ForeignKey( Attribute, on_delete=models.CASCADE, @@ -695,6 +701,12 @@ class QuotaBrokerValue(BaseModel): related_name="broker_values", null=True ) + org_quota_stat = models.ForeignKey( + 'OrganizationQuotaStats', + on_delete=models.CASCADE, + related_name='broker_values', + null=True + ) broker = models.ForeignKey( Broker, on_delete=models.CASCADE, diff --git a/apps/product/services/quota_stat_service.py b/apps/product/services/quota_stat_service.py index ddd3896..cd2dd9e 100644 --- a/apps/product/services/quota_stat_service.py +++ b/apps/product/services/quota_stat_service.py @@ -7,7 +7,6 @@ class QuotaStatsService: @staticmethod def apply_distribution(distribution: QuotaDistribution): quota = distribution.quota - print("ssss") # origin org assigner = distribution.assigner_organization # destination org @@ -24,10 +23,12 @@ class QuotaStatsService: organization=assigner, quota=quota, ) + print(assigner_stat.id) if created: assigner_stat.stat_type = 'distribution' assigner_stat.save() if assigner_stat.stat_type == 'distribution': + print(assigner_stat.remaining_amount) assigner_stat.remaining_amount -= distribution.weight assigner_stat.total_distributed += distribution.weight assigner_stat.save() @@ -38,7 +39,7 @@ class QuotaStatsService: quota=quota, stat_type='distribution' ) - + print(distribution._request) # noqa assigned_stat.total_amount += distribution.weight assigned_stat.remaining_amount += distribution.weight assigned_stat.distributions.add(distribution) diff --git a/apps/product/signals.py b/apps/product/signals.py index a3a5d77..7852f29 100644 --- a/apps/product/signals.py +++ b/apps/product/signals.py @@ -66,14 +66,6 @@ def update_quota_remaining(sender, instance, **kwargs): if getattr(instance, '_from_signal', False): return - # when delete object, prevent from update fields error - # if kwargs.get('signal') == post_delete: - if instance.trash: - if instance.parent_distribution: - remaining_distribution_weight(instance.parent_distribution) - else: - remaining_distribution_weight(instance) - def update_product_stats(instance: Product, distribution: QuotaDistribution = None): """ update all stats of product """ diff --git a/apps/product/validators/quota_stats_validator.py b/apps/product/validators/quota_stats_validator.py index 5554b34..a95bc33 100644 --- a/apps/product/validators/quota_stats_validator.py +++ b/apps/product/validators/quota_stats_validator.py @@ -32,12 +32,14 @@ class QuotaStatsValidator: """ if organization has enough remaining weight """ + if assigner_org.type.key == "ADM": + assigner_org = quota.registerer_organization + stat = QuotaStatsValidator._get_stat(quota, assigner_org) if not stat: raise DistributionException( f"سازمان {assigner_org.name} هیچ مدل میانی برای این سهمیه {quota} ندارد .", # noqa - status.HTTP_403_FORBIDDEN - ) + status.HTTP_403_FORBIDDEN) remaining = getattr(stat, "remaining_amount", None) if remaining is None: diff --git a/apps/product/web/api/v1/viewsets/quota_distribution_api.py b/apps/product/web/api/v1/viewsets/quota_distribution_api.py index 1e44d85..1cbefe2 100644 --- a/apps/product/web/api/v1/viewsets/quota_distribution_api.py +++ b/apps/product/web/api/v1/viewsets/quota_distribution_api.py @@ -60,11 +60,20 @@ class QuotaDistributionViewSet(BaseViewSet, SoftDeleteMixin, viewsets.ModelViewS except APIException as e: raise APIException("unauthorized", code=status.HTTP_401_UNAUTHORIZED) + price_attributes_data = request.data.pop('price_attributes_data') + broker_data = request.data.pop('broker_data') + request.data.update({'assigner_organization': assigner_user.organization.id}) serializer = self.serializer_class(data=request.data) if serializer.is_valid(): distribution = serializer.save() + # to use in signals + distribution._request = { + 'price_attributes_data': price_attributes_data, + 'broker_data': broker_data + } + # add this organization to quota assigned_organizations # this org is received a distribution from quota distribution.quota.assigned_organizations.add(distribution.assigned_organization)