1
0
forked from erp-dev/erp

feat: added wecom notify when printing_job production was completed(new status) and shipment was created

This commit is contained in:
2026-04-09 17:35:14 +08:00
parent 76ea445880
commit 646dbe7f18
27 changed files with 1122 additions and 13 deletions

View File

@@ -7,11 +7,14 @@ from __future__ import annotations
from decimal import Decimal, InvalidOperation
from typing import List
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import transaction
from django.db.models import Count, Exists, IntegerField, OuterRef, QuerySet, Subquery
from django.db.models.functions import Coalesce
from django.utils import timezone
from api_v1.utils.wecom_webhook import send_wecom_webhook_message
from shipment.models import (
ExternalFinishedProduct,
SalesItem,
@@ -22,6 +25,7 @@ from shipment.models import (
ShipmentDeliveryStatus,
ShipmentStatus,
)
from shipment.signals import shipment_created
def _resolve_user_merchant(user):
@@ -33,6 +37,19 @@ def _resolve_user_employee(user):
return getattr(user, "employee", None)
def _user_label(user) -> str:
if not user:
return "系统自动发送"
emp = getattr(user, "employee", None)
name = getattr(emp, "name", None) if emp is not None else None
if name:
return str(name)
username = getattr(user, "username", None)
if username:
return str(username)
return "系统自动发送"
def get_active_sales_items_queryset() -> QuerySet[SalesItem]:
"""
返回未软删除的销售品查询集。
@@ -716,6 +733,7 @@ def update_shipment(
return shipment
@transaction.atomic
@transaction.atomic
def create_shipment(
customer_id: int,
@@ -834,9 +852,119 @@ def create_shipment(
if updated != len(sales_item_ids):
raise ValueError("存在不属于当前商户的销售品,无法关联到出货单")
try:
shipment_created.send(
sender=Shipment,
instance=shipment,
created_by=created_by,
)
except Exception:
import logging
logging.getLogger(__name__).exception(
"[shipment.services] 触发 shipment_created signal 失败(已忽略)"
)
return shipment
def render_shipment_created_markdown(
*,
shipment_id: str,
customer_name: str,
shipment_date: str,
items_count: str,
sender_label: str,
) -> str:
template = getattr(
settings,
"SHIPMENT_CREATED_WECOM_MARKDOWN_TEMPLATE",
(
"### 出货单创建\n"
"\n"
"- **出货单ID**`{shipment_id}`\n"
"- **客户**{customer_name}\n"
"- **出货日期**`{shipment_date}`\n"
"- **销售品数量**`{items_count}`\n"
"- **发送者**{sender}\n"
),
)
return template.format(
shipment_id=str(shipment_id or "-"),
customer_name=str(customer_name or "-"),
shipment_date=str(shipment_date or "-"),
items_count=str(items_count or "0"),
sender=str(sender_label or "系统自动发送"),
)
def send_shipment_created_wecom(
*,
shipment_id: int,
created_by_id: int | None = None,
key: str | None = None,
timeout_seconds: float = 10.0,
dry_run: bool = False,
) -> dict:
shipment = (
Shipment.objects.select_related("customer")
.prefetch_related("items")
.filter(id=int(shipment_id))
.first()
)
if not shipment:
raise ValueError(f"Shipment 不存在id={shipment_id}")
created_by = None
if created_by_id:
created_by = get_user_model().objects.filter(id=int(created_by_id)).first()
customer_name = getattr(getattr(shipment, "customer", None), "name", None) or "-"
shipment_date_text = (
shipment.shipment_date.isoformat() if getattr(shipment, "shipment_date", None) else "-"
)
items_count = shipment.items.filter(delete_at__isnull=True).count()
sender_label = _user_label(created_by)
msg = render_shipment_created_markdown(
shipment_id=str(shipment.id),
customer_name=str(customer_name),
shipment_date=str(shipment_date_text),
items_count=str(items_count),
sender_label=str(sender_label),
)
if dry_run:
return {
"dry_run": True,
"message": msg,
"shipment_id": shipment.id,
"customer_name": str(customer_name),
"shipment_date": str(shipment_date_text),
"items_count": items_count,
"sender_label": str(sender_label),
}
resp = send_wecom_webhook_message(
content=msg,
msgtype="markdown",
key=key,
timeout_seconds=timeout_seconds,
)
return {
"dry_run": False,
"message": msg,
"shipment_id": shipment.id,
"customer_name": str(customer_name),
"shipment_date": str(shipment_date_text),
"items_count": items_count,
"sender_label": str(sender_label),
"wecom": resp.raw,
"ok": resp.ok,
"errcode": resp.errcode,
"errmsg": resp.errmsg,
}
@transaction.atomic
def create_external_shipment(
customer_id: int,