1
0
forked from erp-dev/erp

feat: added n-to-1 relation between sales_order_item and printing_job model

This commit is contained in:
2025-12-11 18:09:10 +08:00
parent 633031d7cb
commit 1a8c446365
30 changed files with 41736 additions and 40 deletions

View File

@@ -0,0 +1,80 @@
# API v1 创建销售单(/api/v1/sales-orders/
> 视图位置:`api_v1.views.business.sales.views.SalesOrderView.post`
> 服务逻辑:`business.services.create_sales_order`(含事务,主单与明细同事务创建)
## 请求
- 方法:`POST`
- 路径:`/api/v1/sales-orders/`
- BodyJSON
- `customer` *(int, 必填)*:客户 ID
- `warehouse` *(int, 必填)*:仓库 ID
- `order_date` *(string, 必填)*:日期,`YYYY-MM-DD`
- `remarks` *(string, 可选)*
- `items` *(array, 必填,至少 1 条)*:销售明细
- 通用字段:
- `product_id` *(int, 必填)*
- `price` *(string/number, 必填)*
- `unit` *(string, 可选;默认产品单位或“米”)*
- `empty_diff_percent` *(string/number, 可选,默认 0)*
- `color` / `batch_number` / `remarks` / `spec` *(可选)*
- `printing_job` *(int, 可选)*:绑定印染任务 ID
- 校验:存在且产品一致;若传入销售客户,需与任务的 `printing_order.customer` 一致。
- 数量字段取决于仓库模式:
- 宽进/宽出 (`UNRESTRICTED`)`quantity``num_of_rolls`
- 严进宽出 (`RESTRICT_IN`)`numbers` 数组(每条数值为正),自动汇总数量
- 严进严出 (`RESTRICT_IN_OUT`):出库需 `consume_detail_ids` 数组 + `quantity`;入库需 `numbers`
## 响应
- 成功 `201 Created``{"id": <销售单ID>, "status": <状态枚举>, "message": "销售单创建成功,等待审批"}`
- 失败 `400 Bad Request`:缺参、格式或校验不通过(含 printing_job 校验)。
## 示例
### 严进严出(出库)示例
```json
{
"customer": 12,
"warehouse": 3,
"order_date": "2025-12-20",
"items": [
{
"product_id": 501,
"price": "18.50",
"quantity": 30,
"unit": "米",
"consume_detail_ids": [101, 102],
"printing_job": 88
}
],
"remarks": "严进严出示例"
}
```
### 宽进宽出示例
```json
{
"customer": 12,
"warehouse": 5,
"order_date": "2025-12-20",
"items": [
{
"product_id": 501,
"price": "15.00",
"quantity": 90,
"num_of_rolls": 3,
"printing_job": 88
}
]
}
```
## 关键行为说明
- 事务:主单与明细在同一 `transaction.atomic()` 中,任一失败整体回滚。
- 校验:
- 仓库模式决定数量字段(`numbers` / `consume_detail_ids` / `quantity`)。
- `printing_job` 可选;如提供需满足产品与客户一致性校验,否则返回 400。
- 明细创建:服务层使用 `bulk_create` 写入 `SalesOrderItem`。***

View File

@@ -0,0 +1,74 @@
# 印染任务查询(按客户+日期范围)- API v2
> 说明:接口视图为 `api_v2.views.printing.PrintingJobByCustomerView`URL 需在 `api_v2/urls.py` 绑定后生效(例如 `/api/v2/printing/jobs/`)。
## 请求
- 方法:`GET`
- Query 参数(必填)
- `customer_id`:客户 ID
- `date_from`:开始日期,格式 `YYYY-MM-DD`
- `date_to`:结束日期,格式 `YYYY-MM-DD`(闭区间,包含当日 23:59:59.999999
- Query 参数(可选过滤)
- `printing_order`:按印染主订单 ID
- `product_id`:按产品 ID
- `product_name`:按产品名称(模糊)
- `product_human_id`:按产品编号(模糊)
- `product_width_size`:按产品幅宽(精确数值)
- `product_color`:按产品颜色(模糊)
### 时间范围说明
`date_from``date_to` 为闭区间,等价于:
- `created_at >= date_from 00:00:00`
- `created_at <= date_to 23:59:59.999999`
## 响应
- 成功:`200 OK`
- 失败:`400 Bad Request`(参数缺失或格式错误)
### 响应字段(列表,每个元素)
- `id`:印染任务 ID
- `printing_order`:印染主订单 ID
- `product`:产品 ID
- `work_state`:业务进展(枚举值)
- `quantity`:数量
- `unit`:单位
- `size`:一段尺寸
- `pieces`:件数
- `description`:备注
- `business_object_id`:流程实例 ID
- `created_at` / `updated_at`
- `billed_quantity`:开单数量(关联全部 `SalesOrderItem.quantity` 之和)
## 示例
### 请求
```
GET /api/v2/printing/jobs/?customer_id=12&date_from=2025-12-01&date_to=2025-12-10&product_name=花布
```
### 成功响应(示例)
```json
[
{
"id": 101,
"printing_order": 55,
"product": 2001,
"work_state": 1,
"quantity": 300,
"unit": "米",
"size": "150cm",
"pieces": 10,
"description": "加急",
"business_object_id": 888,
"created_at": "2025-12-05T10:00:00Z",
"updated_at": "2025-12-06T08:00:00Z",
"billed_quantity": "120.00"
}
]
```