Fixes: None; Extra: 1) Extend debug logging in order status change processing to include serialized order products.
136 lines
5.3 KiB
Python
136 lines
5.3 KiB
Python
import logging
|
|
from datetime import timedelta
|
|
|
|
from django.db import IntegrityError
|
|
from django.db.models.signals import post_save
|
|
from django.dispatch import receiver
|
|
from django.utils.crypto import get_random_string
|
|
from django.utils.http import urlsafe_base64_decode
|
|
from django.utils.timezone import now
|
|
from django.utils.translation import gettext_lazy as _
|
|
from sentry_sdk import capture_exception
|
|
|
|
from core.models import Category, Order, Product, PromoCode, Wishlist
|
|
from core.serializers import OrderProductSimpleSerializer
|
|
from core.utils import (
|
|
generate_human_readable_id,
|
|
resolve_translations_for_elasticsearch,
|
|
)
|
|
from core.utils.emailing import send_order_created_email, send_order_finished_email
|
|
from evibes.utils.misc import create_object
|
|
from vibes_auth.models import User
|
|
|
|
logger = logging.getLogger("django")
|
|
|
|
|
|
@receiver(post_save, sender=User)
|
|
def create_order_on_user_creation_signal(instance, created, **_kwargs):
|
|
if created:
|
|
try:
|
|
Order.objects.create(user=instance, status="PENDING")
|
|
except IntegrityError:
|
|
human_readable_id = generate_human_readable_id()
|
|
while True:
|
|
if Order.objects.filter(human_readable_id=human_readable_id).exists():
|
|
human_readable_id = generate_human_readable_id()
|
|
continue
|
|
Order.objects.create(user=instance, status="PENDING", human_readable_id=human_readable_id)
|
|
break
|
|
|
|
|
|
@receiver(post_save, sender=User)
|
|
def create_wishlist_on_user_creation_signal(instance, created, **_kwargs):
|
|
if created:
|
|
Wishlist.objects.create(user=instance)
|
|
|
|
|
|
@receiver(post_save, sender=User)
|
|
def create_promocode_on_user_referring(instance, created, **_kwargs):
|
|
try:
|
|
if created and instance.attributes.get("referrer", ""):
|
|
referrer_uuid = urlsafe_base64_decode(instance.attributes.get("referrer", ""))
|
|
referrer = User.objects.get(uuid=referrer_uuid)
|
|
code = f"WELCOME-{get_random_string(6)}"
|
|
PromoCode.objects.create(
|
|
user=referrer,
|
|
code=code if len(code) <= 20 else code[:20],
|
|
discount_percent=10,
|
|
start_time=now(),
|
|
end_time=now() + timedelta(days=30),
|
|
)
|
|
except Exception as e:
|
|
capture_exception(e)
|
|
logger.error(_(f"error during promocode creation: {e!s}"))
|
|
|
|
|
|
@receiver(post_save, sender=Order)
|
|
def process_order_changes(instance, created, **_kwargs):
|
|
if not created:
|
|
if instance.status != "PENDING" and instance.user:
|
|
pending_orders = Order.objects.filter(user=instance.user, status="PENDING")
|
|
|
|
if not pending_orders.exists():
|
|
try:
|
|
Order.objects.create(user=instance.user, status="PENDING")
|
|
except IntegrityError:
|
|
human_readable_id = generate_human_readable_id()
|
|
while True:
|
|
if Order.objects.filter(human_readable_id=human_readable_id).exists():
|
|
human_readable_id = generate_human_readable_id()
|
|
continue
|
|
Order.objects.create(
|
|
user=instance,
|
|
status="PENDING",
|
|
human_readable_id=human_readable_id,
|
|
)
|
|
break
|
|
|
|
if instance.status in ["CREATED", "PAYMENT"]:
|
|
logger.debug("Processing order changes: %s\nWith orderproducts: %s",
|
|
str(instance.__dict__),
|
|
str(OrderProductSimpleSerializer(instance.order_products.all(), many=True).data))
|
|
if not instance.is_whole_digital:
|
|
send_order_created_email.delay(instance.uuid)
|
|
|
|
for order_product in instance.order_products.filter(status="DELIVERING"):
|
|
if not order_product.product.is_digital:
|
|
continue
|
|
|
|
try:
|
|
logger.debug("Trying to buy: %s", str(order_product.uuid))
|
|
vendor_name = (
|
|
order_product.product.stocks.filter(price=order_product.buy_price).first().vendor.name.lower()
|
|
)
|
|
|
|
vendor = create_object(f"core.vendors.{vendor_name}", f"{vendor_name.title()}Vendor")
|
|
|
|
vendor.buy_order_product(order_product)
|
|
|
|
except Exception as e:
|
|
order_product.add_error(f"Failed to buy {order_product.uuid}. Reason: {e}...")
|
|
|
|
else:
|
|
instance.finalize()
|
|
|
|
if instance.order_products.filter(status="FAILED").count() == instance.order_products.count():
|
|
instance.status = "FAILED"
|
|
instance.save()
|
|
|
|
if instance.status == "FINISHED":
|
|
send_order_finished_email.delay(instance.uuid)
|
|
|
|
|
|
@receiver(post_save, sender=Product)
|
|
def update_product_name_lang(instance, created, **_kwargs):
|
|
if created:
|
|
pass
|
|
resolve_translations_for_elasticsearch(instance, "name")
|
|
resolve_translations_for_elasticsearch(instance, "description")
|
|
|
|
|
|
@receiver(post_save, sender=Category)
|
|
def update_category_name_lang(instance, created, **_kwargs):
|
|
if created:
|
|
pass
|
|
resolve_translations_for_elasticsearch(instance, "name")
|
|
resolve_translations_for_elasticsearch(instance, "description")
|