主题
审批流程
指用户在业务单据表单上通过审批按钮完成审批的整个过程,主要操作有:提交发起审批、同意推进流程、加签临时插入审批人、驳回到指定节点重新审批、查看流程图追踪进度,以及审批过程中自动执行节点代码。
提交
1. 操作步骤
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 点击 提交 按钮 | 按钮位于业务单据表单顶部 |
| 2 | 选择审批模板 | 下拉框只列出当前单据满足开始条件的已启用模板 |
| 3 | 填写审批备注 | 可选,建议填写 |
| 4 | 点击 确认 按钮 | 系统创建审批实例并启动流程 |
2. 状态变化
| 对象 | 状态变化 |
|---|---|
| 业务单据 | 不变(状态由审批代码控制) |
| 审批实例 | 运行中 |
| 第一个审批节点 | READY(就绪待审批) |
| 其余节点 | WAITING(等待中) |
| 提交人 | 提交 按钮消失,显示 流程图 按钮 |
| 审批人 | 收到审批通知,表单页面显示同意、驳回、加签、流程图四个按钮 |
| 抄送人 | 收到审批通知 |
同意
1. 操作步骤
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 点击 同意 按钮 | 仅审批节点 就绪(READY) + 当前用户是审批人时显示 |
| 2 | 填写审批备注 | 可选,建议填写 |
| 3 | 点击 确认 按钮 | 执行审批通过代码,推进流程到下一审批节点 |
2. 状态变化
| 对象 | 状态变化 |
|---|---|
| 业务单据 | 状态由审批代码决定 |
| 审批实例 | 运行中或已完成(如果下一节点是结束节点) |
| 第一个审批节点 | COMPLETED(已完成) |
| 下一个审批节点 | READY或COMPLETED(如果下一节点是结束节点) |
| 其余节点 | WAITING(等待中) |
| 审批人 | 收到审批通知,表单页面显示同意、驳回、加签、流程图四个按钮 |
| 抄送人 | 收到审批通知 |
| 提交人 | 如果审批实例已完成,提交人收到审批通知 |
加签
1. 什么是加签
加签是指在当前审批节点前或后临时插入一个新的审批人。典型场景:审批人认为需要征求某人意见,先加签给那人审批,再回到自己。
2. 前加签与后加签的区别
| 前加签 | 后加签 | |
|---|---|---|
| 插入位置 | 在当前 READY 节点前面 | 在当前 READY 节点后面 |
| 效果 | 加签节点先审批,通过后回到原审批节点 | 原审批节点审批通过,加签节点成为新的 READY 节点 |
| 适用场景 | 领导表态之前先让法务看一下 | 我批完了,但还需财务确认 |
3. 操作步骤
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 点击 加签 按钮 | 仅审批节点 就绪(READY) + 当前用户是审批人时显示 |
| 2 | 选择加签类型 | 前加签(在当前节点前插入)/ 后加签(在当前节点后插入) |
| 3 | 输入新节点名称 | 如"法务审核" |
| 4 | 选择加签审批人 | 多选用户列表 |
| 5 | 填写审批备注 | 可选,建议填写 |
| 6 | 点击 确认 按钮 | 审批实例插入新节点 |
驳回
1. 操作步骤
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 点击 驳回 按钮 | 仅审批节点 就绪(READY) + 当前用户是审批人时显示 |
| 2 | 选择驳回目标节点 | 下拉框列出所有已完成的 用户任务节点和开始节点 |
| 3 | 填写驳回备注 | 可选,建议写明驳回原因 |
| 4 | 点击 确认 按钮 | 执行驳回逻辑:执行被驳回节点和驳回目标节点之间的所有用户节点配置的驳回代码,并将这些节点和被驳回节点都改为 WAITING 状态;驳回目标节点改为 READY 状态 |
2. 驳回场景
| 场景 | 处理 |
|---|---|
| 驳回到 开始节点 | 删除整个审批实例,相当于撤回审批,单据恢复未发起状态 |
| 驳回到之前的 用户任务 | 流程退回到该节点,该节点重新变为 READY |
| 驳回路径包含多个节点 | 依次执行每个节点的 驳回代码 |
3. 状态变化
| 对象 | 状态 |
|---|---|
| 业务单据 | 由被驳回节点的 驳回代码 决定(如退回草稿) |
| 审批实例 | running |
| 驳回目标节点 | READY |
| 被驳回节点 | 节点状态变为 WAITING |
| 驳回目标审批人 | 重新收到审批通知 |
| 提交人 | 收到"审批被驳回"通知 |
流程图
1. 操作入口
| 入口 | 位置 | 说明 |
|---|---|---|
| 业务表单 | 点击 流程图 按钮 | 审批实例存在时可见 |
| 实例列表 | 点击 查看流程图 按钮 | 实例 列表视图 |
| 实例表单 | 点击 查看流程图 按钮 | 实例 表单详情 |
2. 流程图颜色标注含义
| 颜色 | 含义 |
|---|---|
| 🟢 绿色 | 已完成节点 |
| 🔵 青色 | 待审批节点 |
| ⚪ 默认 | 等待中节点 |
| 🟢 绿色箭头 | 已走过的流转路径 |
节点代码执行
1. 触发时机
| 操作 | 触发代码 | 备注说明 |
|---|---|---|
| 同意 | 批准执行方法 → 批准执行代码 | |
| 驳回 | 驳回执行方法 → 驳回执行代码 | 倒序逐一执行被驳回节点的 驳回 代码 |
| 脚本任务 | 脚本代码 | 引擎自动执行(无人工交互) |
2. 批准/驳回执行方法
批准/驳回执行方法是单行 Python 表达式,如下所示:
python
# 同意时确认订单
self.button_confirm()
# 驳回时退回草稿
self.button_draft()
# 同意时写入审批日期
self.write({'x_approved_date': fields.Date.today()})3. 批准/驳回执行代码
批准/驳回执行代码支持多行、条件判断、ORM 操作等复杂逻辑,预置变量见下表:
| 变量 | 类型 | 说明 | 使用示例 |
|---|---|---|---|
env | Environment | Odoo 执行环境,可访问所有 ORM | env['sale.order'].search([]) |
cr | Cursor | 数据库游标 | 不常用(优先用 env) |
uid | int | 当前用户 ID | uid |
user | Record | 当前用户记录 | user.name |
company | Record | 当前公司记录 | company.name |
model | Model | 流程绑定的模型类 | model.search([]) |
record | Record | 当前正在审批的单据记录 | record.write({'state': 'done'}) |
time | module | Python time 模块 | time.time() |
datetime | module | Python datetime 模块 | datetime.date.today() |
dateutil | module | Python dateutil 模块 | dateutil.parser.parse(...) |
timezone | function | pytz timezone 函数 | timezone('Asia/Shanghai') |
float_compare | function | 浮点数精确比较 | float_compare(a, b, 2) |
log | function | 日志记录到 ir_logging 表 | log('审批通过', level='info') |
_logger | Logger | Python Logger(服务器日志) | _logger.info('审批完成') |
UserError | Exception | 用户警告异常 | raise UserError('金额超限') |
Command | namespace | Odoo x2many 操作命令 | Command.create({...}) |
4. 审批通过时的代码编写范例
范例 1:简单确认订单
python
# 批准/驳回执行方法(单行)
self.button_confirm()范例 2:带日志和字段更新的审批代码
python
# 批准/驳回执行代码(多行)
log(f"订单 {record.name} 审批通过,金额:{record.amount_total}")
# 更新自定义字段
record.write({
'x_approved_date': datetime.date.today(),
'x_approved_by': user.id,
})
# 如果金额超过 50000,额外通知财务
if record.amount_total > 50000:
finance_group = env.ref('account.group_account_manager')
env['mail.activity'].create({
'res_id': record.id,
'res_model_id': model._abstract is False and model._name or record._name,
'activity_type_id': env.ref('mail.mail_activity_data_todo').id,
'summary': '大额订单已审批,请复核',
'user_ids': [(6, 0, finance_group.users.ids)],
})5. 审批拒绝时的代码编写范例
python
# Reject Code
log(f"订单 {record.name} 被驳回,原因:驳回")
# 将订单退回草稿状态
if record.state == 'confirmed':
record.write({'state': 'draft'})
# 给提交人发内部消息
record.message_post(
body=f"审批被驳回,请修改后重新提交",
subtype_xmlid='mail.mt_comment',
)6. 调试技巧
| 技巧 | 说明 |
|---|---|
log() | 写入 ir_logging 表,可在 设置 → 技术 → 数据库结构 → 记录 中查看 |
_logger.info() | 写入 Odoo 服务器日志文件 |
raise UserError() | 抛出用户可见的警告消息,终止审批操作 |
record.message_post() | 在单据的 Chatter 中留下记录,直观可见 |
学习交流
