odoo14流程配置
Odoo 审批流程 (Approval Flow) 实现彻底分析
概览
这个审批流程引擎是一个基于状态机和有向图的通用工作流引擎,核心代码位于 web_approval 模块,业务扩展在 jl_base 模块。它通过 _register_hook 机制动态 patch 业务模型的 create/write/unlink/fields_view_get 方法,实现"业务模型无需写审批代码即可接入"的解耦设计。
注意:代码库中没有名为 button_approve 的引擎方法。button_approve 是各个业务模型自定义的方法,其职责是更新业务状态字段并调用 common.mixin 提供的 start_approval() 来发起审批。真正的引擎入口是 approval.flow.commit_approval() 和 common.mixin.start_approval()。
1. button_approve 方法的定义
button_approve 不是审批引擎的方法,而是每个业务模型自己定义的"发起审批"按钮回调。它不属于任何单一模型,而是约定俗成地存在于各业务模型中。其通用模式:
def button_approve(self):
self.with_context(approval_callback=True).write({'state': 'in_approval', 'initiate': True})
self.start_approval() # 来自 common.mixin
定义位置(部分示例):
| 模型 | 文件路径 | 行号 |
|---|---|---|
jl.supervise |
d:\www\lims_log\vlims_backend\jl_person\models\jl_supervise.py |
57, 595 |
jl.translate.plan 等 |
d:\www\lims_log\vlims_backend\jl_person\models\jl_translate.py |
188, 451, 699 |
jl.person |
d:\www\lims_log\vlims_backend\jl_person\models\jl_person.py |
85 |
jl.labour.price |
d:\www\lims_log\vlims_backend\jl_labour\models\jl_labour_price.py |
288 |
jl.labour.need |
d:\www\lims_log\vlims_backend\jl_labour\models\jl_labour_need.py |
342 |
jl.entrust |
d:\www\lims_log\vlims_backend\jl_entrust\models\jl_entrust.py |
1500 |
jl.entrust.button_approve(行 1500-1507)是个特例——它只更新状态而不调用 start_approval,因为委托单的审批由其他流程触发:
def button_approve(self):
"""委托单(最终的审核节点)"""
self.with_context(**{"approval_callback": True}).write({'state': 'approval'})
而 jl.supervise.button_approve(行 57-59)是标准范式:
def button_approve(self):
self.with_context(approval_callback=True).write({'state': 'in_approval', 'initiate': True})
self.start_approval()
2. 审批流程核心模型类
2.1 引擎核心模型(web_approval 模块)
文件 d:\www\lims_log\vlims_backend\web_approval\models\approval_flow.py:
| 模型 | 类名 | 行号 | 职责 |
|---|---|---|---|
approval.flow |
ApprovalFlow |
89 | 审批流程定义表。绑定 ir.model(业务模型)、condition(domain 条件)、company_ids(适用公司)、node_ids/action_ids(节点和动作)、commit_run/completed_run/cancel_run(自动运行函数名)、版本管理(approval_flow_num/version/is_release) |
approval.flow.node |
ApprovalFlowNode |
1093 | 流程节点。is_start/is_end、type(group/user/job/leader/department_head/department_parent/expression)、会签 is_all_approval、加签 allow_before/after_increase、转签 allow_turn_to、complete_run |
approval.flow.node.action |
ApprovalFlowNodeAction |
1535 | 节点动作(边)。action_type(accept/refuse)、condition、sorce_node_id→target_node_id,构成有向图 |
approval.version.max |
MaxApprovalVersion |
58 | 记录流程版本号,用于版本管理 |
increase.type |
IncreaseType |
1617 | 加签类型字典 |
approval.circulated |
ApprovalCirculated |
1625 | 传阅记录 |
文件 d:\www\lims_log\vlims_backend\web_approval\models\approval_flow_instance.py:
| 模型 | 类名 | 行号 | 职责 |
|---|---|---|---|
approval.flow.instance |
ApprovalFlowInstance |
13 | 审批流实例(一次审批的运行实例)。state(active/complete/cancel)、str_node_ids(JSON 节点路径)、create_approval_instance_and_node |
approval.flow.instance.node |
ApprovalFlowInstanceNode |
393 | 实例节点(每个节点的一次运行)。state(active/running/complete/turn_to)、加签/转签字段、accept_next_action/refuse_next_action/jump_next_node |
approval.copy.for |
ApprovalCopyFor |
1175 | 审批抄送 |
文件 d:\www\lims_log\vlims_backend\web_approval\models\approval_state.py:
| 模型 | 类名 | 行号 | 职责 |
|---|---|---|---|
record.approval.state |
RecordApprovalState |
7 | 记录审批状态(每条业务单据对应一条)。model/res_id/approval_state/is_commit_approval/commit_user_id。是业务单据与审批实例的桥梁 |
approval |
Approval |
211 | 审批动作记录(每次同意/拒绝/转签的日志)。instance_node_id/action_type/say/user_id |
wait.approval |
WaitApproval |
254 | 待审批(待办)。create_wait_approval_for_users_and_instance |
文件 d:\www\lims_log\vlims_backend\web_approval\models\approval_form.py:
| 模型 | 类名 | 行号 | 职责 |
|---|---|---|---|
approval.from (AbstractModel) |
ApprovalForm |
31 | 业务模型必须继承的抽象基类。提供 approval_code/uuid/approval_company_id/apply_user_id/apply_department_id/parent_department/doc_approval_state/circulated 字段,以及 _compute_doc_approval_state(计算展示状态)。create 时自动通过 approval.from.code 生成编号 |
approval.from.code |
ApprovalFormCode |
11 | 流程编码规则(ir.sequence 关联) |
文件 d:\www\lims_log\vlims_backend\web_approval\models\approval_flow_record.py:
| 模型 | 类名 | 行号 | 职责 |
|---|---|---|---|
approval.record |
ApprovalRecord |
89 | 所有审批记录(SQL视图 _auto=False) |
i.proposed.approval.record |
IProposedApprovalRecord |
210 | 我提交的审批记录(视图) |
approval.circulated.summary |
ApprovalCirculatedSummary |
6 | 传阅汇总(视图) |
2.2 引擎扩展模型(jl_base 模块)
文件 d:\www\lims_log\vlims_backend\jl_base\models\approval_flow.py(_inherit 扩展引擎,增加业务特性):
| 类名 | 行号 | 继承 | 扩展内容 |
|---|---|---|---|
ApprovalFlow |
18 | approval.flow |
document(制度文档Html)、customer_node(自定义节点)、start_approval_user_field_id(发起人字段)、get_commit_uid(按字段取发起人)、commit_approval 重写 |
ApprovalFlowNode |
129 | approval.flow.node |
redirect_expression(待办路由表达式)、get_users_for_is_department_parent/head/leader 重写(支持 start_approval_user_field_id) |
ApprovalForm |
274 | approval.from |
approval_start_time、approval_done_time |
ApprovalFlowInstanceNode |
282 | approval.flow.instance.node |
redirect_info、is_customer、customer_node_name、approval_ids(One2many)、can_approval_current_node 重写、jump_next_node 重写、run_complete_func |
RecordApprovalState |
419 | record.approval.state |
approval_code、update_state_ref_record_state(回写业务单据 apply_user_id/approval_code/approval_start_time/approval_done_time)、create/write 时发系统通知 |
Approval |
485 | approval |
redirect_info、create_approval 重写(同时创建 done.approval 已办记录) |
WaitApproval |
521 | wait.approval + common.mixin |
is_done、approval_type、approval_code、approval_name、send_mail_datetime、wait_send_mail(邮件)、run_wait_approval_expire_notice(超时提醒) |
DoneApproval |
651 | common.mixin(新模型) |
已办记录,SQL/related 字段 |
OwnerApprovalRecord |
700 | common.mixin(_auto=False 视图) |
我发起的所有审批记录 |
ApprovalFlowCustomerRecord |
790 | 新模型 | 自定义节点信息,create_customer_approval 发起自定义审批 |
ApprovalCirculatedExtend |
967 | approval.circulated + common.mixin |
扩展传阅 |
3. 业务模型接入审批流程的配置
3.1 必须的继承
业务模型必须同时继承两个抽象类:
_inherit = ['mail.thread', 'mail.activity.mixin', 'common.mixin', 'approval.from']
approval.from(AbstractModel):提供审批相关字段(approval_code、apply_user_id、doc_approval_state、circulated 等)和_compute_doc_approval_state方法。这是接入审批流的标识。common.mixin(即JlCommonMixin,d:\www\lims_log\vlims_backend\jl_base\models\jl_common_mixin.py):提供所有审批操作方法:start_approval、confirm_approval、refuse_approval、cancel_approval、close_approval、endorsement_transfer、before_increase_sign、after_increase_sign、share_approval、get_approval_info、get_approve_history。
3.2 需要在模型上添加的字段
业务模型通常自己定义一个 state Selection 字段(业务状态)和一个 initiate Boolean(是否已发起审批)。这些不是引擎强制要求,但 button_approve 需要操作它们。approval.from 已提供审批状态展示字段 doc_approval_state。
jl_base 扩展的 RecordApprovalState.update_state_ref_record_state(行 425-442)会在审批状态变化时回写业务单据的 apply_user_id、approval_code、approval_start_time、approval_done_time——所以业务模型若继承了 approval.from(及 jl_base 扩展),会自动获得这些字段的回写。
3.3 注册到审批配置表
业务模型不需要在代码中注册。注册是通过后台在 approval.flow 表中创建配置记录完成的:配置时选择 model_id(ir.model)指向业务模型,设置 condition、company_ids,然后设计节点和动作。
引擎通过 _register_hook(approval_flow.py 行 455-718)动态 patch 所有在 approval.flow 中配置了 active=True 的模型:重写其 create(自动创建 record.approval.state)、write(审批中禁止修改)、unlink(审批中禁止删除)、fields_view_get(注入"提交审核/暂停/恢复/取消/审批/传阅"按钮)、_apply_ir_rules/check_access_rule(跳过权限检查)。
3.4 调用链
发起审批(button_approve → start_approval):
业务模型.button_approve() # 业务模型自定义
→ common.mixin.start_approval() # jl_common_mixin.py:1163
→ approval.flow.get_approval_flow_and_check_approval() # approval_flow.py:974
→ approval.flow.commit_approval(model, res_id) # jl_base 扩展版 approval_flow.py:47
→ record.approval.state.change_approval_state_to_active()
→ approval.flow.instance.create_approval_instance_and_node()
→ instance.create_wait_user() # 创建 wait.approval 待办
→ instance.commit_first_node() # 激活首个节点
审批同意(confirm_approval):
common.mixin.confirm_approval(instance_node_id, reason) # jl_common_mixin.py:1466
→ common.mixin._approval(instance_node_id, 'accept', ...) # jl_common_mixin.py:1422
→ approval.create_approval() # 创建审批记录
→ instance_node.accept_next_action(document, jump, multi_approval) # approval_flow_instance.py:856
→ node.state='complete' + complete_run_fun()
→ set_next_node_state() # 激活下一节点
→ 若全部完成 → instance.run_after_the_instance_is_executed()
→ res_state.approval_state='complete'
→ flow_id.completed_run_fun(document) # 执行配置的"完成后自动运行"函数
button_commit 在此代码库中不存在;它属于 Odoo 标准采购模块(purchase),与本审批引擎无关。
4. 所有接入审批流程的业务模型
通过 _inherit 包含 approval.from 找到全部接入模型:
4.1 business_approval 模块(专门用于给既有模型追加审批能力)
文件 d:\www\lims_log\vlims_backend\business_approval\models\:
| 文件 | 模型 | 接入方式 |
|---|---|---|
sale_order.py |
jl.sale.order |
_inherit = ['approval.from', 'jl.sale.order'],仅追加 approval.from,无自定义 button_approve |
res_partner.py |
res.partner |
_inherit = ['approval.from', 'res.partner'] |
project_task.py |
project.task |
_inherit = ['approval.from', 'project.task'] |
ir_attachment.py |
ir.attachment |
_inherit = ['approval.from', 'ir.attachment'] |
4.2 各业务模块
| 模块/文件路径 | 模型名 | 接入方式(关键点) |
|---|---|---|
jl_entrust\models\jl_entrust.py:78 |
jl.entrust |
_inherit=[...,'common.mixin','approval.from'];button_approve(1500行)只改 state;button_entrust(1509行)为审批完成回调(配置在 completed_run) |
jl_entrust\models\jl_collaboration.py:24 |
jl.collaboration |
同上模式 |
jl_person\models\jl_supervise.py:11,129,400 |
jl.supervise 等3个模型 |
button_approve(57行) 改 state+initiate 并调 start_approval();create_and_approval(62行) 创建后立即审批 |
jl_person\models\jl_translate.py:13,232,489,739 |
jl.translate.plan 等4个模型 |
button_approve(188/451/699行) 改 state+initiate 并调 start_approval() |
jl_person\models\jl_person.py:10,110 |
jl.person 等2个模型 |
button_approve(85行) 调 start_approval() |
jl_labour\models\jl_labour.py:22 |
jl.labour |
继承审批 |
jl_labour\models\jl_labour_price.py |
jl.labour.price |
button_approve(288行) 改 state='waiting' 并 start_approval() |
jl_labour\models\jl_labour_need.py |
jl.labour.need |
button_approve(342行) 批量发起审批 |
jl_outsource\models\jl_subcontract.py:40 |
jl.subcontract |
继承审批 |
jl_report\models\jl_subcontract_report.py:9 |
委外技术验收单 | 继承审批 |
jl_check_accept\models\jl_check_accept.py:32 |
jl.check.accept |
继承审批 |
jl_check_accept\models\jl_final_statement.py:11 |
jl.final.statement |
继承审批 |
jl_disassembly_manage\models\jl_disassembly_plan.py:18 |
jl.disassembly.plan |
继承审批 |
jl_ingredients_manage\models\jl_ingredients_declaration.py:16 |
jl.ingredients.declaration |
行200:write state='approval'+is_commit_approval=True(不走 button_approve,直接发起) |
jl_ingredients_manage\models\jl_annual_plan.py:12 |
jl.annual.plan |
行58:同上模式 |
jl_execute\models\jl_execute_order.py:309 |
jl.execute.order |
继承审批 |
jl_experimental_assistant_base\models\jl_outline.py:115 |
jl.outline |
行865:write state='approval'+is_commit_approval=True |
jl_vlims_extend\models\jl_srlc_contract.py:10 |
jl.srlc.contract |
继承审批 |
jl_vlims_extend\models\jl_site_order_ext.py:15 |
jl.site.order(扩展) |
_inherit=['approval.from','jl.site.order'] |
jl_plan\models\jl_experimental_plan.py:27 |
jl.experimental.plan |
继承审批 |
jl_plan\models\jl_experimental_total.py:41 |
jl.experimental.total |
继承审批 |
jl_plan\models\jl_maintain_exchange.py:15 |
jl.maintain.exchange |
继承审批 |
jl_base\models\res_partner.py:15 |
res.partner(扩展) |
继承审批 |
接入方式分两类:
- 定义
button_approve:显式更新 state 字段后调用self.start_approval()(最常见范式) - 仅继承不定义 button_approve:通过
business_approval模块或直接_inherit=['approval.from', <原模型>]只追加审批能力,审批由其他途径(如控制器/web/approval/commit_approval或前端按钮type=commitApproval)触发
create_and_approval 方法(jl_supervise.py:62、jl_person.py:70):创建记录后立即调用 button_approve,用于"保存并发起审批"场景。
5. 审批节点的数据配置方式
5.1 节点配置是后台手动配置
审批流程、节点、动作全部在后台手动配置,没有 XML/CSV 初始数据。配置入口为菜单 "流程审批 → 流程配置":
- 菜单定义:
d:\www\lims_log\vlims_backend\web_approval\views\approval_flow_view.xml:233<menuitem name="流程配置" id="menu_action_approval_flow" action="action_approval_flow" groups="group_approval_config" parent="menu_approval_root" sequence="40"/> - 根菜单"流程审批":
d:\www\lims_log\vlims_backend\web_approval\views\menu.xml - 表单视图:
approval_flow_view.xml:45(view_approval_flow_form),包含"发布流程/升级流程/设计流程"按钮 - 设计器是前端 JS 组件
approval_diagram(approval_flow.py:164的show_flow_designer)
5.2 仅有序列号初始数据
d:\www\lims_log\vlims_backend\web_approval\data\approval_from_code_data.xml 只定义了两个 ir.sequence:
approval.from.code(流程编号 S+年月日)approval.flow.instance.code(实例编号 年月日)
以及一条默认 approval.from.code 记录。没有任何预置的审批流配置。
5.3 配置表与配置项
在 approval.flow 表单(approval_flow_view.xml)中配置:
model_id:指向业务模型(ir.model)condition:domain 表达式(条件审批,如[("amount", ">", 10000)])company_ids:适用公司node_ids:节点(开始/结束/中间审批节点,每节点配 type、审批人、会签、加签权限、complete_run)action_ids:节点动作(源节点→目标节点,accept/refuse,可带 condition)commit_run/completed_run/cancel_run:自动运行的业务方法名(逗号分隔)approval_can_run/approval_cannot_run:审批后(不)能执行的方法(如 write/unlink)- 版本管理:
approval_flow_num/version/is_release,"发布流程"按钮激活
另外 approval.from.code(流程编号规则)在菜单 "流程审批 → 流程编号" 配置(approval_form_code_view.xml:56)。
record.approval.state(记录审批状态)在菜单 "流程审批 → 记录审批状态"(record_approval_state_view.xml:26,仅 group_approval_config 组可见)。
总结:新模型类接入审批流程的配置清单
要让一个新 Odoo 模型接入此审批流程引擎,需要:
-
模块依赖:在
__manifest__.py的depends中加入web_approval和jl_base(jl_base提供common.mixin和引擎扩展)。 -
模型继承:在模型类中添加继承:
_inherit = ['mail.thread', 'mail.activity.mixin', 'common.mixin', 'approval.from']approval.from是接入审批的标识(必选)common.mixin提供所有审批操作方法start_approval/confirm_approval/refuse_approval/cancel_approval等(必选)
-
定义业务状态字段:模型自定义一个
stateSelection 字段和(可选)initiateBoolean,用于业务状态流转展示。approval.from已提供doc_approval_state(审批展示状态)、approval_code、apply_user_id等。 -
定义发起审批方法:定义
button_approve方法,范式:def button_approve(self): self.with_context(approval_callback=True).write({'state': 'in_approval', 'initiate': True}) self.start_approval()approval_callback=Truecontext 用于绕过引擎 patch 的 write 限制(审批中不可修改)。 -
(可选)定义审批回调方法:在
approval.flow配置中填写completed_run/cancel_run等方法名,这些方法需在本模型上定义,引擎会在审批完成/取消时自动调用(如jl.entrust.button_entrust)。 -
后台配置审批流:进入"流程审批 → 流程配置"菜单,新建
approval.flow记录:- 选择
model_id为本模型 - 设置
condition(可选)和company_ids - 用"设计流程"按钮配置节点(开始/审批节点/结束)和节点动作(边)
- 点击"发布流程"激活
- 选择
-
(可选)配置流程编号:在"流程审批 → 流程编号"为模型配置
approval.from.code(ir.sequence),否则用默认序列。 -
无需:不需要在代码中注册到任何配置表(
_register_hook会自动扫描approval.flow中active=True的记录并 patch 对应模型);不需要定义_get_flow方法(引擎的get_approval_flow会通过 model_id + condition + company 匹配)。
关键文件路径汇总:
- 引擎核心:
d:\www\lims_log\vlims_backend\web_approval\models\approval_flow.py、approval_flow_instance.py、approval_state.py、approval_form.py - 引擎扩展与业务 mixin:
d:\www\lims_log\vlims_backend\jl_base\models\approval_flow.py、jl_common_mixin.py - 控制器:
d:\www\lims_log\vlims_backend\web_approval\controllers\main.py - 配置视图:
d:\www\lims_log\vlims_backend\web_approval\views\approval_flow_view.xml、menu.xml - 审批向导:
d:\www\lims_log\vlims_backend\web_approval\wizard\approval_wizard.py(button_ok执行同意/驳回)
子代理已完成全库扫描,现在把"其他用到审批的地方"这一项给你补全,并对前面的分析做两处修正补充。
四、所有接入审批流程的业务模型(完整清单)
通过全库扫描 _inherit 包含 approval.from 的模型,接入方式分两类:
A. 标准范式:自定义 button_approve → 改 state → start_approval()
| 模型 | 文件 | button_approve 行号 | 备注 |
|---|---|---|---|
jl.person.auth |
jl_person/models/jl_person.py | :85 | 你选中的这个,有 create_and_approval |
jl.supervise 等 3 个 |
jl_person/models/jl_supervise.py | :57 | 也有 create_and_approval(:62) |
jl.translate.plan 等 4 个 |
jl_person/models/jl_translate.py | :188/:451/:699 | |
jl.labour.price |
jl_labour/models/jl_labour_price.py | :288 | state 用 waiting |
jl.labour.need |
jl_labour/models/jl_labour_need.py | :342 | 批量发起 |
B. 特例:button_approve 只改 state,不调 start_approval()
| 模型 | 文件 | 行号 | 说明 |
|---|---|---|---|
jl.entrust |
jl_entrust/models/jl_entrust.py | :1500 | 委托单这里只是"最终审核节点"的回调,真正的发起由 completed_run 里配的 button_entrust(:1509) 等触发。这说明 button_approve 不是引擎约定,只是惯例名——真正引擎入口永远是 start_approval。 |
C. 不走 button_approve,直接 write + start_approval
| 模型 | 文件 | 行号 |
|---|---|---|
jl.ingredients.declaration |
jl_ingredients_manage/models/jl_ingredients_declaration.py | :200 |
jl.annual.plan |
jl_ingredients_manage/models/jl_annual_plan.py | :58 |
jl.outline |
jl_experimental_assistant_base/models/jl_outline.py | :865 |
D. 仅继承、不写 button:用 business_approval 模块给既有模型"贴"审批能力
business_approval/models/ 下用 _inherit=['approval.from','<原模型>'] 给 jl.sale.order、res.partner、project.task、ir.attachment 追加审批字段,发起动作由前端 type=commitApproval 按钮经控制器 /web/approval/commit_approval 触发。这是接入成本最低的方式:零业务方法,全靠后台配置 + 引擎 patch。
两处修正/补充(相对前面的回答)
-
button_approve不是引擎方法,是各业务模型自定义的按钮回调,名字只是惯例。引擎真正入口是common.mixin.start_approval()(jl_common_mixin.py:1163)和approval.flow.commit_approval()。 -
审批通过的回调路径(之前只讲了发起链,补全同意链):
common.mixin.confirm_approval(instance_node_id, reason) # jl_common_mixin.py:1466 → _approval(node_id, 'accept', ...) → approval.create_approval() # 写审批日志 + done.approval 已办 → instance_node.accept_next_action(document, ...) → 当前节点 complete + complete_run_fun() → set_next_node_state() 激活下一节点 → 全部完成 → instance.run_after_the_instance_is_executed() → record.approval.state 写 'complete' → flow.completed_run_fun(document) # 执行后台配的"完成后自动运行"方法这就是为什么
jl.entrust那种"只改 state"的button_approve能工作——它其实是被配置在completed_run/commit_run里、由引擎在节点流转时回调,而不是前端直接调。 -
后台配置入口:菜单 流程审批 → 流程配置(approval_flow_view.xml:233,需
group_approval_config组权限),点"设计流程"打开前端 JS 流程图编辑器approval_diagram,配好节点和 accept/refuse 动作后点"发布流程"激活。无任何 CSV/XML 预置流程数据,只有两条ir.sequence(approval_from_code_data.xml)。
最终:新模型接入审批的完整配置清单
代码侧(你的模型类):
__manifest__.py的depends加web_approval、jl_base_inherit = ['mail.thread','mail.activity.mixin','common.mixin','approval.from']- 自定义
stateSelection(业务状态)+initiateBoolean(可选) - 保证有
company_id字段(审批流配"适用公司"时匹配必需) - 定义发起方法(二选一):
- 标准:
button_approve→with_context(approval_callback=True).write(state=in_approval)→self.start_approval() - 零代码:不写方法,靠前端
commitApproval按钮经控制器触发
- 标准:
- 如需自动编号:配
ir.sequence+ 在 create 里next_by_code,并在approval.from.code配编码规则(不配则用兜底序列) - 审批完成/取消后要跑的业务方法,定义在本模型上,方法名填到后台
completed_run/cancel_run/commit_run
后台配置侧(运行时数据):
approval.flow新建一条,model_id选你的模型、company_ids/condition/commit_approval_group_id按需- "设计流程"配节点(开始/审批/结束,每节点 type=user/group/job/leader、会签/加签/转签权限)
- 至少一条
action_type='accept'的节点动作(否则报"没有为审批定义审批流程") active=True后"发布流程" → 引擎_register_hook自动 patch 你的模型 create/write/unlink/fields_view_get 5.(可选)approval.from.code配流程编号规则
不需要做的:
- 不用在代码里注册到配置表(
_register_hook自动扫描approval.flow中active=True记录) - 不用写
_get_flow(引擎get_approval_flow按 model_id+company+condition 匹配) - 不用自己写 create/write 拦截(patch 后的 write 自动拦截审批中修改、自动建
record.approval.state)
这样你的新模型就完整接入了审批流程。

浙公网安备 33010602011771号