deploy product & quota base system

This commit is contained in:
2025-06-09 16:09:50 +03:30
parent fa9c7dfaf8
commit 5f440c52bd
8 changed files with 562 additions and 107 deletions

View File

@@ -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)