From 7e8f350b7428b575bf7603998360f619ac440083 Mon Sep 17 00:00:00 2001 From: Mojtaba-z Date: Wed, 30 Jul 2025 09:23:11 +0330 Subject: [PATCH] distributed & remaining weight of distribution by signal calculated --- ...0_alter_deviceactivationcode_expires_at.py | 19 +++++++++++ ...lquotadistribution_distributed_and_more.py | 33 +++++++++++++++++++ apps/product/models.py | 2 ++ apps/product/signals.py | 32 +++++++++++++++++- .../api/v1/viewsets/quota_distribution_api.py | 9 +++++ 5 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 apps/pos_device/migrations/0010_alter_deviceactivationcode_expires_at.py create mode 100644 apps/product/migrations/0057_historicalquotadistribution_distributed_and_more.py diff --git a/apps/pos_device/migrations/0010_alter_deviceactivationcode_expires_at.py b/apps/pos_device/migrations/0010_alter_deviceactivationcode_expires_at.py new file mode 100644 index 0000000..08f2eb3 --- /dev/null +++ b/apps/pos_device/migrations/0010_alter_deviceactivationcode_expires_at.py @@ -0,0 +1,19 @@ +# Generated by Django 5.0 on 2025-07-30 04:36 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pos_device', '0009_device_is_activated_deviceactivationcode'), + ] + + operations = [ + migrations.AlterField( + model_name='deviceactivationcode', + name='expires_at', + field=models.DateTimeField(default=datetime.datetime(2025, 7, 30, 8, 6, 2, 513737)), + ), + ] diff --git a/apps/product/migrations/0057_historicalquotadistribution_distributed_and_more.py b/apps/product/migrations/0057_historicalquotadistribution_distributed_and_more.py new file mode 100644 index 0000000..70a2f9e --- /dev/null +++ b/apps/product/migrations/0057_historicalquotadistribution_distributed_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 5.0 on 2025-07-30 04:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('product', '0056_productstats_organization_alter_productstats_product'), + ] + + operations = [ + migrations.AddField( + model_name='historicalquotadistribution', + name='distributed', + field=models.PositiveBigIntegerField(default=0), + ), + migrations.AddField( + model_name='historicalquotadistribution', + name='remaining_weight', + field=models.PositiveBigIntegerField(default=0), + ), + migrations.AddField( + model_name='quotadistribution', + name='distributed', + field=models.PositiveBigIntegerField(default=0), + ), + migrations.AddField( + model_name='quotadistribution', + name='remaining_weight', + field=models.PositiveBigIntegerField(default=0), + ), + ] diff --git a/apps/product/models.py b/apps/product/models.py index a50856c..1b83596 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -551,6 +551,8 @@ class QuotaDistribution(BaseModel): null=True ) weight = models.PositiveBigIntegerField(default=0) + remaining_weight = models.PositiveBigIntegerField(default=0) + distributed = models.PositiveBigIntegerField(default=0) warehouse_entry = models.PositiveBigIntegerField(default=0) warehouse_balance = models.PositiveBigIntegerField(default=0) been_sold = models.PositiveBigIntegerField(default=0) diff --git a/apps/product/signals.py b/apps/product/signals.py index 901bb7d..031b963 100644 --- a/apps/product/signals.py +++ b/apps/product/signals.py @@ -1,4 +1,4 @@ -from django.db.models import Sum +from django.db.models import Sum, Q from django.db.models.signals import post_save, post_delete from common.helpers import get_organization_by_user from django.dispatch import receiver @@ -18,6 +18,7 @@ from crum import get_current_user def recalculate_remaining_amount(quota): + """ calculate remaining weight from distribution """ total_distributed = quota.distributions_assigned.aggregate( total=Sum('weight') )['total'] or 0 @@ -27,10 +28,39 @@ def recalculate_remaining_amount(quota): quota.save(update_fields=["remaining_weight", "quota_distributed"]) +def remaining_distribution_weight(instance: QuotaDistribution): + """ calculate remaining & distributed weight from distribution """ + + organization = get_organization_by_user(get_current_user()) + + total_assigned_distribution = QuotaDistribution.objects.filter( + Q(assigned_organization=organization) + ).aggregate( + total=Sum('weight') + )['total'] or 0 + + print(total_assigned_distribution) + + total_assigner_distribution = QuotaDistribution.objects.filter( + Q(assigner_organization=organization) + ).aggregate( + total=Sum('weight') + )['total'] or 0 + + instance.remaining_weight = total_assigned_distribution - total_assigner_distribution + instance.distributed = total_assigner_distribution + instance._from_signal = True + instance.save(update_fields=['remaining_weight', 'distributed']) + + @receiver(post_save, sender=QuotaDistribution) @receiver(post_delete, sender=QuotaDistribution) def update_quota_remaining(sender, instance, **kwargs): + recalculate_remaining_amount(instance.quota) + if getattr(instance, '_from_signal', False): + return + remaining_distribution_weight(instance) def update_product_stats(instance: Product): 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 bdb8f24..de4efc8 100644 --- a/apps/product/web/api/v1/viewsets/quota_distribution_api.py +++ b/apps/product/web/api/v1/viewsets/quota_distribution_api.py @@ -44,6 +44,15 @@ class QuotaDistributionViewSet(viewsets.ModelViewSet): start_date = params.get('start') end_date = params.get('end') + search = QuotaDistributionSearch( + query, + start_date, + end_date + ) + + serializer = self.serializer_class(search.search(), many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + @transaction.atomic def create(self, request, *args, **kwargs): """ create distribution for organizations users """