deploy product & quota base system
This commit is contained in:
@@ -3,7 +3,6 @@ from apps.authorization.api.v1.serializers import (
|
||||
PermissionSerializer,
|
||||
RoleSerializer
|
||||
)
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import serializers
|
||||
from apps.authentication.models import (
|
||||
User,
|
||||
@@ -18,6 +17,8 @@ import typing
|
||||
|
||||
|
||||
class CitySerializer(serializers.ModelSerializer):
|
||||
""" Serialize city data """
|
||||
|
||||
class Meta:
|
||||
model = City
|
||||
fields = [
|
||||
@@ -27,6 +28,8 @@ class CitySerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class ProvinceSerializer(serializers.ModelSerializer):
|
||||
""" Serialize province data """
|
||||
|
||||
class Meta:
|
||||
model = Province
|
||||
fields = [
|
||||
@@ -36,6 +39,8 @@ class ProvinceSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class BankAccountSerializer(serializers.ModelSerializer):
|
||||
""" Serialize bank account data """
|
||||
|
||||
class Meta:
|
||||
model = BankAccountInformation
|
||||
fields = [
|
||||
@@ -63,23 +68,9 @@ class BankAccountSerializer(serializers.ModelSerializer):
|
||||
return instance
|
||||
|
||||
|
||||
class UserDataRelationSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = authorize_models.UserRelations
|
||||
fields = '__all__'
|
||||
|
||||
def to_representation(self, instance):
|
||||
representation = super().to_representation(instance)
|
||||
representation['role'] = RoleSerializer(instance.role).data
|
||||
representation['organization'] = instance.organization.name
|
||||
representation['permissions'] = PermissionSerializer().permissions_structure_output(
|
||||
instance.permissions.all()
|
||||
)
|
||||
|
||||
return representation
|
||||
|
||||
|
||||
class UserSerializer(serializers.ModelSerializer):
|
||||
""" Serialize user data """
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = [
|
||||
@@ -103,11 +94,9 @@ class UserSerializer(serializers.ModelSerializer):
|
||||
]
|
||||
|
||||
def to_representation(self, instance):
|
||||
""" Custom output """
|
||||
|
||||
representation = super().to_representation(instance)
|
||||
if authorize_models.UserRelations.objects.filter(user=instance).exists():
|
||||
representation['relation_data'] = UserDataRelationSerializer(
|
||||
authorize_models.UserRelations.objects.filter(user=instance).first()
|
||||
).data
|
||||
if instance.bank_information.all():
|
||||
representation['bank_account'] = BankAccountSerializer(
|
||||
instance.bank_information.all(), many=True
|
||||
@@ -160,6 +149,8 @@ class UserSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class OrganizationTypeSerializer(serializers.ModelSerializer):
|
||||
""" Serialize organization type data """
|
||||
|
||||
class Meta:
|
||||
model = OrganizationType
|
||||
fields = [
|
||||
@@ -170,6 +161,8 @@ class OrganizationTypeSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class OrganizationSerializer(serializers.ModelSerializer):
|
||||
""" Serialize organization data """
|
||||
|
||||
class Meta:
|
||||
model = Organization
|
||||
fields = [
|
||||
@@ -184,14 +177,16 @@ class OrganizationSerializer(serializers.ModelSerializer):
|
||||
extra_kwargs = {}
|
||||
|
||||
def to_representation(self, instance):
|
||||
""" Custom output """
|
||||
representation = super().to_representation(instance)
|
||||
if isinstance(instance, Organization):
|
||||
representation['province'] = ProvinceSerializer(instance.province).data
|
||||
representation['city'] = CitySerializer(instance.city).data
|
||||
representation['type'] = OrganizationTypeSerializer(instance.type).data
|
||||
if instance.parent_organization:
|
||||
representation['parent_organization'] = OrganizationSerializer(instance.parent_organization).data
|
||||
|
||||
representation['parent_organization'] = OrganizationSerializer(
|
||||
instance.parent_organization
|
||||
).data
|
||||
return representation
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
|
||||
@@ -111,6 +111,12 @@ class UserRelationSerializer(serializers.ModelSerializer):
|
||||
'permissions',
|
||||
]
|
||||
|
||||
extra_kwargs = {
|
||||
'organization': {
|
||||
'required': False
|
||||
}
|
||||
}
|
||||
|
||||
def to_representation(self, instance):
|
||||
""" custom output for serializer """
|
||||
representation = super().to_representation(instance)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# Generated by Django 5.0 on 2025-06-09 10:13
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('product', '0006_alter_saleunit_unit_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='attribute',
|
||||
name='reference_product',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='saleunit',
|
||||
name='reference_product',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='product',
|
||||
name='reference',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='broker',
|
||||
name='reference_product',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='ReferenceProduct',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,132 @@
|
||||
# Generated by Django 5.0 on 2025-06-09 12:38
|
||||
|
||||
import django.contrib.postgres.fields
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('product', '0007_remove_attribute_reference_product_and_more'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='IncentivePlan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='attributevalue',
|
||||
name='product',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='attribute',
|
||||
name='is_global',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='attribute',
|
||||
name='product',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='attributes', to='product.product'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='broker',
|
||||
name='product',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='product_broker', to='product.product'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='saleunit',
|
||||
name='product',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sale_unit', to='product.product'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='attributevalue',
|
||||
name='attribute',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='values', to='product.attribute'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProductCategory',
|
||||
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)),
|
||||
('name', models.CharField(default='empty', max_length=250)),
|
||||
('type', models.CharField(choices=[('F', 'Free'), ('G', 'Governmental')], default='empty', max_length=3)),
|
||||
('img', models.CharField(default='empty', max_length=100)),
|
||||
('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)),
|
||||
('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)),
|
||||
('parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='parents', to='product.productcategory')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='product',
|
||||
name='category',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='products', to='product.productcategory'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Quota',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('sale_type', models.CharField(choices=[('free', 'آزاد'), ('gov', 'دولتی')], max_length=50)),
|
||||
('month_choices', django.contrib.postgres.fields.ArrayField(base_field=models.IntegerField(), null=True, size=None)),
|
||||
('group', models.CharField(choices=[('roostaei', 'روستایی'), ('sanati', 'صنعتی'), ('ashayeri', 'عشایری')], max_length=50)),
|
||||
('has_distribution_limit', models.BooleanField(default=False)),
|
||||
('distribution_mode', models.CharField(blank=True, max_length=50, null=True)),
|
||||
('base_price_factory', models.DecimalField(decimal_places=2, max_digits=12)),
|
||||
('base_price_cooperative', models.DecimalField(decimal_places=2, max_digits=12)),
|
||||
('final_price', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True)),
|
||||
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quota', to='product.product')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='attributevalue',
|
||||
name='quota',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='attribute_values', to='product.quota'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='QuotaBrokerValue',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('value', models.DecimalField(decimal_places=2, max_digits=12)),
|
||||
('broker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='values', to='product.broker')),
|
||||
('quota', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='broker_values', to='product.quota')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='QuotaIncentiveAssignment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('heavy_value', models.DecimalField(decimal_places=2, max_digits=12)),
|
||||
('light_value', models.DecimalField(decimal_places=2, max_digits=12)),
|
||||
('incentive_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quota_assignment', to='product.incentiveplan')),
|
||||
('quota', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='incentive_assignments', to='product.quota')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='QuotaLivestockAllocation',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('livestock_group', models.CharField(choices=[('roostaei', 'روستایی'), ('sanati', 'صنعتی'), ('ashayeri', 'عشایری')], max_length=20)),
|
||||
('livestock_type', models.CharField(choices=[('light', 'سبک'), ('heavy', 'سنگین')], max_length=20)),
|
||||
('livestock_subtype', models.CharField(choices=[('milking', 'شیری'), ('fattening', 'پرواری')], max_length=20)),
|
||||
('quantity_kg', models.DecimalField(decimal_places=2, max_digits=12)),
|
||||
('quota', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='livestock_allocations', to='product.quota')),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('quota', 'livestock_group', 'livestock_type', 'livestock_subtype')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,26 +1,49 @@
|
||||
from django.db import models
|
||||
from apps.core.models import BaseModel
|
||||
from apps.authorization.models import UserRelations
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
|
||||
|
||||
class LivestockGroup(models.TextChoices):
|
||||
ROOSTAEI = "roostaei", "روستایی" # noqa
|
||||
SANATI = "sanati", "صنعتی" # noqa
|
||||
ASHAYERI = "ashayeri", "عشایری" # noqa
|
||||
|
||||
|
||||
class LivestockType(models.TextChoices):
|
||||
LIGHT = "light", "سبک"
|
||||
HEAVY = "heavy", "سنگین" # noqa
|
||||
|
||||
|
||||
class LivestockSubtype(models.TextChoices):
|
||||
MILKING = "milking", "شیری" # noqa
|
||||
FATTENING = "fattening", "پرواری" # noqa
|
||||
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class ReferenceProduct(BaseModel):
|
||||
""" Reference product - like: rice """
|
||||
class ProductCategory(BaseModel):
|
||||
""" Category for products """
|
||||
|
||||
name = models.CharField(max_length=250, default='empty') # noqa
|
||||
type_choices = (
|
||||
('F', 'Free'), # free product
|
||||
('G', 'Governmental') # government product
|
||||
)
|
||||
type = models.CharField(max_length=3, choices=type_choices)
|
||||
type = models.CharField(max_length=3, choices=type_choices, default='empty')
|
||||
img = models.CharField(max_length=100, default='empty')
|
||||
parent = models.ForeignKey(
|
||||
'self',
|
||||
on_delete=models.CASCADE,
|
||||
related_name='parents',
|
||||
null=True
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f'name: {self.name} - type: {self.type}'
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super(ReferenceProduct, self).save(*args, **kwargs)
|
||||
super(ProductCategory, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class Product(BaseModel):
|
||||
@@ -28,14 +51,14 @@ class Product(BaseModel):
|
||||
name = models.CharField(max_length=250, default='empty') # noqa
|
||||
type_choices = (
|
||||
('F', 'Free'), # free product
|
||||
('G', 'Governmental') #
|
||||
('G', 'Governmental') # government product
|
||||
)
|
||||
type = models.CharField(max_length=3, choices=type_choices)
|
||||
img = models.CharField(max_length=100, default='empty')
|
||||
reference = models.ForeignKey(
|
||||
ReferenceProduct,
|
||||
category = models.ForeignKey(
|
||||
ProductCategory,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='reference_product',
|
||||
related_name='products',
|
||||
null=True
|
||||
)
|
||||
|
||||
@@ -50,10 +73,10 @@ class Attribute(BaseModel):
|
||||
"""
|
||||
every reference product have multiple attributes
|
||||
"""
|
||||
reference_product = models.ForeignKey(
|
||||
ReferenceProduct,
|
||||
product = models.ForeignKey(
|
||||
Product,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='reference_attribute',
|
||||
related_name='attributes',
|
||||
null=True
|
||||
)
|
||||
name = models.CharField(max_length=100, default='empty')
|
||||
@@ -68,8 +91,10 @@ class Attribute(BaseModel):
|
||||
help_text='type of attribute like: calculate product by kilogram'
|
||||
)
|
||||
|
||||
is_global = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.reference_product.name} - {self.name}'
|
||||
return f'{self.product.name} - {self.name}'
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return super(Attribute, self).save(*args, **kwargs)
|
||||
@@ -80,22 +105,23 @@ class AttributeValue(BaseModel):
|
||||
every child product should have attribute value for
|
||||
reference product attribute
|
||||
"""
|
||||
product = models.ForeignKey(
|
||||
Product,
|
||||
|
||||
quota = models.ForeignKey(
|
||||
'Quota',
|
||||
on_delete=models.CASCADE,
|
||||
related_name='product_attribute_value',
|
||||
related_name='attribute_values',
|
||||
null=True
|
||||
)
|
||||
attribute = models.ForeignKey(
|
||||
Attribute,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='attribute_value',
|
||||
related_name='values',
|
||||
null=True
|
||||
)
|
||||
value = models.IntegerField(default=0)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.product.name} - {self.attribute.name} - {self.value}'
|
||||
return f'Quota({self.quota.id}) - {self.attribute.name} - {self.value}'
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return super(AttributeValue, self).save(*args, **kwargs)
|
||||
@@ -104,8 +130,8 @@ class AttributeValue(BaseModel):
|
||||
class Broker(BaseModel):
|
||||
""" Broker for product """
|
||||
|
||||
reference_product = models.ForeignKey(
|
||||
ReferenceProduct,
|
||||
product = models.ForeignKey(
|
||||
Product,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='product_broker',
|
||||
null=True
|
||||
@@ -128,7 +154,7 @@ class Broker(BaseModel):
|
||||
required = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.organization_relations.organization.name} - {self.reference_product.name}'
|
||||
return f'{self.organization_relations.organization.name} - {self.product.name}'
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return super(Broker, self).save(*args, **kwargs)
|
||||
@@ -137,8 +163,8 @@ class Broker(BaseModel):
|
||||
class SaleUnit(BaseModel):
|
||||
""" Units of product for sale """
|
||||
|
||||
reference_product = models.ForeignKey(
|
||||
ReferenceProduct,
|
||||
product = models.ForeignKey(
|
||||
Product,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='sale_unit',
|
||||
null=True
|
||||
@@ -153,4 +179,109 @@ class SaleUnit(BaseModel):
|
||||
required = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.reference_product} - {self.unit} - {self.variation_coefficient}'
|
||||
return f'{self.product.name} - {self.unit} - {self.variation_coefficient}'
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return super(SaleUnit, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class IncentivePlan(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
description = models.TextField(blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return super(IncentivePlan, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class Quota(models.Model):
|
||||
product = models.ForeignKey(
|
||||
Product,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='quota'
|
||||
)
|
||||
sale_type = models.CharField(max_length=50, choices=[("free", "آزاد"), ("gov", "دولتی")]) # noqa
|
||||
month_choices = ArrayField(base_field=models.IntegerField(), null=True)
|
||||
group = models.CharField(
|
||||
max_length=50,
|
||||
choices=[("roostaei", "روستایی"), ("sanati", "صنعتی"), ("ashayeri", "عشایری")] # noqa
|
||||
)
|
||||
has_distribution_limit = models.BooleanField(default=False)
|
||||
distribution_mode = models.CharField(max_length=50, 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)
|
||||
final_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"Quota ({self.id}) for {self.product.name}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return super(Quota, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class QuotaIncentiveAssignment(models.Model):
|
||||
quota = models.ForeignKey(
|
||||
Quota,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="incentive_assignments",
|
||||
null=True
|
||||
)
|
||||
incentive_plan = models.ForeignKey(
|
||||
IncentivePlan,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='quota_assignment'
|
||||
)
|
||||
heavy_value = models.DecimalField(max_digits=12, decimal_places=2)
|
||||
light_value = models.DecimalField(max_digits=12, decimal_places=2)
|
||||
|
||||
def __str__(self):
|
||||
return f"Quota ({self.quota.id}) for {self.incentive_plan.name}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return super(QuotaIncentiveAssignment, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class QuotaBrokerValue(models.Model):
|
||||
quota = models.ForeignKey(
|
||||
Quota,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="broker_values",
|
||||
null=True
|
||||
)
|
||||
broker = models.ForeignKey(
|
||||
Broker,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='values'
|
||||
)
|
||||
value = models.DecimalField(max_digits=12, decimal_places=2)
|
||||
|
||||
def __str__(self):
|
||||
return f"Quota ({self.quota.id}) for Broker({self.broker.organization_relations.organization.name})"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return super(QuotaBrokerValue, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class QuotaLivestockAllocation(models.Model):
|
||||
quota = models.ForeignKey(
|
||||
"Quota",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="livestock_allocations",
|
||||
null=True
|
||||
)
|
||||
livestock_group = models.CharField(max_length=20, choices=LivestockGroup.choices)
|
||||
livestock_type = models.CharField(max_length=20, choices=LivestockType.choices)
|
||||
livestock_subtype = models.CharField(max_length=20, choices=LivestockSubtype.choices)
|
||||
quantity_kg = models.DecimalField(max_digits=12, decimal_places=2)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('quota', 'livestock_group', 'livestock_type', 'livestock_subtype')
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.livestock_group} - {self.livestock_type}/{self.livestock_subtype}: {self.quantity_kg}kg"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return super(QuotaLivestockAllocation, self).save(*args, **kwargs)
|
||||
|
||||
@@ -57,42 +57,6 @@ class ProductViewSet(viewsets.ModelViewSet):
|
||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class ReferenceProductViewSet(viewsets.ModelViewSet):
|
||||
queryset = product_models.ReferenceProduct.objects.all()
|
||||
serializer_class = product_serializers.ReferenceProductSerializer
|
||||
|
||||
@action(
|
||||
methods=['put'],
|
||||
detail=True,
|
||||
url_path='trash',
|
||||
url_name='trash',
|
||||
name='trash',
|
||||
)
|
||||
@transaction.atomic
|
||||
def trash(self, request, pk=None):
|
||||
""" Sent product to trash """
|
||||
try:
|
||||
trash(self.queryset, pk)
|
||||
except APIException as e:
|
||||
return Response(e, status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(
|
||||
methods=['post'],
|
||||
detail=True,
|
||||
url_name='delete',
|
||||
url_path='delete',
|
||||
name='delete'
|
||||
)
|
||||
@transaction.atomic
|
||||
def delete(self, request, pk=None):
|
||||
""" Full delete of product object """
|
||||
try:
|
||||
delete(self.queryset, pk)
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
except APIException as e:
|
||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class AttributeViewSet(viewsets.ModelViewSet):
|
||||
""" attributes of reference product """
|
||||
|
||||
@@ -243,3 +207,193 @@ class SaleUnitViewSet(viewsets.ModelViewSet):
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
except APIException as e:
|
||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class IncentivePlanViewSet(viewsets.ModelViewSet):
|
||||
""" apis for incentive plan """
|
||||
|
||||
queryset = product_models.IncentivePlan.objects.all()
|
||||
serializer_class = product_serializers.IncentivePlanSerializer
|
||||
|
||||
@action(
|
||||
methods=['put'],
|
||||
detail=True,
|
||||
url_path='trash',
|
||||
url_name='trash',
|
||||
name='trash',
|
||||
)
|
||||
@transaction.atomic
|
||||
def trash(self, request, pk=None):
|
||||
""" Sent incentive plan to trash """
|
||||
try:
|
||||
trash(self.queryset, pk)
|
||||
except APIException as e:
|
||||
return Response(e, status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(
|
||||
methods=['post'],
|
||||
detail=True,
|
||||
url_name='delete',
|
||||
url_path='delete',
|
||||
name='delete'
|
||||
)
|
||||
@transaction.atomic
|
||||
def delete(self, request, pk=None):
|
||||
""" Full delete of incentive plan object """
|
||||
try:
|
||||
delete(self.queryset, pk)
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
except APIException as e:
|
||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class QuotaViewSet(viewsets.ModelViewSet):
|
||||
""" apis for product quota """
|
||||
|
||||
queryset = product_models.Quota.objects.all()
|
||||
serializer_class = product_serializers.QuotaSerializer
|
||||
|
||||
@action(
|
||||
methods=['put'],
|
||||
detail=True,
|
||||
url_path='trash',
|
||||
url_name='trash',
|
||||
name='trash',
|
||||
)
|
||||
@transaction.atomic
|
||||
def trash(self, request, pk=None):
|
||||
""" Sent quota to trash """
|
||||
try:
|
||||
trash(self.queryset, pk)
|
||||
except APIException as e:
|
||||
return Response(e, status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(
|
||||
methods=['post'],
|
||||
detail=True,
|
||||
url_name='delete',
|
||||
url_path='delete',
|
||||
name='delete'
|
||||
)
|
||||
@transaction.atomic
|
||||
def delete(self, request, pk=None):
|
||||
""" Full delete of quota object """
|
||||
try:
|
||||
delete(self.queryset, pk)
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
except APIException as e:
|
||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class QuotaIncentiveAssignmentViewSet(viewsets.ModelViewSet):
|
||||
""" apis for incentive assignment """
|
||||
|
||||
queryset = product_models.QuotaIncentiveAssignment.objects.all()
|
||||
serializer_class = product_serializers.QuotaIncentiveAssignmentSerializer
|
||||
|
||||
@action(
|
||||
methods=['put'],
|
||||
detail=True,
|
||||
url_path='trash',
|
||||
url_name='trash',
|
||||
name='trash',
|
||||
)
|
||||
@transaction.atomic
|
||||
def trash(self, request, pk=None):
|
||||
""" Sent quota incentive assignment to trash """
|
||||
try:
|
||||
trash(self.queryset, pk)
|
||||
except APIException as e:
|
||||
return Response(e, status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(
|
||||
methods=['post'],
|
||||
detail=True,
|
||||
url_name='delete',
|
||||
url_path='delete',
|
||||
name='delete'
|
||||
)
|
||||
@transaction.atomic
|
||||
def delete(self, request, pk=None):
|
||||
""" Full delete of quota incentive assignment object """
|
||||
try:
|
||||
delete(self.queryset, pk)
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
except APIException as e:
|
||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class QuotaBrokerValueViewSet(viewsets.ModelViewSet): # noqa
|
||||
""" apis for quota broker value """
|
||||
|
||||
queryset = product_models.QuotaBrokerValue.objects.all()
|
||||
serializer_class = product_serializers.QuotaBrokerValueSerializer
|
||||
|
||||
@action(
|
||||
methods=['put'],
|
||||
detail=True,
|
||||
url_path='trash',
|
||||
url_name='trash',
|
||||
name='trash',
|
||||
)
|
||||
@transaction.atomic
|
||||
def trash(self, request, pk=None):
|
||||
""" Sent quota broker value to trash """
|
||||
try:
|
||||
trash(self.queryset, pk)
|
||||
except APIException as e:
|
||||
return Response(e, status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(
|
||||
methods=['post'],
|
||||
detail=True,
|
||||
url_name='delete',
|
||||
url_path='delete',
|
||||
name='delete'
|
||||
)
|
||||
@transaction.atomic
|
||||
def delete(self, request, pk=None):
|
||||
""" Full delete of quota broker value object """
|
||||
try:
|
||||
delete(self.queryset, pk)
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
except APIException as e:
|
||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class QuotaLiveStockAllocationViewSet(viewsets.ModelViewSet):
|
||||
""" apis for quota livestock allocation """
|
||||
|
||||
queryset = product_models.QuotaLivestockAllocation.objects.all()
|
||||
serializer_class = product_serializers.QuotaLiveStockAllocationSerializer
|
||||
|
||||
@action(
|
||||
methods=['put'],
|
||||
detail=True,
|
||||
url_path='trash',
|
||||
url_name='trash',
|
||||
name='trash',
|
||||
)
|
||||
@transaction.atomic
|
||||
def trash(self, request, pk=None):
|
||||
""" Sent quota livestock allocation to trash """
|
||||
try:
|
||||
trash(self.queryset, pk)
|
||||
except APIException as e:
|
||||
return Response(e, status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(
|
||||
methods=['post'],
|
||||
detail=True,
|
||||
url_name='delete',
|
||||
url_path='delete',
|
||||
name='delete'
|
||||
)
|
||||
@transaction.atomic
|
||||
def delete(self, request, pk=None):
|
||||
""" Full delete of quota livestock allocation object """
|
||||
try:
|
||||
delete(self.queryset, pk)
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
except APIException as e:
|
||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@@ -3,14 +3,6 @@ from apps.product import models as product_models
|
||||
from apps.authorization.api.v1 import serializers as authorize_serializers
|
||||
|
||||
|
||||
class ReferenceProductSerializer(serializers.ModelSerializer):
|
||||
""" Serializer of reference product """
|
||||
|
||||
class Meta:
|
||||
model = product_models.ReferenceProduct
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class ProductSerializer(serializers.ModelSerializer):
|
||||
""" Serializer of product """
|
||||
|
||||
@@ -22,8 +14,6 @@ class ProductSerializer(serializers.ModelSerializer):
|
||||
""" Custom output of product serializer """
|
||||
|
||||
representation = super().to_representation(instance)
|
||||
if instance.reference:
|
||||
representation['reference'] = ReferenceProductSerializer(instance.reference).data
|
||||
|
||||
return representation
|
||||
|
||||
@@ -37,11 +27,6 @@ class AttributeSerializer(serializers.ModelSerializer):
|
||||
|
||||
def to_representation(self, instance):
|
||||
representation = super().to_representation(instance)
|
||||
if instance.reference_product:
|
||||
representation['reference_product'] = ReferenceProductSerializer(
|
||||
instance.reference_product
|
||||
).data
|
||||
|
||||
return representation
|
||||
|
||||
|
||||
@@ -73,10 +58,6 @@ class BrokerSerializer(serializers.ModelSerializer):
|
||||
|
||||
def to_representation(self, instance):
|
||||
representation = super().to_representation(instance)
|
||||
if instance.reference_product:
|
||||
representation['reference_product'] = ReferenceProductSerializer(
|
||||
instance.reference_product
|
||||
).data
|
||||
if instance.organization_relations:
|
||||
representation['organization_relations'] = authorize_serializers.UserRelationSerializer(
|
||||
instance.organization_relations
|
||||
@@ -94,9 +75,34 @@ class SaleUnitSerializer(serializers.ModelSerializer):
|
||||
|
||||
def to_representation(self, instance):
|
||||
representation = super().to_representation(instance)
|
||||
if instance.reference_product:
|
||||
representation['reference_product'] = ReferenceProductSerializer(
|
||||
instance.reference_product
|
||||
).data
|
||||
|
||||
return representation
|
||||
|
||||
|
||||
class IncentivePlanSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = product_models.IncentivePlan
|
||||
fields = '__all_'
|
||||
|
||||
|
||||
class QuotaSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = product_models.Quota
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class QuotaIncentiveAssignmentSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = product_models.QuotaIncentiveAssignment
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class QuotaBrokerValueSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = product_models.QuotaBrokerValue
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class QuotaLiveStockAllocationSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = product_models.QuotaLivestockAllocation
|
||||
fields = '__all__'
|
||||
|
||||
@@ -4,7 +4,6 @@ from django.urls import path, include
|
||||
|
||||
router = DefaultRouter()
|
||||
router.register(r'product', api_views.ProductViewSet, basename='product')
|
||||
router.register(r'reference', api_views.ReferenceProductViewSet, basename='reference')
|
||||
router.register(r'attribute', api_views.AttributeViewSet, basename='attribute')
|
||||
router.register(r'attribute_value', api_views.AttributeValueViewSet, basename='attribute_value')
|
||||
router.register(r'broker', api_views.BrokerViewSet, basename='broker')
|
||||
|
||||
Reference in New Issue
Block a user