Introduce notifications app and integrate emails
Add a new notifications app (models, serializers, views, admin, tasks, consumers, routing, urls, tests) with Notification.notify for in-app websocket pushes and optional email delivery. Centralize email sending in notifications.tasks.send_email_with_context and re-export it from account.tasks for compatibility. Update account and commerce and advertisement tasks to use Notification.notify/_notify_order and the new email helper; adjust order/notification tasks to consolidate logic. Wire notifications into ASGI routing, settings and URL conf. Misc: handle OSError when importing weasyprint, add tmp/ to .gitignore, add local .claude PowerShell checks, add social.blog skeleton, and remove legacy ews-component test files.
This commit is contained in:
@@ -11,7 +11,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator, validat
|
||||
|
||||
try:
|
||||
from weasyprint import HTML
|
||||
except ImportError:
|
||||
except (ImportError, OSError):
|
||||
HTML = None
|
||||
|
||||
import os
|
||||
|
||||
@@ -1,182 +1,157 @@
|
||||
from account.tasks import send_email_with_context
|
||||
from celery import shared_task
|
||||
|
||||
from django.apps import apps
|
||||
from django.utils import timezone
|
||||
|
||||
from notifications.models import Notification
|
||||
from notifications.tasks import send_email_with_context
|
||||
|
||||
|
||||
def _notify_order(order, title, text, template_path, action_url=None):
|
||||
"""Send in-app notification + email for logged-in users, email-only for guests."""
|
||||
if order.user:
|
||||
Notification.notify(
|
||||
user=order.user,
|
||||
title=title,
|
||||
text=text,
|
||||
notification_type=Notification.Type.ORDER,
|
||||
action_url=action_url or f"/objednavky/{order.id}/",
|
||||
template_path=template_path,
|
||||
email_context={"order": order},
|
||||
)
|
||||
else:
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject=title,
|
||||
template_path=template_path,
|
||||
context={"order": order},
|
||||
)
|
||||
|
||||
|
||||
# -- CLEANUP TASKS --
|
||||
|
||||
# Delete expired/cancelled orders (older than 24 hours)
|
||||
@shared_task
|
||||
def delete_expired_orders():
|
||||
Order = apps.get_model('commerce', 'Order')
|
||||
|
||||
expired_orders = Order.objects.filter(status=Order.OrderStatus.CANCELLED, created_at__lt=timezone.now() - timezone.timedelta(hours=24))
|
||||
expired_orders = Order.objects.filter(
|
||||
status=Order.OrderStatus.CANCELLED,
|
||||
created_at__lt=timezone.now() - timezone.timedelta(hours=24),
|
||||
)
|
||||
count = expired_orders.count()
|
||||
expired_orders.delete()
|
||||
return count
|
||||
|
||||
|
||||
# -- NOTIFICATIONS CARRIER --
|
||||
# -- CARRIER NOTIFICATIONS --
|
||||
|
||||
# Zásilkovna
|
||||
@shared_task
|
||||
def notify_zasilkovna_sended(order = None, **kwargs):
|
||||
def notify_zasilkovna_sended(order=None, **kwargs):
|
||||
if not order:
|
||||
raise ValueError("Order must be provided for notification.")
|
||||
|
||||
if kwargs:
|
||||
print("Additional kwargs received in notify_zasilkovna_sended:", kwargs)
|
||||
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject="Your order has been shipped",
|
||||
raise ValueError("Order must be provided.")
|
||||
_notify_order(
|
||||
order,
|
||||
title="Vaše objednávka byla odeslána",
|
||||
text=f"Objednávka #{order.id} byla předána přepravci Zásilkovna.",
|
||||
template_path="email/shipping/zasilkovna/zasilkovna_sended.html",
|
||||
context={
|
||||
"order": order,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
# Shop
|
||||
@shared_task
|
||||
def notify_Ready_to_pickup(order = None, **kwargs):
|
||||
def notify_Ready_to_pickup(order=None, **kwargs):
|
||||
if not order:
|
||||
raise ValueError("Order must be provided for notification.")
|
||||
|
||||
if kwargs:
|
||||
print("Additional kwargs received in notify_Ready_to_pickup:", kwargs)
|
||||
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject="Your order is ready for pickup",
|
||||
raise ValueError("Order must be provided.")
|
||||
_notify_order(
|
||||
order,
|
||||
title="Vaše objednávka je připravena k vyzvednutí",
|
||||
text=f"Objednávka #{order.id} čeká na vyzvednutí na prodejně.",
|
||||
template_path="email/shipping/ready_to_pickup/ready_to_pickup.html",
|
||||
context={
|
||||
"order": order,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
# -- NOTIFICATIONS ORDER --
|
||||
# -- ORDER NOTIFICATIONS --
|
||||
|
||||
@shared_task
|
||||
def notify_order_successfuly_created(order = None, **kwargs):
|
||||
def notify_order_successfuly_created(order=None, **kwargs):
|
||||
if not order:
|
||||
raise ValueError("Order must be provided for notification.")
|
||||
|
||||
if kwargs:
|
||||
print("Additional kwargs received in notify_order_successfuly_created:", kwargs)
|
||||
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject="Your order has been successfully created",
|
||||
raise ValueError("Order must be provided.")
|
||||
_notify_order(
|
||||
order,
|
||||
title="Objednávka byla úspěšně vytvořena",
|
||||
text=f"Vaše objednávka #{order.id} byla přijata a čeká na zpracování.",
|
||||
template_path="email/order_created.html",
|
||||
context={
|
||||
"order": order,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@shared_task
|
||||
def notify_order_payed(order = None, **kwargs):
|
||||
def notify_order_payed(order=None, **kwargs):
|
||||
if not order:
|
||||
raise ValueError("Order must be provided for notification.")
|
||||
|
||||
if kwargs:
|
||||
print("Additional kwargs received in notify_order_payed:", kwargs)
|
||||
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject="Your order has been paid",
|
||||
raise ValueError("Order must be provided.")
|
||||
_notify_order(
|
||||
order,
|
||||
title="Platba objednávky přijata",
|
||||
text=f"Platba za objednávku #{order.id} byla úspěšně přijata.",
|
||||
template_path="email/order_paid.html",
|
||||
context={
|
||||
"order": order,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@shared_task
|
||||
def notify_about_missing_payment(order = None, **kwargs):
|
||||
def notify_about_missing_payment(order=None, **kwargs):
|
||||
if not order:
|
||||
raise ValueError("Order must be provided for notification.")
|
||||
|
||||
if kwargs:
|
||||
print("Additional kwargs received in notify_about_missing_payment:", kwargs)
|
||||
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject="Payment missing for your order",
|
||||
raise ValueError("Order must be provided.")
|
||||
_notify_order(
|
||||
order,
|
||||
title="Nezaplacená objednávka",
|
||||
text=f"Objednávka #{order.id} dosud nebyla zaplacena. Dokončete platbu co nejdříve.",
|
||||
template_path="email/order_missing_payment.html",
|
||||
context={
|
||||
"order": order,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
# -- NOTIFICATIONS REFUND --
|
||||
# -- REFUND NOTIFICATIONS --
|
||||
|
||||
@shared_task
|
||||
def notify_refund_items_arrived(order = None, **kwargs):
|
||||
def notify_refund_items_arrived(order=None, **kwargs):
|
||||
if not order:
|
||||
raise ValueError("Order must be provided for notification.")
|
||||
|
||||
if kwargs:
|
||||
print("Additional kwargs received in notify_refund_items_arrived:", kwargs)
|
||||
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject="Your refund items have arrived",
|
||||
raise ValueError("Order must be provided.")
|
||||
_notify_order(
|
||||
order,
|
||||
title="Vrácené zboží přijato",
|
||||
text=f"Vrácené zboží k objednávce #{order.id} bylo přijato. Reklamace bude zpracována.",
|
||||
template_path="email/order_refund_items_arrived.html",
|
||||
context={
|
||||
"order": order,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
# Refund accepted, returning money
|
||||
@shared_task
|
||||
def notify_refund_accepted(order = None, **kwargs):
|
||||
def notify_refund_accepted(order=None, **kwargs):
|
||||
if not order:
|
||||
raise ValueError("Order must be provided for notification.")
|
||||
|
||||
if kwargs:
|
||||
print("Additional kwargs received in notify_refund_accepted:", kwargs)
|
||||
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject="Your refund has been accepted",
|
||||
raise ValueError("Order must be provided.")
|
||||
_notify_order(
|
||||
order,
|
||||
title="Vrácení peněz schváleno",
|
||||
text=f"Vaše reklamace k objednávce #{order.id} byla schválena. Peníze budou vráceny.",
|
||||
template_path="email/order_refund_accepted.html",
|
||||
context={
|
||||
"order": order,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
# -- NOTIFICATIONS ORDER STATUS --
|
||||
# -- ORDER STATUS NOTIFICATIONS --
|
||||
|
||||
@shared_task
|
||||
def notify_order_cancelled(order = None, **kwargs):
|
||||
def notify_order_cancelled(order=None, **kwargs):
|
||||
if not order:
|
||||
raise ValueError("Order must be provided for notification.")
|
||||
|
||||
if kwargs:
|
||||
print("Additional kwargs received in notify_order_cancelled:", kwargs)
|
||||
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject="Your order has been cancelled",
|
||||
raise ValueError("Order must be provided.")
|
||||
_notify_order(
|
||||
order,
|
||||
title="Objednávka zrušena",
|
||||
text=f"Objednávka #{order.id} byla zrušena.",
|
||||
template_path="email/order_cancelled.html",
|
||||
context={
|
||||
"order": order,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@shared_task
|
||||
def notify_order_completed(order = None, **kwargs):
|
||||
def notify_order_completed(order=None, **kwargs):
|
||||
if not order:
|
||||
raise ValueError("Order must be provided for notification.")
|
||||
|
||||
if kwargs:
|
||||
print("Additional kwargs received in notify_order_completed:", kwargs)
|
||||
|
||||
send_email_with_context(
|
||||
recipients=order.email,
|
||||
subject="Your order has been completed",
|
||||
raise ValueError("Order must be provided.")
|
||||
_notify_order(
|
||||
order,
|
||||
title="Objednávka dokončena",
|
||||
text=f"Vaše objednávka #{order.id} byla úspěšně dokončena. Děkujeme za nákup!",
|
||||
template_path="email/order_completed.html",
|
||||
context={
|
||||
"order": order,
|
||||
})
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user