from django.db.models.signals import post_save, post_delete from django.dispatch import receiver from django.core.mail import send_mail from django.conf import settings from django.urls import reverse from .models import Order, OrderItem, OrderStatus from django.db import transaction @receiver([post_save, post_delete], sender=Order) def send_order_notification(sender, instance, **kwargs): print("send_order_notification") """ Send an email notification when an order is created, updated, or deleted. """ # Use transaction.on_commit to ensure database operations are complete transaction.on_commit(lambda: _send_order_email(instance, **kwargs)) def _send_order_email(instance, **kwargs): created = kwargs.get('created', False) update_fields = kwargs.get('update_fields', None) # Determine the action type if 'signal' in kwargs and kwargs['signal'] == post_delete: action = "DELETED" return elif created: action = "CREATED" return else: action = "UPDATED" print('updated', update_fields) if update_fields and 'status' in update_fields: action = "UPDATED" # Get order details order_id = instance.id status = instance.status print("status", status) if status == OrderStatus.PENDING: return total_price = instance.total_price # Generate admin URL admin_url = f"{settings.SITE_URL}{reverse('admin:shop_order_change', args=[order_id])}" # Get customer info customer_email = None if instance.user: customer_info = f"Utilisateur: {instance.user.email}" customer_email = instance.user.email elif instance.guest_user: customer_info = f"Invité: {instance.guest_user.email} ({instance.guest_user.phone})" customer_email = instance.guest_user.email else: customer_info = "Client inconnu" # Build order item details items_list = "" if action != "DELETED": # Use a fresh query to ensure we have the most recent data order_items = OrderItem.objects.filter(order_id=order_id).select_related('product', 'color', 'size') for item in order_items: color = item.color.name if item.color else "N/A" size = item.size.name if item.size else "N/A" item_line = f"- {item.quantity}x {item.product.title} (Couleur: {color}, Taille: {size}, Prix: {item.price}€)\n" items_list += item_line # Compose the email if action == "CREATED": action_fr = "CRÉÉE" elif action == "UPDATED": action_fr = "MISE À JOUR" elif action == "DELETED": action_fr = "SUPPRIMÉE" else: action_fr = action # Translate current status status_fr_map = { "PENDING": "EN ATTENTE", "PAID": "PAYÉE", "SHIPPED": "EXPÉDIÉE", "DELIVERED": "LIVRÉE", "CANCELED": "ANNULÉE" } status_fr = status_fr_map.get(status, status) # Translate payment status payment_status_fr_map = { "UNPAID": "NON PAYÉE", "PAID": "PAYÉE", "FAILED": "ÉCHOUÉE" } payment_status_fr = payment_status_fr_map.get(instance.payment_status, instance.payment_status) # Send internal notification email subject = f"Commande #{order_id} {action_fr}: {status_fr}" message = f""" La commande #{order_id} a été {action_fr.lower()} Statut: {status_fr} Statut de paiement: {payment_status_fr} Prix total: {total_price}€ {customer_info} Articles: {items_list} Voir la commande dans le panneau d'administration: {admin_url} Ceci est un message automatique. Merci de ne pas répondre. """ # Send internal email recipient_list = [email for name, email in settings.MANAGERS] if not recipient_list: recipient_list = [settings.DEFAULT_FROM_EMAIL] send_mail( subject=subject, message=message, from_email=settings.DEFAULT_FROM_EMAIL, recipient_list=recipient_list, fail_silently=False, ) # Only send customer email for PAID status and if we have customer email if status == OrderStatus.PAID and customer_email and instance.payment_status == "PAID": # Generate customer-facing URLs shop_url = f"{settings.SITE_URL}/shop" contact_email = "support@padelclub.app" # Create a customer receipt email customer_subject = f"Confirmation de votre commande #{order_id} - PadelClub" customer_message = f""" Bonjour, Nous vous remercions pour votre commande sur PadelClub ! Récapitulatif de votre commande #{order_id} du {instance.date_ordered.strftime('%d/%m/%Y')} : Statut: {status_fr} Prix total: {total_price}€ Détail de votre commande : {items_list} Nous nous occupons de préparer votre commande dans les plus brefs délais. Pour toute question concernant votre commande, n'hésitez pas à contacter notre service client : {contact_email} Visitez notre boutique pour découvrir d'autres produits : {shop_url} Merci de votre confiance et à bientôt sur PadelClub ! L'équipe PadelClub """ # Send email to customer send_mail( subject=customer_subject, message=customer_message, from_email=settings.DEFAULT_FROM_EMAIL, recipient_list=[customer_email], fail_silently=False, )