半山仙人
半山仙人
发布于 2026-06-16 / 11 阅读
0
0

订单与执行分流模块需求设计文档

MSERP 订单与执行分流模块需求设计文档

一、项目背景

1.1 技术栈

  • 后端:FastAPI

  • 数据库:MySQL 8.4

  • 前端:LayuiAdmin

  • 系统定位:面向标签印刷、标签原料、不干胶材料、套装类产品、多币种订单与分流执行的 ERP 订单模块

1.2 业务特点

系统需要同时兼容:

  • 标签印刷:常见多张订单合并出货

  • 标签原料:常见一张订单一张出货单

  • 套装销售:对客户以“套装”销售,但仓库、生产、出库需要拆分为具体单品

  • 多币种报价与订单:外币辅助核算,本币落库

  • 先做货后确认单价:订单、出货链路允许单价待确认,但出货最终审核前必须确认

  • 多执行方向:库存、生产、外协采购

  • 多生产模块:印刷、涂布、分切,各模块独立开工单


二、核心设计原则

2.1 订单是销售计划,不是库存成本单

订单模块主要负责:

  • 记录客户需求

  • 确认销售数量、交期、税率、币种、价格状态

  • 触发后续分流计划

  • 给管理人员提供订单与明细进度视图

订单主表不承担:

  • 成本核算

  • 生产成本归集

  • 仓库实际扣库存

  • 产品快照最终凭据

成本应在出库、生产、采购等执行单据中沉淀。


2.2 订单分为销售契约层与执行履约层

系统采用双层模型:

订单销售层
  ├─ 订单主表 ord_order_master
  └─ 订单明细 ord_order_detail
        ↓
履约执行层
  ├─ 履约明细 FulfillmentItem(履约明细)
  ├─ 分流计划 PlanItem(履约计划)
  ├─ 生产工单 / 外协单
  └─ 出货单 / 出库单

销售层

销售层面向客户,记录客户下单内容:

  • 单品订单就是单品

  • 套装订单就是套装

  • 金额、税率、外币、单价状态都以销售行为准

执行层

执行层面向内部:

  • 非套装订单行生成 1 条履约明细

  • 套装订单行按套装定义展开为 N 条履约明细

  • 执行层负责库存、生产、采购、外协、出库


三、订单选品与报价机制

3.1 订单只有一个选品入口

订单录入时不允许让用户选择:

  • 来源=客户报价

  • 来源=产品档案

统一为一个关键字搜索入口。

系统内部自动分流:

  • 优先匹配客户产品报价

  • 找不到报价时允许选择基础产品

  • 选择基础产品后,自动执行 ensure_cus_price(customer_code, product_id)


3.2 ensure_cus_price 机制

当用户直接选择产品档案时:

如果客户报价已存在:
    返回已有 cus_price_id

如果客户报价不存在:
    自动创建客户报价行
    price_status = PENDING
    price = NULL
    返回新 cus_price_id

因此:

  • 订单明细必须引用 cus_price_id

  • cus_price_id 是订单、出货链路的价格链键

  • 不再单独设计 price_chain_id


3.3 客户报价表承担两类职责

客户报价表目前同时承担:

  1. 客户 SKU

    • 客户产品名称

    • 客户别名

    • 销售单位

    • 报价规格

    • 换算规则

  2. 价格策略

    • 单价

    • 阶梯价

    • 税率结构

    • 单价状态


四、单价待确认机制

4.1 状态字段独立控制

单价是否确认,不依赖 NULL、空字符串、0 判断。

使用字段:

price_status
0 = 待确认
1 = 已确认

订单明细、出货单明细都应保存:

  • cus_price_id

  • price_status

  • price

  • amount


4.2 单价待确认流程

允许出现:

  • 报价行有记录,但单价为空

  • 订单行引用该报价,价格状态为待确认

  • 出货单继续继承待确认状态

业务允许:

订单录入 → 审核 → 分流 → 生产/库存/外协 → 出货草稿/出库

但在出货单最终审核前必须完成单价确认。


4.3 出货最终审核是单价确认截止点

出货单最终审核前校验:

  1. 如果存在:

    • price_status = PENDING

    • 且 price IS NULL 或无有效单价

    则禁止审核。

  2. 如果存在:

    • price_status = PENDING

    • 但已经有单价

    则提示用户:

当前存在已填单价但未确认的明细,是否自动确认单价?

用户确认后:

  • 当前出货单相关明细置为已确认

  • 可选择是否同步回写客户报价

  • 已审核、已对账、已结账单据不允许被自动改价


4.4 报价确认后的批量回填

当客户报价由待确认变为已确认时:

  • 按 cus_price_id 查找订单明细、出货明细

  • 只回填 price_status = PENDING 的记录

  • 默认只补缺,不覆盖已有手工单价

  • 覆盖已有价格必须做成单独的强制操作


五、多币种与汇率设计

5.1 原则

系统采用:

本币核心记账 + 外币辅助核算

订单明细中保存:

  • 是否启用外币

  • 外币符号

  • 汇率

  • 外币单价

  • 外币金额

  • 本币单价

  • 本币金额

5.2 汇率锁定节点

订单录入时:

  • 引用客户默认币种或报价币种

  • 读取当前汇率

  • 允许用户手工调整汇率

  • 保存订单明细时锁定汇率

保存后:

  • 后续汇率档案更新不影响历史订单

  • 对账和收款阶段如有汇兑差异,在收款或对账相关模块单独记录


六、套装产品设计

6.1 销售层不拆套装

套装产品在销售层是独立产品:

  • 一个订单明细

  • 一个销售数量

  • 一个销售单价

  • 一个销售金额

  • 一个税率与外币结构

销售层不做套装子件价格分摊。


6.2 执行层自动展开套装

套装产品在执行层展开:

订单明细:红酒标签套装 × 10000 套

展开后:
  正标 × 10000
  背标 × 10000
  颈标 × 10000

展开后的明细用于:

  • 库存判断

  • 出库扣减

  • 生产分流

  • 外协采购

  • 成本归集


6.3 套装成本不分摊,而是聚合

套装销售是一个总价。

执行出库时,套装子件分别出库:

套装出库成本 = 子件1成本 + 子件2成本 + 子件3成本 ...

订单层不保存成本聚合字段。

成本应在出库/成本模块中根据实际出库明细计算。


6.4 FulfillmentItem 不允许手工调整

FulfillmentItem(履约明细)由系统根据订单行和套装定义生成:

  • 非套装:生成 1 条

  • 套装:生成 N 条

履约明细不允许用户手工增删改。

如果套装定义调整,应通过刷新/重建机制处理,并保留必要变更记录。


七、订单主表设计原则

7.1 表名

订单主表:

ord_order_master

命名遵循:

  • 同类表自然排列

  • 主表使用 master

  • 明细表使用 detail


7.2 主表只保存订单主流程状态

主表状态字段:

status
0 = 新入单
1 = 已审核
2 = 已处理
8 = 已关闭
9 = 作废

其中:

  • 已处理 = 订单已经完成分流

  • 分流方向包括库存、生产、外协采购

  • 主表不保存明细进度状态

这样可以支持简单查询:

status < 2

表示未处理订单。


7.3 主表不保存明细汇总状态

不在主表保存:

  • 生产状态

  • 出货状态

  • 对账状态

  • 结账状态

原因:

订单主表与明细是一对多关系,不同明细进度可能不一致。

如果在主表保存一个汇总状态,会产生逻辑冲突。

前端采用:

  • 默认订单主表列表

  • 点击“显示明细”或切换明细视图

  • 在明细视图中查看每行生产、出货、对账、结账状态


7.4 主表字段原则

主表应包含:

  • 客户编码

  • 客户订号

  • 订单类别

  • 结款方式

  • 业务员

  • 跟单员

  • 客服员

  • 主状态

  • 是否有附件

  • 入单/审核/处理人员与时间

主表不包含:

  • order_no

  • currency_code

  • 成本字段

  • 产品明细状态

  • 附件路径

  • 更新时间字段

说明:

  • currency_code 是系统全局属性,不放订单主表

  • 附件由附件模块统一管理,订单主表只保存 has_attach

  • 操作日志独立存在,不需要 updated_at


八、订单明细设计原则

8.1 明细表名

订单明细表:

ord_order_detail

8.2 明细不保存 line_no

订单明细统一使用 id 作为行标识。

不再保存 line_no。


8.3 明细不保存产品快照

订单明细不保存:

  • 产品编码快照

  • 产品名称快照

  • 产品规格快照

理由:

  • 订单本身只是销售计划

  • 最终需要法律/业务固定的执行单据是生产单、出货单

  • 产品快照应保存到生产单、出货单等执行单据


8.4 明细必须引用报价

订单明细必须保存:

cus_price_id

即使用户从产品档案选品,也通过 ensure 机制自动生成客户报价记录。


8.5 税率放明细

税率结构在明细层。

同一张订单允许不同明细有不同税率。

订单主表不保存税率。


8.6 交期放明细

订单交期放在订单明细:

due_date

因为同一张订单不同产品可能交期不同。


九、规格类型与卷料规格设计

9.1 产品档案规格类别

产品档案存在字段:

规格类别
0 = 通用规格
1 = 标签长宽规格
2 = 卷料库存规格

订单明细冗余保存:

spec_type

原因:

  • 产品档案后续修改规格类别,不影响历史订单

  • 前端可以直接根据订单明细判断输入方式

  • 查询不必强依赖产品档案 join


9.2 通用规格文本

订单明细保存:

spec_text

这是通用规格文本,不是卷料专用。

适用于:

  • 通用规格

  • 标签长宽规格

  • 卷料组合规格

例如:

100*80
150mm*500m*2卷

9.3 卷料规格字段

当 spec_type = 2 时,订单明细需要保存:

  • roll_width:卷料宽度,单位 mm

  • roll_length:卷料长度,单位 m

  • roll_count:卷数

业务规则:

qty = roll_width / 1000 * roll_length * roll_count
uom = ㎡
spec_text = roll_width + 'mm*' + roll_length + 'm*' + roll_count + '卷'

十、订单明细进度状态

订单明细保存两套独立进度状态。

10.1 make_status:生产/外协状态

0 = 未开单
1 = 生产中
2 = 已生产

外协单纳入生产/外协状态。


10.2 ship_status:出货单状态

0 = 未开单
1 = 已开单
2 = 已出库
3 = 已确认
4 = 已对账
8 = 已结账

说明:

  • 已确认表示出货单已完成确认,确认过程是修改数量、单价、金额的最后窗口

  • 已对账表示出货单已汇总生成对账单

  • 已结账表示账期封存,不允许再修改


十一、生产与外协执行设计

11.1 订单分流方向

订单处理后,明细或履约明细可以分流为:

  1. 库存出库

  2. 生产

  3. 外协采购

允许一行多 Plan(履约计划):

部分库存 + 部分生产 + 部分外协

11.2 生产模块独立

生产模块包括:

  • 印刷

  • 涂布

  • 分切

三个模块独立开生产工单。

订单不直接控制生产细节,只负责生成生产需求或 Plan。


11.3 模块之间的流转

建议采用:

上工序完工入库
  ↓
生成下工序生产需求
  ↓
下工序开生产单
  ↓
从半成品库存领料到工单

库存只识别物料状态,不识别生产模块。

半成品应作为库存物料状态或物料类型管理。


11.4 外协工序

生产路线中可以插入外协工序:

内部生产
  ↓
外协发出
  ↓
外协回厂入库
  ↓
继续生产 或 直接入库

外协回厂后形成半成品成本。


十二、出货设计

12.1 出货方式

系统同时支持两种模式:

  1. 订单直出

    • 适合标签原料

    • 一单一出为主

  2. 弱出货计划 / 波次拣货

    • 适合标签印刷

    • 多订单合并出货

    • 波次只是临时篮子,不是强约束单据


12.2 弱出货计划原则

如果设计出货计划,必须是弱约束:

  • 不锁死数量

  • 不要求计划数量等于实际出货数量

  • 不走复杂审批

  • 最终以出货单为准


12.3 待出货列表

系统应设计订单待出货列表,可查看:

  • 订单数量

  • 已出库数量

  • 可出货数量

  • 生产进度

  • 当前库存

  • 单价状态

用户可从待出货列表直接生成出货单。


12.4 出货单与仓库出库

系统可在逻辑上区分:

对外出货单

  • 面向客户

  • 保持销售层结构

  • 套装仍显示为套装

  • 保存销售单价、金额、税率、外币

内部出库明细

  • 面向仓库

  • 套装按子件展开

  • 只显示实物数量

  • 不显示销售价格

  • 用于扣库存与成本计算

这两者可以是两张单,也可以是出货单主从结构中的两个视图,后续再细化。


十三、对账与结账设计

13.1 对账模式

采用逐月对账模式:

当前账期 = 全局账期
上月完成对账与结账后
系统账期推进到下一个月

类似财务软件结账模式。


13.2 出货确认、对账、结账关系

出货单状态流转:

已开单 → 已出库 → 已确认 → 已对账 → 已结账

规则:

  • 出货确认前允许调整数量、单价、金额

  • 已确认后作为对账依据

  • 已对账后原则上不允许直接修改

  • 已结账后封存,只能通过冲销、红字或新单据处理


十四、索引与外键策略

14.1 索引策略

订单主表常用查询字段需要索引:

  • customer_code

  • order_type

  • pay_term

  • sales_id

  • follow_id

  • cs_id

  • status

  • created_at

数据权限查询常用:

sales_id = ?
follow_id = ?
cs_id = ?

建议建立联合索引:

(customer_code, created_at)
(sales_id, created_at)
(follow_id, created_at)
(cs_id, created_at)
(status, created_at)

是否给 order_type、pay_term 建联合索引,视实际查询频率决定。


14.2 外键策略

建议:

  • 订单明细 → 订单主表:可以加外键

  • 订单主表 → sys_user:不强制加外键,应用层校验即可

原因:

  • 单据与 sys_user 属于引用型关系

  • ERP 用户一般不物理删除,只禁用

  • 加外键会增加迁移、导入、测试库维护成本

应用层规则:

  • 用户下拉只能选择有效用户

  • 保存时校验用户是否存在

  • 禁止物理删除用户,只允许禁用


十五、前端交互设计

15.1 订单列表

默认显示订单主表。

显示字段:

  • 客户

  • 客户订号

  • 订单类别

  • 业务员

  • 跟单员

  • 客服员

  • 订单金额

  • 状态

  • 附件标记

  • 入单日期


15.2 明细视图切换

订单列表提供“显示明细”按钮或切换开关。

明细视图显示:

  • 产品

  • 规格文本

  • 数量

  • 单位

  • 交期

  • 单价状态

  • 生产状态

  • 出货状态

管理人员可在一个入口掌握订单全链路状态,但状态字段仍保留在明细层,避免主表状态冲突。


15.3 凭证式录入

订单录入要求:

  • 键盘高速录入

  • Suggest 联想

  • 弹窗多选

  • 支持从客户报价和产品档案统一搜索

  • 用户无感知创建客户报价

  • 单价待确认时有明显标记

  • 外币录入时显示汇率与本币换算结果


十六、后续待细化表结构

后续应继续设计:

  1. ord_order_fulfill
    履约明细,统一承载套装展开与非套装本体

  2. ord_order_plan
    履约计划,支持库存、生产、采购/外协多方向分流

  3. 出货单主表与明细表
    支持销售出货与内部出库视图

  4. 对账单主表与明细表
    支持逐月对账、结账封存

  5. 汇率档案表
    支持默认汇率、账期汇率、手工锁定汇率

  6. 附件模块
    通过 biz_type + biz_id 关联订单、出货单、对账单等业务单据


十七、一句话总结

订单模块采用“销售层不拆、执行层自动展开”的双层模型;价格通过客户报价 ID 形成待确认链路,出货最终审核前强制确认;订单主表只管订单阶段,明细表管生产与出货进度;套装成本在出库层聚合,不在订单层分摊;多币种采用本币落库、外币辅助、汇率锁定的财务软件式处理方式。


评论