You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
6.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from django.db import models
# Справочник товаров
class Product(models.Model):
name = models.CharField(max_length=255, verbose_name="Наименование товара")
manufacturer_name = models.CharField(max_length=255, verbose_name="Производитель")
manufacturer_country = models.CharField(max_length=255, verbose_name="Страна производителя")
manufacturer_code = models.CharField(max_length=50, verbose_name="Код производителя", blank=True, null=True)
dimensions = models.CharField(max_length=255, verbose_name="Размеры", blank=True, null=True)
unit_of_measure = models.CharField(max_length=50, verbose_name="Единица измерения")
shelf_life_days = models.IntegerField(verbose_name="Срок годности (дни)")
barcode = models.CharField(max_length=50, unique=True, verbose_name="Штрихкод")
def __str__(self):
return self.name
# Типы цен (например, регулярная, скидочная, акционная)
class PriceType(models.Model):
name = models.CharField(max_length=50, verbose_name="Тип цены", choices=[
('regular', 'Регулярная'),
('discount', 'Скидочная'),
('promotional', 'Акционная'),
])
def __str__(self):
return self.name
# Прайс-листы (со всеми ценами)
class PriceList(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="Товар")
price_type = models.ForeignKey(PriceType, on_delete=models.CASCADE, verbose_name="Тип цены")
entry_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Входная цена")
final_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Итоговая цена")
date_effective = models.DateField(verbose_name="Дата вступления в силу")
constraint_percent_limit = models.DecimalField(max_digits=5, decimal_places=2, default=1000, verbose_name="Лимит на наценку (%)")
constraint_price_change = models.DecimalField(max_digits=5, decimal_places=2, default=90, verbose_name="Лимит на изменение цены (%)")
def save(self, *args, **kwargs):
# Логика проверки на изменение цены
if self.pk:
old_price = PriceList.objects.get(pk=self.pk).final_price
price_change_percent = abs((self.final_price - old_price) / old_price) * 100
if price_change_percent > self.constraint_price_change:
raise ValueError(f"Цена не может измениться более чем на {self.constraint_price_change}%")
super().save(*args, **kwargs)
def __str__(self):
return f"{self.product.name} - {self.price_type.name} - {self.final_price} руб."
# Скидки и акции (могут применяться к товарам)
class Discount(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="Товар")
discount_percentage = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Процент скидки")
start_date = models.DateField(verbose_name="Дата начала")
end_date = models.DateField(verbose_name="Дата окончания")
description = models.TextField(verbose_name="Описание акции", blank=True, null=True)
def __str__(self):
return f"Скидка {self.discount_percentage}% на {self.product.name} с {self.start_date} по {self.end_date}"
# История изменений цен
class PriceChangeHistory(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="Товар")
old_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Старая цена")
new_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Новая цена")
change_date = models.DateTimeField(auto_now_add=True, verbose_name="Дата изменения цены")
reason = models.TextField(verbose_name="Причина изменения цены", blank=True, null=True)
def __str__(self):
return f"{self.product.name} - изменение цены с {self.old_price} на {self.new_price} - {self.change_date}"
# Пример использования ценников для печати
class PriceTag(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="Товар")
price_list = models.ForeignKey(PriceList, on_delete=models.CASCADE, verbose_name="Прайс-лист")
tag_image = models.ImageField(upload_to='price_tags/', verbose_name="Изображение ценника", blank=True, null=True)
price_effective_date = models.DateField(verbose_name="Дата вступления в силу ценника")
def __str__(self):
return f"Ценник для {self.product.name} - {self.price_effective_date}"
# Связь с историей акций
class DiscountHistory(models.Model):
discount = models.ForeignKey(Discount, on_delete=models.CASCADE, verbose_name="Акция/Скидка")
old_discount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Старая скидка")
new_discount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Новая скидка")
change_date = models.DateTimeField(auto_now_add=True, verbose_name="Дата изменения скидки")
reason = models.TextField(verbose_name="Причина изменения скидки", blank=True, null=True)
def __str__(self):
return f"Изменение скидки с {self.old_discount}% на {self.new_discount}% для {self.discount.product.name}"
# Пример применения скидки к прайс-листу
class PriceListWithDiscount(models.Model):
price_list = models.ForeignKey(PriceList, on_delete=models.CASCADE, verbose_name="Прайс-лист")
discount = models.ForeignKey(Discount, on_delete=models.CASCADE, verbose_name="Скидка")
final_price_after_discount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Итоговая цена после скидки")
def __str__(self):
return f"{self.price_list.product.name} - {self.final_price_after_discount} руб. (с учетом скидки)"