signal of address and some model udapte send address filed of an order

This commit is contained in:
Parsa Nazer
2025-04-18 17:29:04 +03:30
parent aa12540eb7
commit d50dc2309d
9 changed files with 177 additions and 64 deletions
+52 -42
View File
@@ -1,9 +1,10 @@
from django.db import models
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='کد تخفیف')
@@ -44,20 +45,19 @@ class OrderModel(models.Model):
('CANCELED', 'لغو شده'),
('REFUNDED', 'مرجوع شده'),
]
order_id = models.PositiveIntegerField(unique=True, null=True, blank=True, verbose_name='شماره سفارش')
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, verbose_name="وضعیت سفارش")
discount = models.BigIntegerField(null=True, blank=True, verbose_name='کل تخقیف')
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='CART', 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.id + 1000}'
return f'سفارش: {self.pk + 1000}'
class Meta:
verbose_name = 'سفارش'
@@ -65,58 +65,68 @@ class OrderModel(models.Model):
def save(self, *args, **kwargs):
# genrate order id
if not self.pk:
last_instance = self.__class__.objects.order_by("pk").last()
self.order_id = (last_instance.pk + 1001) if last_instance else 1001
super().save(*args, **kwargs)
def _cal_discount_amount(self, cart_total):
discount_percent = self.discount_code.percent if self.discount_code else 0
return int(cart_total * discount_percent / 100)
def cal_discount(self):
# total_with_item_discount = sum(item.total_with_discount() for item in self.items.all())
# discount_percent = self.discount_code.percent
# return total_with_item_discount * ((100 - discount_percent) / 100)
pass
def cal_tax(self):
return self.total_without_tax() * 0.2
def _cal_tax(self, cart_total, discount_amount):
tax_rate = getattr(settings, 'DEFAULT_TAX_RATE', 20)
return int((cart_total - discount_amount) * tax_rate / 100)
def _cal_cart_total(self):
from django.db.models import Sum, F, FloatField
return self.items.aggregate(
total=Sum(F('price') * (1 - F('discount_percent')/100) * F('quantity'),
output_field=FloatField()
)).get('total') or 0
def cal_total(self):
pass
return self.total_with_discount() + self.tax()
def cal_final_price(self):
pass
def _cal_final_price(self, cart_total, discount_amount, tax):
return cart_total - discount_amount + tax
def update_order(self):
if self.status == 'CART':
cart_total = self._cal_cart_total()
discount_amount = self._cal_discount_amount(cart_total)
self.discount_amount = discount_amount
self.cart_total = cart_total
tax = self._cal_tax(cart_total, discount_amount)
self.tax = tax
self.final_price = self._cal_final_price(cart_total, discount_amount, tax)
self.save()
else:
pass
class OrderItemModel(models.Model):
order = models.ForeignKey(OrderModel, on_delete=models.CASCADE, related_name='items', verbose_name='سفارش')
quantity = models.PositiveSmallIntegerField(verbose_name="تعداد")
price = models.PositiveIntegerField(verbose_name='قیمت', default=0)
price = models.BigIntegerField(verbose_name='قیمت')
product = models.ForeignKey(ProductVariant, on_delete=models.PROTECT, verbose_name="محصول")
discount = models.SmallIntegerField(default=0, verbose_name='تخفیف')
discount_percent = models.SmallIntegerField(verbose_name='درصد تخفیف')
class Meta:
verbose_name = 'ایتم سبد خرید'
verbose_name_plural = 'ایتم های سبد خرید'
# def total(self):
# return self.quantity * self.product.price
# def total_with_discount(self):
# return self.quantity * self.product.get_toman_price_after_discount()
def update_fields(self):
pass
def set_or_update_fields(self):
self.price = self.product.price
self.discount_percent = self.product.discount
def __str__(self):
return f'({self.product}) - ({self.order.user})'
def save(self, *args, **kwargs):
self.clean()
self.set_or_update_fields()
super().save(*args, **kwargs)
self.order.update_order()
def delete(self, *args, **kwargs):
self.clean()
order = self.order
super().delete(*args, **kwargs)
order.update_order()
def clean(self):
if self.pk and self.order.status != "CART":
raise ValidationError("ایتم ها فقط در حالت سبد خرید قابل ادیت هستند")