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 ProductCategory(BaseModel): """ Category for products """ name = models.CharField(max_length=250, default='empty') # noqa type_choices = ( ('free', 'Free'), # free product ('gov', 'Governmental') # government product ) type = models.CharField(max_length=5, 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(ProductCategory, self).save(*args, **kwargs) class Product(BaseModel): """ Child of reference product - like: brown rice """ name = models.CharField(max_length=250, default='empty') # noqa type_choices = ( ('free', 'FREE'), # free product ('gov', 'GOVERNMENTAL') # government product ) type = models.CharField(max_length=5, choices=type_choices) img = models.CharField(max_length=100, default='empty') category = models.ForeignKey( ProductCategory, on_delete=models.CASCADE, related_name='products', null=True ) def __str__(self): return f'name: {self.name} - type: {self.type}' def save(self, *args, **kwargs): super(Product, self).save(*args, **kwargs) class Attribute(BaseModel): """ every reference product have multiple attributes """ product = models.ForeignKey( Product, on_delete=models.CASCADE, related_name='attributes', null=True ) name = models.CharField(max_length=100, default='empty') type_choices = ( ('K', 'Per Kilo'), ('', ''), ) type = models.CharField( max_length=10, choices=type_choices, default='empty', help_text='type of attribute like: calculate product by kilogram' ) is_global = models.BooleanField(default=False) def __str__(self): return f'{self.product.name} - {self.name}' def save(self, *args, **kwargs): return super(Attribute, self).save(*args, **kwargs) class AttributeValue(BaseModel): """ every child product should have attribute value for reference product attribute """ quota = models.ForeignKey( 'Quota', on_delete=models.CASCADE, related_name='attribute_values', null=True ) attribute = models.ForeignKey( Attribute, on_delete=models.CASCADE, related_name='values', null=True ) value = models.IntegerField(default=0) def __str__(self): return f'Quota({self.quota.id}) - {self.attribute.name} - {self.value}' def save(self, *args, **kwargs): return super(AttributeValue, self).save(*args, **kwargs) class Broker(BaseModel): """ Broker for product """ CALCULATION_CHOICES = ( ('K', 'Per Kilo'), ('', ''), ) BROKER_TYPES = ( ('public', 'PUBLIC'), ('exclusive', 'EXCLUSIVE') ) product = models.ForeignKey( Product, on_delete=models.CASCADE, related_name='product_broker', null=True ) organization_relations = models.ForeignKey( UserRelations, on_delete=models.CASCADE, related_name='product_organization', null=True ) calculation_strategy = models.CharField( max_length=3, choices=CALCULATION_CHOICES, default='empty' ) broker_type = models.CharField(choices=BROKER_TYPES, max_length=20, null=True) required = models.BooleanField(default=False) def __str__(self): return f'{self.organization_relations.organization.name} - {self.product.name}' def save(self, *args, **kwargs): return super(Broker, self).save(*args, **kwargs) class SaleUnit(BaseModel): """ Units of product for sale """ product = models.ForeignKey( Product, on_delete=models.CASCADE, related_name='sale_unit', null=True ) unit_choices = ( ('10P', '10KG Package'), ('50P', '50KG Package'), ('', ''), ) unit = models.CharField(max_length=10, choices=unit_choices, null=True) variation_coefficient = models.IntegerField(default=0) required = models.BooleanField(default=False) def __str__(self): return f'{self.product.name} - {self.unit} - {self.variation_coefficient}' def save(self, *args, **kwargs): return super(SaleUnit, self).save(*args, **kwargs) class IncentivePlan(BaseModel): """ incentive plan for every quota """ PLAN_TYPE_CHOICES = ( ('ILQ', 'increasing livestock quotas'), ('SM', 'statistical/monitoring') ) GROUP_CHOICES = ( ('industrial', 'Industrial'), ('rural', 'Rural'), ('nomadic', 'Nomadic') ) name = models.CharField(max_length=255) description = models.TextField(blank=True, null=True) registering_organization = models.ForeignKey( UserRelations, on_delete=models.CASCADE, related_name='incentive_plans', null=True ) plan_type = models.CharField(choices=PLAN_TYPE_CHOICES, max_length=5, null=True) group = models.CharField(choices=GROUP_CHOICES, max_length=15, null=True) is_time_unlimited = models.BooleanField(default=False) start_date_limit = models.DateField(null=True, blank=True) end_date_limit = models.DateField(null=True, blank=True) class Meta: unique_together = ('name', 'registering_organization') def __str__(self): return self.name def save(self, *args, **kwargs): return super(IncentivePlan, self).save(*args, **kwargs) 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( 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=[("rural", "روستایی"), ("industrial", "صنعتی"), ("nomadic", "عشایری")] # noqa ) has_distribution_limit = models.BooleanField(default=False) 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) 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(BaseModel): """ assign incentive plan to quota """ 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', null=True ) 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(BaseModel): """ broker attributes value for quota """ 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(BaseModel): """ livestock allocation to quota """ 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)