from math import fsum from django.db import models from django.db.models.signals import pre_save, post_save from django.dispatch import receiver from billing.models import BillingProfile from carts.models import Cart from ecommerce.utils import unique_order_id_generator from addresses.models import Address ORDER_STATUS_CHOICES = ( ('created', 'Created'), ('paid', 'Paid'), ('shipped', 'Shipped'), ('refunded', 'Refunded') ) class OrderManager(models.Manager): def new_or_get(self, billing_profile, cart_obj): created = False qs = self.get_queryset().filter(billing_profile=billing_profile, cart=cart_obj, active=True, status='created') if qs.count() == 1: obj = qs.first() else: obj = self.model.objects.create(billing_profile=billing_profile, cart=cart_obj) created = True return obj, created class Order(models.Model): billing_profile = models.ForeignKey(BillingProfile, null=True, blank=True) order_id = models.CharField(max_length=100, blank=True) address = models.ForeignKey(Address, null=True, blank=True) cart = models.ForeignKey(Cart) status = models.CharField(max_length=120, default='created', choices=ORDER_STATUS_CHOICES) shipping_total = models.DecimalField(default=5.99, max_digits=100, decimal_places=2) total = models.DecimalField(default=0.00, max_digits=100, decimal_places=2) active = models.BooleanField(default=True) objects = OrderManager() def __str__(self): return self.order_id def update_total(self): cart_total = self.cart.total shipping_total = self.shipping_total total = fsum([cart_total, shipping_total]) total = format(total, '.2f') self.total = total self.save() return total def check_done(self): billing_profile = self.billing_profile address = self.address total = self.total if billing_profile and address and total > 0: return True return False def mark_paid(self): if self.check_done(): self.status = "paid" self.save() return self.status @receiver(pre_save, sender=Order) def create_order_id(sender, instance, *args, **kwargs): print('ord_id') if not instance.order_id: instance.order_id = unique_order_id_generator(instance) qs = Order.objects.filter(cart=instance.cart).exclude(billing_profile=instance.billing_profile) if qs.exists(): qs.update(active=False) @receiver(post_save, sender=Cart) def create_cart_total(sender, instance, created, *args, **kwargs): if not created: cart_obj = instance cart_total = cart_obj.total cart_id = cart_obj.id qs = Order.objects.filter(cart__id=cart_id) if qs.count() == 1: order_obj = qs.first() order_obj.update_total() @receiver(post_save, sender=Order) def create_order(sender, instance, created, *args, **kwargs): if created: instance.update_total()