from django.db import models from django.urls import reverse_lazy from django.contrib.postgres.fields import HStoreField from django.utils.translation import ugettext_lazy as _ import mptt from mptt.models import MPTTModel, TreeForeignKey from autoslug import AutoSlugField from core.models import AbstractStatusModel, AbstractDateTimeModel class ProductAttribute(AbstractStatusModel): name = models.CharField(max_length=64, blank=True, null=True, default=None) slug = AutoSlugField(populate_from='name') main_attribute = models.BooleanField(default=False) def __str__(self): return self.name class Meta: ordering = ('slug',) verbose_name = _('Product attribute') verbose_name_plural = _('Product attributes') class Manufacturer(AbstractStatusModel): name = models.CharField(max_length=64, blank=True, null=True, default=None) slug = AutoSlugField(populate_from='name') image = models.ImageField(upload_to='producers', blank=True, verbose_name="image of producer") def __str__(self): return self.name def get_absolute_url(self): return reverse_lazy('products:manufacturer', kwargs={'producer_slug': self.slug, 'path': ''}) #@TODO: tranlsate into english and use traslation class Meta: verbose_name = _('Производитель') verbose_name_plural = _('Производители') class ProductCategory(MPTTModel, AbstractDateTimeModel): name = models.CharField(db_index=True, unique=True, max_length=64, blank=True, null=True, default=None) slug = AutoSlugField(populate_from='name') parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') image = models.ImageField(upload_to='categories', blank=True, verbose_name="image of category") def __str__(self): return self.name class Meta: verbose_name = 'Product\'s category' verbose_name_plural = 'Product\'s categories' ordering = ('tree_id', 'level') class MPTTMeta: order_insertion_by = ['name'] mptt.register(ProductCategory, order_insertion_py=['name']) class Product(AbstractStatusModel): name = models.CharField(max_length=64, db_index=True, blank=True, null=True, default=None) slug = AutoSlugField(populate_from='name') price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) description = models.TextField(db_index=True, blank=True, null=True, default=None) manufacturer = models.ForeignKey(Manufacturer, on_delete=models.PROTECT) image = models.ImageField(upload_to='products', blank=True, verbose_name="image of products") category = models.ForeignKey(ProductCategory, on_delete=models.SET_NULL, blank=True, null=True, default=None) attributes = models.ManyToManyField(ProductAttribute, blank=True) discount_policy = HStoreField(blank=True, null=True, default={}) is_active = models.BooleanField(default=True) def __str__(self): return self.name def get_absolute_url(self): return reverse_lazy('products:item', args=[self.slug]) class Meta: indexes = [ models.Index(fields=['id', 'slug']) ] verbose_name = _('Product') verbose_name_plural = _('Products') # def save(self, *args, **kwargs): # if self.category: # super(Product, self).save(*args, **kwargs) # # for cp in ProductClass.objects.filter(category=self.product_class): # pp = ProductProperty.objects.filter(category_property=cp, # products=self) # if not pp: # pp = ProductProperty(category_property=cp, products=self, value="--") # pp.save() class ProductAttributeValue(AbstractDateTimeModel): product = models.ForeignKey(Product, on_delete=models.PROTECT) name = models.CharField(max_length=64, blank=True, null=True, default=None) slug = AutoSlugField(populate_from='name') attribute = models.ForeignKey(ProductAttribute, on_delete=models.CASCADE, related_name='values') def __str__(self): return self.name class Meta: unique_together = ('name', 'attribute') verbose_name = 'Product attribute value' verbose_name_plural = 'Product attribute values' # class Offer(models.Model): # name = models.CharField(max_length=64, blank=True, null=True, default=None) # slug = AutoSlugField(populate_from='name') # price = models.DecimalField(max_digits=8, decimal_places=2, null=True, default=0.00) # # points = models.DecimalField(max_digits=8, decimal_places=2, null=True, default=0.00) # products = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True, default=None, # related_name='variants') # is_active = models.BooleanField(default=True) # attributes = HStoreField(blank=True, null=True, default={}) # # def __str__(self): # return self.name # # class Meta: # verbose_name = 'Offer' # verbose_name_plural = 'Offers' # # def save(self, *args, **kwargs): # self.points = self.price * decimal.Decimal('0.1') # super(Offer, self).save(*args, **kwargs)