import logging import stripe from io import BytesIO from django.db.models.signals import post_save from django.dispatch import receiver from django.db import models from django.conf import settings from . import OrderStatus, TransactionStatus from .models import Product, Order, OrderLine, Transaction, TrackingNumber from .tasks import ( send_order_confirmation_email, send_order_shipped_email ) logger = logging.getLogger(__name__) @receiver(post_save, sender=Product, dispatch_uid="product_created") def product_saved(sender, instance, created, **kwargs): logger.info('Product was saved') if created or not instance.stripe_id: stripe.api_key = settings.STRIPE_API_KEY prod_response = stripe.Product.create( name=instance.name, description=instance.description ) price_response = stripe.Price.create( unit_amount=int(instance.price * 100), currency=settings.DEFAULT_CURRENCY, product=prod_response['id'] ) instance.stripe_id = prod_response['id'] instance.stripe_price_id = price_response['id'] instance.save() else: stripe.Product.modify( instance.stripe_id, name=instance.name, description=instance.description ) stripe.Price.modify( instance.stripe_price_id, unit_amount=int(instance.price * 100) ) @receiver(post_save, sender=Order, dispatch_uid="order_created") def order_created(sender, instance, created, **kwargs): if created: logger.info("Order was created") Transaction.objects.create(order=instance) @receiver(post_save, sender=Transaction, dispatch_uid="transaction_created") def transaction_created(sender, instance, created, **kwargs): if created: logger.info("Transaction was created") elif instance.status == TransactionStatus.COMPLETED and not instance.confirmation_email_sent: # TODO: change order to order.values() order = { 'order_id': instance.order.pk, 'email': instance.order.customer.email, 'full_name': instance.order.customer.get_full_name() } send_order_confirmation_email.delay(order) instance.confirmation_email_sent = True instance.save() @receiver(post_save, sender=TrackingNumber, dispatch_uid="trackingnumber_postsave") def trackingnumber_postsave(sender, instance, created, **kwargs): if created: logger.info("TrackingNumber was created") data = { 'order_id': instance.order.pk, 'email': instance.order.customer.email, 'full_name': instance.order.customer.get_full_name(), 'tracking_id': instance.tracking_id } send_order_shipped_email.delay(data) def get_order_status(total_quantity_fulfilled, total_quantity_ordered): if total_quantity_fulfilled >= total_quantity_ordered: return OrderStatus.FULFILLED elif total_quantity_fulfilled > 0: return OrderStatus.PARTIALLY_FULFILLED else: return OrderStatus.UNFULFILLED @receiver(post_save, sender=OrderLine, dispatch_uid="order_line_post_save") def order_line_post_save(sender, instance, created, **kwargs): if not created: order = Order.objects.with_fulfillment().filter( pk=instance.order.pk )[0] order.status = get_order_status(order.total_quantity_fulfilled, order.total_quantity_ordered) order.save() # order.update( # status=models.Case( # models.When(models.lookups.GreaterThan(models.F('total_quantity_fulfilled'), models.F('total_quantity_ordered')), # then=models.Value(OrderStatus.FULFILLED)), # models.When(models.lookups.GreaterThan(models.F('total_quantity_fulfilled'), 0), # then=models.Value(OrderStatus.PARTIALLY_FULFILLED)), # default=models.Value(OrderStatus.UNFULFILLED) # ) # )