117 lines
4.2 KiB
Python

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, ProductVariant, Order, OrderLine, Transaction, TrackingNumber
)
from .tasks import (
send_order_confirmation_email,
send_order_shipped_email
)
logger = logging.getLogger(__name__)
stripe.api_key = settings.STRIPE_API_KEY
def format_order_lines(lines):
for line in lines:
yield {
'variant': str(line.variant),
'customer_note': line.customer_note,
'quantity': line.quantity,
'unit_price': str(line.unit_price)
}
@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(),
'subtotal_amount': str(instance.order.subtotal_amount),
'coupon_amount': str(instance.order.coupon_amount),
'shipping_total': str(instance.order.shipping_total),
'total_amount': str(instance.order.total_amount),
'shipping_address': {
'first_name': instance.order.shipping_first_name,
'last_name': instance.order.shipping_last_name,
'street_address_1': instance.order.shipping_street_address_1,
'street_address_2': instance.order.shipping_street_address_2,
'city': instance.order.shipping_city,
'state': instance.order.shipping_state,
'postal_code': instance.order.shipping_postal_code
},
'line_items': list(
format_order_lines(instance.order.lines.all())
)
}
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)
# )
# )