rancher incentive plan
This commit is contained in:
39
apps/product/migrations/0076_incentiveplanrancher.py
Normal file
39
apps/product/migrations/0076_incentiveplanrancher.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Generated by Django 5.0 on 2025-09-23 12:12
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('herd', '0018_rancher_dhi_state'),
|
||||||
|
('livestock', '0015_livestocktype_en_name_alter_livestocktype_name'),
|
||||||
|
('product', '0075_historicalquotadistribution_free_sale_balance_and_more'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='IncentivePlanRancher',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('create_date', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('modify_date', models.DateTimeField(auto_now=True)),
|
||||||
|
('creator_info', models.CharField(max_length=100, null=True)),
|
||||||
|
('modifier_info', models.CharField(max_length=100, null=True)),
|
||||||
|
('trash', models.BooleanField(default=False)),
|
||||||
|
('allowed_quantity', models.PositiveBigIntegerField(default=0)),
|
||||||
|
('used_quantity', models.PositiveBigIntegerField(default=0)),
|
||||||
|
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('livestock_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rancher_plans', to='livestock.livestocktype')),
|
||||||
|
('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('plan', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rancher_plans', to='product.incentiveplan')),
|
||||||
|
('rancher', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='plans', to='herd.rancher')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -6,6 +6,7 @@ from apps.authorization.models import UserRelations
|
|||||||
from apps.authentication.models import OrganizationType, Organization
|
from apps.authentication.models import OrganizationType, Organization
|
||||||
from django.contrib.postgres.fields import ArrayField
|
from django.contrib.postgres.fields import ArrayField
|
||||||
from apps.livestock.models import LiveStockType
|
from apps.livestock.models import LiveStockType
|
||||||
|
from apps.herd.models import Rancher
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import jdatetime
|
import jdatetime
|
||||||
|
|
||||||
@@ -312,6 +313,35 @@ class IncentivePlan(BaseModel):
|
|||||||
return super(IncentivePlan, self).save(*args, **kwargs)
|
return super(IncentivePlan, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class IncentivePlanRancher(BaseModel):
|
||||||
|
plan = models.ForeignKey(
|
||||||
|
IncentivePlan,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='rancher_plans',
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
rancher = models.ForeignKey(
|
||||||
|
Rancher,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='plans',
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
livestock_type = models.ForeignKey(
|
||||||
|
LiveStockType,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='rancher_plans',
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
allowed_quantity = models.PositiveBigIntegerField(default=0)
|
||||||
|
used_quantity = models.PositiveBigIntegerField(default=0)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.plan.name}-{self.rancher.first_name}-{self.livestock_type.name}'
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
return super(IncentivePlanRancher, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Quota(BaseModel):
|
class Quota(BaseModel):
|
||||||
""" quota for product with some conditions """
|
""" quota for product with some conditions """
|
||||||
|
|
||||||
@@ -428,7 +458,7 @@ class QuotaStats(BaseModel):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'Quota: {self.quota.quota_id} stats'
|
return f'Quota: {self.quota.quota_id} stats'
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
return super(QuotaStats, self).save(*args, **kwargs)
|
return super(QuotaStats, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|||||||
@@ -155,3 +155,9 @@ class IncentivePlanSerializer(serializers.ModelSerializer): # noqa
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = product_models.IncentivePlan
|
model = product_models.IncentivePlan
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class IncentivePlanRancherSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = product_models.IncentivePlanRancher
|
||||||
|
fields = '__all__'
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ router.register(r'attribute_value', product_api.AttributeValueViewSet, basename=
|
|||||||
router.register(r'broker', product_api.BrokerViewSet, basename='broker')
|
router.register(r'broker', product_api.BrokerViewSet, basename='broker')
|
||||||
router.register(r'sale_unit', product_api.SaleUnitViewSet, basename='sale_unit')
|
router.register(r'sale_unit', product_api.SaleUnitViewSet, basename='sale_unit')
|
||||||
router.register(r'incentive_plan', product_api.IncentivePlanViewSet, basename='incentive_plan')
|
router.register(r'incentive_plan', product_api.IncentivePlanViewSet, basename='incentive_plan')
|
||||||
|
router.register(r'rancher_incentive_plan', product_api.IncentivePlanRancherViewSet, basename='rancher_incentive_plan')
|
||||||
router.register(r'stats', product_api.ProductStatsViewSet, basename='stats')
|
router.register(r'stats', product_api.ProductStatsViewSet, basename='stats')
|
||||||
router.register(r'quota', quota_api.QuotaViewSet, basename='quota')
|
router.register(r'quota', quota_api.QuotaViewSet, basename='quota')
|
||||||
router.register(r'quota_distribution', distribution_apis.QuotaDistributionViewSet, basename='quota_distribution')
|
router.register(r'quota_distribution', distribution_apis.QuotaDistributionViewSet, basename='quota_distribution')
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ import datetime
|
|||||||
from apps.product.web.api.v1.serializers import product_serializers as product_serializers
|
from apps.product.web.api.v1.serializers import product_serializers as product_serializers
|
||||||
from apps.product.web.api.v1.serializers import quota_serializers
|
from apps.product.web.api.v1.serializers import quota_serializers
|
||||||
from apps.core.mixins.soft_delete_mixin import SoftDeleteMixin
|
from apps.core.mixins.soft_delete_mixin import SoftDeleteMixin
|
||||||
|
from apps.core.mixins.search_mixin import DynamicSearchMixin
|
||||||
from common.helpers import get_organization_by_user
|
from common.helpers import get_organization_by_user
|
||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException
|
||||||
from apps.product import models as product_models
|
from apps.product import models as product_models
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework import viewsets, filters
|
from rest_framework import viewsets, filters
|
||||||
|
from common.tools import CustomOperations
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
@@ -27,7 +29,7 @@ def delete(queryset, pk):
|
|||||||
obj.delete()
|
obj.delete()
|
||||||
|
|
||||||
|
|
||||||
class ProductCategoryViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
class ProductCategoryViewSet(viewsets.ModelViewSet, SoftDeleteMixin, DynamicSearchMixin):
|
||||||
queryset = product_models.ProductCategory.objects.all()
|
queryset = product_models.ProductCategory.objects.all()
|
||||||
serializer_class = product_serializers.ProductCategorySerializer
|
serializer_class = product_serializers.ProductCategorySerializer
|
||||||
filter_backends = [filters.SearchFilter]
|
filter_backends = [filters.SearchFilter]
|
||||||
@@ -65,7 +67,7 @@ class ProductCategoryViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
|||||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
class ProductViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
class ProductViewSet(viewsets.ModelViewSet, SoftDeleteMixin, DynamicSearchMixin):
|
||||||
queryset = product_models.Product.objects.all()
|
queryset = product_models.Product.objects.all()
|
||||||
serializer_class = product_serializers.ProductSerializer
|
serializer_class = product_serializers.ProductSerializer
|
||||||
filter_backends = [filters.SearchFilter]
|
filter_backends = [filters.SearchFilter]
|
||||||
@@ -144,7 +146,7 @@ class ProductViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
|||||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
class ProductStatsViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
class ProductStatsViewSet(viewsets.ModelViewSet, SoftDeleteMixin, DynamicSearchMixin):
|
||||||
""" product statistics by its quotas """
|
""" product statistics by its quotas """
|
||||||
|
|
||||||
queryset = product_models.ProductStats.objects.all()
|
queryset = product_models.ProductStats.objects.all()
|
||||||
@@ -175,7 +177,7 @@ class ProductStatsViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
|||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
class AttributeViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
class AttributeViewSet(viewsets.ModelViewSet, SoftDeleteMixin, DynamicSearchMixin):
|
||||||
""" attributes of reference product """ #
|
""" attributes of reference product """ #
|
||||||
|
|
||||||
queryset = product_models.Attribute.objects.select_related('product').all()
|
queryset = product_models.Attribute.objects.select_related('product').all()
|
||||||
@@ -233,7 +235,7 @@ class AttributeViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
|||||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
class AttributeValueViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
class AttributeValueViewSet(viewsets.ModelViewSet, SoftDeleteMixin, DynamicSearchMixin):
|
||||||
""" apis for attribute values of child products """ # noqa
|
""" apis for attribute values of child products """ # noqa
|
||||||
|
|
||||||
queryset = product_models.AttributeValue.objects.all()
|
queryset = product_models.AttributeValue.objects.all()
|
||||||
@@ -271,7 +273,7 @@ class AttributeValueViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
|||||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
class BrokerViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
class BrokerViewSet(viewsets.ModelViewSet, SoftDeleteMixin, DynamicSearchMixin):
|
||||||
""" apis of product brokers """ # noqa
|
""" apis of product brokers """ # noqa
|
||||||
|
|
||||||
queryset = product_models.Broker.objects.all()
|
queryset = product_models.Broker.objects.all()
|
||||||
@@ -311,7 +313,7 @@ class BrokerViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
|||||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
class SaleUnitViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
class SaleUnitViewSet(viewsets.ModelViewSet, SoftDeleteMixin, DynamicSearchMixin):
|
||||||
""" apis of unit of sale for products """ # noqa
|
""" apis of unit of sale for products """ # noqa
|
||||||
|
|
||||||
queryset = product_models.SaleUnit.objects.all()
|
queryset = product_models.SaleUnit.objects.all()
|
||||||
@@ -351,7 +353,7 @@ class SaleUnitViewSet(viewsets.ModelViewSet, SoftDeleteMixin):
|
|||||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
class IncentivePlanViewSet(viewsets.ModelViewSet, SoftDeleteMixin): # noqa
|
class IncentivePlanViewSet(viewsets.ModelViewSet, SoftDeleteMixin, DynamicSearchMixin): # noqa
|
||||||
""" apis for incentive plan """
|
""" apis for incentive plan """
|
||||||
|
|
||||||
queryset = product_models.IncentivePlan.objects.all()
|
queryset = product_models.IncentivePlan.objects.all()
|
||||||
@@ -439,3 +441,8 @@ class IncentivePlanViewSet(viewsets.ModelViewSet, SoftDeleteMixin): # noqa
|
|||||||
return Response(status=status.HTTP_200_OK)
|
return Response(status=status.HTTP_200_OK)
|
||||||
except APIException as e:
|
except APIException as e:
|
||||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
|
class IncentivePlanRancherViewSet(viewsets.ModelViewSet, SoftDeleteMixin, DynamicSearchMixin):
|
||||||
|
queryset = product_models.IncentivePlanRancher.objects.all()
|
||||||
|
serializer_class = product_serializers.IncentivePlanRancherSerializer
|
||||||
|
|||||||
Reference in New Issue
Block a user