From b52baa5d3bacc517640f9bd14e5d345bd41c17ee Mon Sep 17 00:00:00 2001 From: Mojtaba-z Date: Tue, 10 Jun 2025 14:53:01 +0330 Subject: [PATCH] list of organizations by province - some changes in quota an models of that --- apps/authentication/api/v1/api.py | 19 +++++++++++- .../api/v1/serializers/serializer.py | 5 ++-- ..._alter_quota_distribution_mode_and_more.py | 25 ++++++++++++++++ apps/product/models.py | 15 ++++++++-- apps/product/web/api/v1/api.py | 30 ++++++++++++++++++- 5 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 apps/product/migrations/0018_alter_quota_distribution_mode_and_more.py diff --git a/apps/authentication/api/v1/api.py b/apps/authentication/api/v1/api.py index 0d92f77..6a459c5 100644 --- a/apps/authentication/api/v1/api.py +++ b/apps/authentication/api/v1/api.py @@ -188,7 +188,6 @@ class OrganizationViewSet(ModelViewSet): """ Crud operations for organization model """ # queryset = Organization.objects.all() serializer_class = OrganizationSerializer - permission_classes = [auth_permissions.CreateOrganization] @transaction.atomic def create(self, request, *args, **kwargs): @@ -217,6 +216,24 @@ class OrganizationViewSet(ModelViewSet): else: return Response(serializer.errors, status=status.HTTP_406_NOT_ACCEPTABLE) + @action( + methods=['get'], + detail=False, + url_path='organizations_by_province', + url_name='organizations_by_province', + name='organizations_by_province' + ) + @transaction.atomic + def get_organizations_by_province(self, request): + """ list of organizations by province """ + + serializer = self.serializer_class( + self.queryset.filter( + province=int(request.GET['province'])), + many=True + ) + return Response(serializer.data, status=status.HTTP_200_OK) + class BankAccountViewSet(ModelViewSet): """ Crud operations for bank account model """ # diff --git a/apps/authentication/api/v1/serializers/serializer.py b/apps/authentication/api/v1/serializers/serializer.py index b9fac7d..3268312 100644 --- a/apps/authentication/api/v1/serializers/serializer.py +++ b/apps/authentication/api/v1/serializers/serializer.py @@ -23,7 +23,8 @@ class CitySerializer(serializers.ModelSerializer): model = City fields = [ 'id', - 'name' + 'name', + 'province' ] @@ -34,7 +35,7 @@ class ProvinceSerializer(serializers.ModelSerializer): model = Province fields = [ 'id', - 'name' + 'name', ] diff --git a/apps/product/migrations/0018_alter_quota_distribution_mode_and_more.py b/apps/product/migrations/0018_alter_quota_distribution_mode_and_more.py new file mode 100644 index 0000000..d1dcfad --- /dev/null +++ b/apps/product/migrations/0018_alter_quota_distribution_mode_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 5.0 on 2025-06-10 11:22 + +import django.contrib.postgres.fields +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('product', '0017_incentiveplan_create_date_incentiveplan_created_by_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='quota', + name='distribution_mode', + field=django.contrib.postgres.fields.ArrayField(base_field=models.IntegerField(), blank=True, null=True, size=None), + ), + migrations.AlterField( + model_name='quotaincentiveassignment', + name='incentive_plan', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='quota_assignment', to='product.incentiveplan'), + ), + ] diff --git a/apps/product/models.py b/apps/product/models.py index 7864573..40cc290 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -192,6 +192,8 @@ class SaleUnit(BaseModel): class IncentivePlan(BaseModel): + """ incentive plan for every quota """ + PLAN_TYPE_CHOICES = ( ('ILQ', 'increasing livestock quotas'), ('SM', 'statistical/monitoring') @@ -226,6 +228,8 @@ class IncentivePlan(BaseModel): class Quota(BaseModel): + """ quota for product with some conditions """ + quota_id = models.CharField(max_length=15, null=True) quota_code = models.CharField(max_length=15, null=True) product = models.ForeignKey( @@ -240,7 +244,7 @@ class Quota(BaseModel): choices=[("rural", "روستایی"), ("industrial", "صنعتی"), ("nomadic", "عشایری")] # noqa ) has_distribution_limit = models.BooleanField(default=False) - distribution_mode = models.CharField(max_length=50, blank=True, null=True) + distribution_mode = ArrayField(base_field=models.IntegerField(), blank=True, null=True) base_price_factory = models.DecimalField(max_digits=12, decimal_places=2) base_price_cooperative = models.DecimalField(max_digits=12, decimal_places=2) @@ -254,6 +258,8 @@ class Quota(BaseModel): class QuotaIncentiveAssignment(BaseModel): + """ assign incentive plan to quota """ + quota = models.ForeignKey( Quota, on_delete=models.CASCADE, @@ -263,7 +269,8 @@ class QuotaIncentiveAssignment(BaseModel): incentive_plan = models.ForeignKey( IncentivePlan, on_delete=models.CASCADE, - related_name='quota_assignment' + related_name='quota_assignment', + null=True ) heavy_value = models.DecimalField(max_digits=12, decimal_places=2) light_value = models.DecimalField(max_digits=12, decimal_places=2) @@ -276,6 +283,8 @@ class QuotaIncentiveAssignment(BaseModel): class QuotaBrokerValue(BaseModel): + """ broker attributes value for quota """ + quota = models.ForeignKey( Quota, on_delete=models.CASCADE, @@ -297,6 +306,8 @@ class QuotaBrokerValue(BaseModel): class QuotaLivestockAllocation(BaseModel): + """ livestock allocation to quota """ + quota = models.ForeignKey( "Quota", on_delete=models.CASCADE, diff --git a/apps/product/web/api/v1/api.py b/apps/product/web/api/v1/api.py index baafb46..0f1bcf4 100644 --- a/apps/product/web/api/v1/api.py +++ b/apps/product/web/api/v1/api.py @@ -251,6 +251,30 @@ class IncentivePlanViewSet(viewsets.ModelViewSet): # noqa queryset = product_models.IncentivePlan.objects.all() serializer_class = product_serializers.IncentivePlanSerializer + @transaction.atomic + def create(self, request, *args, **kwargs): + """ custom incentive plan create object """ + # set incentive plans with user relations like organization + user_relation = product_models.UserRelations.objects.filter(user=request.user).first() + request.data['registering_organization'] = user_relation.id + + serializer = self.serializer_class(data=request.data) + if serializer.is_valid(raise_exception=True): + serializer.save() + + return Response(serializer.data, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN) + + @transaction.atomic + def list(self, request, *args, **kwargs): + """ get incentive plans by user relations like organization """ + + user_relations = product_models.UserRelations.objects.filter(user=request.user).first() + incentive_plans = user_relations.incentive_plans.all() + + serializer = self.serializer_class(incentive_plans, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + @action( methods=['put'], detail=True, @@ -283,12 +307,16 @@ class IncentivePlanViewSet(viewsets.ModelViewSet): # noqa return Response(e, status=status.HTTP_204_NO_CONTENT) -class QuotaViewSet(viewsets.ModelViewSet): +class QuotaViewSet(viewsets.ModelViewSet): # noqa """ apis for product quota """ queryset = product_models.Quota.objects.all() serializer_class = product_serializers.QuotaSerializer + @transaction.atomic + def create(self, request, *args, **kwargs): + pass + @action( methods=['put'], detail=True,