1
0
forked from erp-dev/erp

feat: added 'follow_url into pre sales order created message'

This commit is contained in:
2026-02-02 11:09:16 +08:00
parent ac065e115e
commit dde0fda926
3 changed files with 162 additions and 1 deletions

View File

@@ -24,6 +24,21 @@ def render_pre_sales_order_created_markdown(
kind: str,
items_count: int,
) -> str:
followup_url_template = getattr(
settings,
"PRE_SALES_ORDER_CREATED_FOLLOWUP_URL_TEMPLATE",
"",
)
followup_url = ""
if followup_url_template:
try:
followup_url = str(followup_url_template).format(
pre_sales_order_id=str(pre_sales_order_id or "")
)
except Exception:
followup_url = ""
followup_line = f"- **跟进**[点击跟进]({followup_url})\n" if followup_url else ""
template = getattr(
settings,
"PRE_SALES_ORDER_CREATED_WECOM_MARKDOWN_TEMPLATE",
@@ -38,6 +53,7 @@ def render_pre_sales_order_created_markdown(
"- **仓库**{warehouse_name}\n"
"- **类型**{kind}\n"
"- **明细条数**`{items_count}`\n"
"{followup_line}"
),
)
@@ -54,6 +70,7 @@ def render_pre_sales_order_created_markdown(
warehouse_name=str(warehouse_name or "-"),
kind=str(kind or "-"),
items_count=int(items_count) if items_count is not None else 0,
followup_line=str(followup_line),
)

View File

@@ -96,7 +96,138 @@
- 上述校验必须在 **service 层独立函数** 中完成
- 不写入 model 层,不引入重复代码
## 六、待后续阶段处理
## 六、已实现的配货记录 API
### 6.1 创建配货记录
**接口路径:** `POST /api/v1/pre-sales-order-items/{item_id}/allocations/`
**请求参数JSON Body**
```json
{
"stock_ids": [1, 2, 3], // 库存明细ID数组必填
"quantity": "10.00", // 配货数量(必填)
"unit": "KG", // 单位(必填)
"remarks": "备注信息" // 备注(可选)
}
```
**响应数据201 Created**
```json
{
"id": 123,
"pre_sales_order_item": 456,
"stock_ids": [1, 2, 3],
"quantity": "10.00",
"unit": "KG",
"status": 1, // 1=有效2=撤销
"scanned_by": 78,
"scanned_by_name": "张三",
"scanned_at": "2026-02-02T10:30:00Z",
"remarks": "备注信息",
"created_at": "2026-02-02T10:30:00Z"
}
```
**业务逻辑:**
- 自动校验 stock_ids 存在、未消费、未冻结
- 自动校验产品匹配(库存明细产品必须与预销售单明细产品一致)
- 创建配货记录的同时自动冻结对应的库存明细(在同一事务中完成)
- 自动记录扫码员工与扫码时间
**错误响应400 Bad Request**
```json
{
"error": "库存明细 ID [1, 2] 不存在"
}
```
```json
{
"error": "库存明细 ID [3] 已被冻结"
}
```
### 6.2 撤销配货记录
**接口路径:** `DELETE /api/v1/pre-sales-order-items/{item_id}/allocations/{pk}/`
**响应数据200 OK**
```json
{
"id": 123,
"pre_sales_order_item": 456,
"stock_ids": [1, 2, 3],
"quantity": "10.00",
"unit": "KG",
"status": 2, // 已撤销
"scanned_by": 78,
"scanned_by_name": "张三",
"scanned_at": "2026-02-02T10:30:00Z",
"remarks": "备注信息",
"created_at": "2026-02-02T10:30:00Z"
}
```
**业务逻辑:**
- 将配货记录状态置为"撤销"status=2
- 撤销的记录不计入配货进度统计
- 不删除记录,保留审计痕迹
**错误响应404 Not Found**
```json
{
"error": "配货记录不存在"
}
```
### 6.3 预销售单明细新增字段(查询时自动返回)
当查询预销售单详情(`GET /api/v1/pre-sales-orders/{pk}/`)时,明细数据会自动包含以下派生字段:
```json
{
"items": [
{
"id": 456,
"product": 789,
"quantity": "100.00",
"unit": "KG",
// ... 其他字段 ...
// 新增:配货记录列表
"allocation_records": [
{
"id": 123,
"stock_ids": [1, 2, 3],
"quantity": "10.00",
"status": 1,
// ... 完整记录 ...
}
],
// 新增:已配货数量(仅统计 status=1 的记录)
"allocated_quantity": "25.50",
// 新增配货进度0.0-1.0
"progress": "0.255",
// 新增:配货状态(计算字段,不落库)
"allocation_status": 2 // 1=pending(0%), 2=allocating(0%-100%), 3=completed(>=100%)
}
]
}
```
**字段说明:**
- `allocation_records`:该明细的所有配货记录(包括撤销的)
- `allocated_quantity`:已配货总量(仅统计 status=1 的有效记录)
- `progress`:配货进度 = allocated_quantity / quantity
- `allocation_status`:配货状态(派生字段)
- `1` = pending尚未配货allocated_quantity = 0
- `2` = allocating配货中0 < allocated_quantity < quantity
- `3` = completed已完成allocated_quantity >= quantity允许超配
## 七、待后续阶段处理
- 转销售单流程(确认并转单)
- 任务指派/接收/完成等任务主表流程
- 撤销配货记录时的库存解冻逻辑(当前仅标记撤销,未解冻)

View File

@@ -308,6 +308,19 @@ PRINTING_ORDER_CREATED_WECOM_MARKDOWN_TEMPLATE = (
"- **出货日期**`{outgoing_date}`\n"
)
# PreSalesOrder创建时的企业微信通知markdown
# - 默认:测试环境关闭(避免单测出网/刷屏),非测试环境开启
PRE_SALES_ORDER_CREATED_WECOM_NOTIFY_ENABLED = env.bool(
"PRE_SALES_ORDER_CREATED_WECOM_NOTIFY_ENABLED",
default=(not TESTING),
)
# 预销售单跟进地址(用于企业微信通知里展示/点击)
# 使用 pre_sales_order_id 进行格式化
PRE_SALES_ORDER_CREATED_FOLLOWUP_URL_TEMPLATE = env(
"PRE_SALES_ORDER_CREATED_FOLLOWUP_URL_TEMPLATE",
default="https://app.yuwen.cloud/workstation/warehouse/task-allocation/{pre_sales_order_id}",
)
# Logging configuration
# 目标: