forked from erp-dev/erp
feat: mission category
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import logging
|
||||
|
||||
from django.db.models import Case, IntegerField, Q, Value, When
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from notifier.models import Notifier
|
||||
from notifier.models import Notifier, NotifierRoute
|
||||
from notifier.registry import get_notifier_backend
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -22,7 +23,6 @@ def send_notification_with_notifier(*, notifier: Notifier, payload: dict) -> dic
|
||||
result = {
|
||||
"notifier_id": notifier.id,
|
||||
"notifier_name": notifier.name,
|
||||
"event_key": notifier.event_key,
|
||||
"channel": notifier.channel,
|
||||
"template_key": notifier.template_key,
|
||||
"status": "sent",
|
||||
@@ -32,29 +32,78 @@ def send_notification_with_notifier(*, notifier: Notifier, payload: dict) -> dic
|
||||
return result
|
||||
|
||||
|
||||
def _match_notifier_routes(*, event_key: str, merchant_id: int, payload: dict | None = None) -> list[NotifierRoute]:
|
||||
payload = payload or {}
|
||||
category_id = payload.get("category_id")
|
||||
queryset = NotifierRoute.objects.filter(
|
||||
merchant_id=merchant_id,
|
||||
event_key=event_key,
|
||||
is_enabled=True,
|
||||
notifier__is_enabled=True,
|
||||
).select_related("notifier", "mission_category")
|
||||
|
||||
if category_id is not None:
|
||||
queryset = queryset.filter(Q(mission_category_id=category_id) | Q(mission_category__isnull=True)).annotate(
|
||||
route_priority=Case(
|
||||
When(mission_category_id=category_id, then=Value(0)),
|
||||
default=Value(1),
|
||||
output_field=IntegerField(),
|
||||
)
|
||||
)
|
||||
else:
|
||||
queryset = queryset.filter(mission_category__isnull=True).annotate(
|
||||
route_priority=Value(0, output_field=IntegerField())
|
||||
)
|
||||
|
||||
queryset = queryset.order_by("notifier_id", "route_priority", "id")
|
||||
matched_by_notifier_id = {}
|
||||
for route in queryset:
|
||||
matched_by_notifier_id.setdefault(route.notifier_id, route)
|
||||
return list(matched_by_notifier_id.values())
|
||||
|
||||
|
||||
def dispatch_notification_event(*, event_key: str, merchant_id: int, payload: dict | None = None) -> list[dict]:
|
||||
notifiers = list(
|
||||
Notifier.objects.filter(
|
||||
merchant_id=merchant_id,
|
||||
event_key=event_key,
|
||||
is_enabled=True,
|
||||
).order_by("id")
|
||||
payload = payload or {}
|
||||
routes = _match_notifier_routes(
|
||||
event_key=event_key,
|
||||
merchant_id=merchant_id,
|
||||
payload=payload,
|
||||
)
|
||||
if not notifiers:
|
||||
if not routes:
|
||||
logger.info(
|
||||
"[notifier.services] no enabled notifier matched: event_key=%s merchant_id=%s",
|
||||
"[notifier.services] no enabled notifier route matched: event_key=%s merchant_id=%s category_id=%s",
|
||||
event_key,
|
||||
merchant_id,
|
||||
payload.get("category_id"),
|
||||
)
|
||||
return []
|
||||
|
||||
results = []
|
||||
for notifier in notifiers:
|
||||
for route in routes:
|
||||
notifier = route.notifier
|
||||
try:
|
||||
results.append(send_notification_with_notifier(notifier=notifier, payload=payload or {}))
|
||||
item = send_notification_with_notifier(notifier=notifier, payload=payload)
|
||||
item.update(
|
||||
{
|
||||
"event_key": event_key,
|
||||
"route_id": route.id,
|
||||
"route_event_key": route.event_key,
|
||||
"route_mission_category_id": route.mission_category_id,
|
||||
}
|
||||
)
|
||||
results.append(item)
|
||||
logger.info(
|
||||
"[notifier.services] notification routed: route_id=%s notifier_id=%s event_key=%s merchant_id=%s route_category_id=%s",
|
||||
route.id,
|
||||
notifier.id,
|
||||
event_key,
|
||||
merchant_id,
|
||||
route.mission_category_id,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.exception(
|
||||
"[notifier.services] notification failed: notifier_id=%s event_key=%s merchant_id=%s",
|
||||
"[notifier.services] notification failed: route_id=%s notifier_id=%s event_key=%s merchant_id=%s",
|
||||
route.id,
|
||||
notifier.id,
|
||||
event_key,
|
||||
merchant_id,
|
||||
@@ -63,9 +112,12 @@ def dispatch_notification_event(*, event_key: str, merchant_id: int, payload: di
|
||||
{
|
||||
"notifier_id": notifier.id,
|
||||
"notifier_name": notifier.name,
|
||||
"event_key": notifier.event_key,
|
||||
"event_key": event_key,
|
||||
"channel": notifier.channel,
|
||||
"template_key": notifier.template_key,
|
||||
"route_id": route.id,
|
||||
"route_event_key": route.event_key,
|
||||
"route_mission_category_id": route.mission_category_id,
|
||||
"status": "failed",
|
||||
"error": str(exc),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user