Files

164 lines
6.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from django.conf import settings
from django.db import models
from apps.catalog.models import Brand, Product, Service
class OrderStatus(models.TextChoices):
NEW = 'new', 'Новый'
CONFIRMED = 'confirmed', 'Подтверждён'
PAID = 'paid', 'Оплачен' # этап 2
ASSEMBLED = 'assembled', 'Собран'
SHIPPED = 'shipped', 'Передан в доставку' # этап 2
DONE = 'done', 'Выполнен'
CANCELLED = 'cancelled', 'Отменён'
REFUNDED = 'refunded', 'Возврат' # этап 2
class DeliveryMethod(models.TextChoices):
PICKUP = 'pickup', 'Самовывоз'
COURIER = 'courier', 'Доставка по договорённости' # этап 1
CDEK = 'cdek', 'СДЭК' # этап 2
class PaymentMethod(models.TextChoices):
BY_AGREEMENT = 'by_agreement', 'По договорённости (напрямую продавцу)'
ONLINE = 'online', 'Онлайн через агрегатор' # этап 2
class PickupPoint(models.Model):
"""Пункт выдачи (ТЗ §4: PickupPoint)."""
name = models.CharField('Название', max_length=200)
address = models.CharField('Адрес', max_length=300)
working_hours = models.CharField('Часы работы', max_length=200, blank=True)
partner = models.CharField('Партнёр', max_length=200, blank=True)
is_active = models.BooleanField('Активен', default=True)
class Meta:
verbose_name = 'Пункт выдачи'
verbose_name_plural = 'Пункты выдачи'
ordering = ('name',)
def __str__(self):
return f'{self.name} ({self.address})'
class Order(models.Model):
"""Заказ / заявка (ТЗ §4: Order)."""
buyer = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.PROTECT,
related_name='orders', verbose_name='Покупатель',
)
status = models.CharField(
'Статус', max_length=20, choices=OrderStatus.choices,
default=OrderStatus.NEW,
)
delivery_method = models.CharField(
'Способ получения', max_length=20,
choices=DeliveryMethod.choices, default=DeliveryMethod.PICKUP,
)
address = models.CharField('Адрес доставки', max_length=300, blank=True)
pickup_point = models.ForeignKey(
PickupPoint, null=True, blank=True, on_delete=models.SET_NULL,
related_name='orders', verbose_name='Пункт выдачи',
)
payment_method = models.CharField(
'Способ оплаты', max_length=20,
choices=PaymentMethod.choices, default=PaymentMethod.BY_AGREEMENT,
)
customer_comment = models.TextField('Комментарий покупателя', blank=True)
total = models.DecimalField('Сумма', max_digits=12, decimal_places=2, default=0)
commission = models.DecimalField(
'Комиссия площадки', max_digits=12, decimal_places=2, default=0,
)
created_at = models.DateTimeField('Создан', auto_now_add=True)
updated_at = models.DateTimeField('Обновлён', auto_now=True)
class Meta:
verbose_name = 'Заказ'
verbose_name_plural = 'Заказы'
ordering = ('-created_at',)
def __str__(self):
return f'Заказ №{self.pk}'
def recalculate_total(self):
self.total = sum((item.line_total for item in self.items.all()), start=0)
self.save(update_fields=['total'])
class OrderItem(models.Model):
"""Позиция заказа. Может относиться к товару или к услуге (ТЗ §4)."""
order = models.ForeignKey(
Order, on_delete=models.CASCADE, related_name='items',
verbose_name='Заказ',
)
brand = models.ForeignKey(
Brand, on_delete=models.PROTECT, related_name='order_items',
verbose_name='Бренд',
)
product = models.ForeignKey(
Product, null=True, blank=True, on_delete=models.SET_NULL,
related_name='order_items', verbose_name='Товар',
)
service = models.ForeignKey(
Service, null=True, blank=True, on_delete=models.SET_NULL,
related_name='order_items', verbose_name='Услуга',
)
name = models.CharField('Название позиции', max_length=255)
price = models.DecimalField('Цена за единицу', max_digits=12, decimal_places=2)
quantity = models.PositiveIntegerField('Количество', default=1)
class Meta:
verbose_name = 'Позиция заказа'
verbose_name_plural = 'Позиции заказа'
def __str__(self):
return f'{self.name} × {self.quantity}'
@property
def line_total(self):
return self.price * self.quantity
class Favorite(models.Model):
"""Избранное покупателя (ТЗ §3.2, §3.3)."""
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
related_name='favorites', verbose_name='Пользователь',
)
product = models.ForeignKey(
Product, null=True, blank=True, on_delete=models.CASCADE,
related_name='favorited_by', verbose_name='Товар',
)
service = models.ForeignKey(
Service, null=True, blank=True, on_delete=models.CASCADE,
related_name='favorited_by', verbose_name='Услуга',
)
created_at = models.DateTimeField('Добавлено', auto_now_add=True)
class Meta:
verbose_name = 'Избранное'
verbose_name_plural = 'Избранное'
constraints = [
models.UniqueConstraint(
fields=('user', 'product'),
condition=models.Q(product__isnull=False),
name='uniq_favorite_user_product',
),
models.UniqueConstraint(
fields=('user', 'service'),
condition=models.Q(service__isnull=False),
name='uniq_favorite_user_service',
),
]
def __str__(self):
return f'{self.user} → {self.product or self.service}'