Files
hossein-por-shop/backend/order/models.py
T
2025-09-23 10:17:19 +03:30

177 lines
6.5 KiB
Python

from django.db import models, transaction
from account.models import User, UserAddressModel, PushSubscription
from product.models import ProductModel, ProductVariant, ProductImageModel
from django.utils import timezone
from django_jalali.db import models as jmodels
from django.core.exceptions import ValidationError
from django.conf import settings
class DiscountCode(models.Model):
code = models.CharField(max_length=50, verbose_name='کد تخفیف')
percent = models.DecimalField(
max_digits=4, decimal_places=2, verbose_name='درصد')
quantity = models.PositiveIntegerField(verbose_name='تعداد')
expiration_date = models.DateTimeField(verbose_name='تاریخ انقضا')
def __str__(self):
return self.code
class Meta:
verbose_name = 'کد تخفیف'
verbose_name_plural = 'کد های تخفیف'
def is_valid(self):
return self.expiration_date > timezone.now() and self.quantity > 0
def not_valid_reason(self):
if self.expiration_date > timezone.now() and self.quantity > 0:
return 'این کد معتبر میباشد'
elif not self.expiration_date > timezone.now():
return 'تایم کد تخفیف تمام شده'
elif not self.quantity > 0:
return 'این کد تخفیف تمام شده است'
else:
print('log later bug')
class Cart(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='carts'
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
address = models.ForeignKey(UserAddressModel, on_delete=models.SET_NULL,
related_name='carts', null=True, verbose_name='ادرس')
discount_code = models.ForeignKey(
DiscountCode, on_delete=models.PROTECT, null=True, blank=True, verbose_name="کدتخفیف")
class Meta:
verbose_name = 'سبد خرید'
verbose_name_plural = 'سبد های خرید'
def __str__(self):
return f"Cart for {self.user.email}"
@property
def discount_code_amount(self):
if self.discount_code:
return int(int(self.cart_total - self.items_discount_amount) * (self.discount_code.percent / 100))
else:
return 0
@property
def items_discount_amount(self):
return int(sum(item.item_discount_amount for item in self.items.all()))
@property
def total_before_tax(self):
return self.cart_total - (self.discount_code_amount + self.items_discount_amount)
@property
def tax_amount(self):
return int(self.total_before_tax * settings.DEFAULT_TAX_RATE / 100)
@property
def cart_total(self):
return sum(item.price_before_discount for item in self.items.all())
@property
def final_price(self):
return self.total_before_tax + self.tax_amount
class CartItem(models.Model):
cart = models.ForeignKey(
Cart,
on_delete=models.CASCADE,
related_name='items'
)
product_variant = models.ForeignKey(
ProductVariant,
on_delete=models.CASCADE,
related_name='cart_items'
)
quantity = models.PositiveIntegerField(default=1)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = 'ایتم سبد خرید'
verbose_name_plural = 'ایتم های سبد خرید'
unique_together = ('cart', 'product_variant')
def __str__(self):
return f"{self.quantity} x {self.product_variant.product.name} in cart {self.cart.id}"
@property
def price_before_discount(self):
return self.quantity * self.product_variant.price_before_discount
@property
def item_discount_amount(self):
return self.product_variant.discount_amount * self.quantity
@property
def price_after_discount(self):
return self.price_before_discount - self.item_discount_amount
@property
def discount(self):
return self.product_variant.discount
class OrderModel(models.Model):
objects = jmodels.jManager()
STATUS_CHOICES = [
('ADMIN_PENDING', 'در انتظار تایید'),
('PENDING', 'درحال پردازش'),
('POSTED', 'ارسال شده'),
('RECEIVED', 'تحویل شده'),
('CANCELED', 'لغو شده'),
('REFUNDED', 'مرجوع شده'),
]
user = models.ForeignKey(User, on_delete=models.SET_NULL,
null=True, related_name='orders', verbose_name='کاربر')
address = models.ForeignKey(UserAddressModel, on_delete=models.SET_NULL,
related_name='orders', null=True, verbose_name='ادرس')
created_at = jmodels.jDateField(
blank=True, null=True, verbose_name="تاریخ ثبت سفارش")
is_paid = models.BooleanField(default=False, verbose_name="وضعیت پرداخت")
discount_code = models.ForeignKey(
DiscountCode, on_delete=models.PROTECT, null=True, blank=True, verbose_name="کدتخفیف")
status = models.CharField(max_length=20, choices=STATUS_CHOICES,
default='ADMIN_PENDING', verbose_name="وضعیت سفارش")
discount_amount = models.BigIntegerField(
null=True, blank=True, verbose_name='مقدار کد تخفیف')
tax = models.BigIntegerField(null=True, blank=True, verbose_name='مالیات')
final_price = models.BigIntegerField(
null=True, blank=True, verbose_name='قیمت نهایی')
cart_total = models.BigIntegerField(
null=True, blank=True, verbose_name='کل سبد خرید')
def __str__(self):
return f'سفارش: {self.pk + 1000}'
class Meta:
verbose_name = 'سفارش'
verbose_name_plural = 'سفارشات'
class OrderItemModel(models.Model):
order = models.ForeignKey(
OrderModel, on_delete=models.CASCADE, related_name='items', verbose_name='سفارش')
quantity = models.PositiveSmallIntegerField(verbose_name="تعداد")
price = models.BigIntegerField(verbose_name='قیمت')
product = models.ForeignKey(
ProductVariant, on_delete=models.PROTECT, verbose_name="محصول")
discount_percent = models.SmallIntegerField(verbose_name='درصد تخفیف')
class Meta:
verbose_name = 'ایتم سبد خرید'
verbose_name_plural = 'ایتم های سبد خرید'
def __str__(self):
return f'({self.product}) - ({self.order.user})'