关于 frappe-impl-workflow
为 Frappe 开发者提供的文档工作流实施指南,覆盖设计、配置、测试和常见审批模式。内容也说明状态、角色、条件及文档状态之间的配置关系。
主要功能
- 01工作流状态与转换设计
- 02按角色配置审批权限
- 03设置条件转换与自审批限制
- 04配置通知及状态字段更新
- 05手动与程序化测试
适用场景
- 01为采购订单设置多级审批
- 02按金额将文档路由至不同审批人
- 03为文档配置驳回后返修流程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ impertio-studio/ frappe_claude_skill_package --skill frappe-impl-workflow安装后在 Claude Code 中输入/frappe-impl-workflow确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/.gitkeepanti-patterns.mddecision-tree.mdexamples.mdworkflows.md详细介绍
Frappe 工作流实现
在 Frappe 中实现文档工作流的分步指南。涵盖设计、设置、测试和常见的审批链模式。
快速参考:实现检查清单
1. □ Design states and transitions on paper/diagram first
2. □ Create Workflow State records (master list)
3. □ Create Workflow Action Master records (Approve, Reject, etc.)
4. □ Create the Workflow DocType record
5. □ Add states with correct doc_status values
6. □ Add transitions with roles, actions, and conditions
7. □ Set allow_edit roles per state
8. □ Configure email notifications (optional)
9. □ Test every transition path with test users
10. □ Verify self-approval blocking works as expected
第 1 步:设计工作流
在操作界面之前,先在纸上规划工作流。
确定状态
始终先列出文档的每个不同阶段:
Example — Purchase Order Approval:
Draft → Pending Review → Pending Approval → Approved → Submitted → Cancelled
将 DocStatus 映射到状态
对于可提交的 DocType,始终正确设置 doc_status:
| 阶段 | doc_status | 含义 |
|---|---|---|
| 所有“进行中”状态 | 0 | 文档为草稿,可编辑 |
| 最终批准/生效状态 | 1 | 文档已提交,已锁定 |
| 已取消状态 | 2 | 文档已取消 |
切勿将 doc_status = 1 设置为中间审批状态。已提交的文档无法返回草稿状态。提交后,唯一可行的后续路径是进入另一个已提交状态或取消。
映射转换
对于每个状态,定义:可以执行哪些操作?由谁执行?是否有任何条件?
Draft →[Submit for Review / Creator]→ Pending Review
Pending Review →[Approve / Reviewer]→ Pending Approval
Pending Review →[Reject / Reviewer]→ Draft
Pending Approval →[Approve / Manager]→ Approved
Pending Approval →[Reject / Manager]→ Draft
Approved →[Submit / Manager]→ Submitted (doc_status=1)
Submitted →[Cancel / Manager]→ Cancelled (doc_status=2)
第 2 步:创建前置记录
2a. 创建工作流状态
前往 Workflow State 列表,或通过 API 创建:
# Create states with appropriate styles
states = [
{"workflow_state_name": "Draft", "style": ""},
{"workflow_state_name": "Pending Review", "style": "Primary"},
{"workflow_state_name": "Pending Approval", "style": "Warning"},
{"workflow_state_name": "Approved", "style": "Success"},
{"workflow_state_name": "Submitted", "style": "Info"},
{"workflow_state_name": "Rejected", "style": "Danger"},
{"workflow_state_name": "Cancelled", "style": "Inverse"},
]
for s in states:
if not frappe.db.exists("Workflow State", s["workflow_state_name"]):
frappe.get_doc({"doctype": "Workflow State", **s}).insert()
可用样式:Primary、Success、Warning、Danger、Info、Inverse(留空则使用默认样式)。
2b. 创建工作流操作主记录
actions = ["Submit for Review", "Approve", "Reject", "Send Back", "Cancel"]
for action in actions:
if not frappe.db.exists("Workflow Action Master", action):
frappe.get_doc({
"doctype": "Workflow Action Master",
"workflow_action_name": action
}).insert()
第 3 步:创建工作流
通过界面
前往 Setup > Workflow > New Workflow:
- 设置 Workflow Name(例如,“采购订单审批”)
- 设置 Document Type(例如,“Purchase Order”)
- 勾选 Is Active
- 在 States 表格中添加状态
- 在 Transitions 表格中添加转换
通过 Python
workflow = frappe.get_doc({
"doctype": "Workflow",
"workflow_name": "Purchase Order Approval",
"document_type": "Purchase Order",
"is_active": 1,
"send_email_alert": 1,
"states": [
{"state": "Draft", "doc_status": "0", "allow_edit": "Purchase User"},
{"state": "Pending Approval", "doc_status": "0", "allow_edit": "Purchase Manager"},
{"state": "Approved", "doc_status": "1", "allow_edit": "Purchase Manager"},
{"state": "Rejected", "doc_status": "0", "allow_edit": "Purchase User"},
{"state": "Cancelled", "doc_status": "2"},
],
"transitions": [
{
"state": "Draft",
"action": "Submit for Review",
"next_state": "Pending Approval",
"allowed": "Purchase User",
"allow_self_approval": 1,
},
{
"state": "Pending Approval",
"action": "Approve",
"next_state": "Approved",
"allowed": "Purchase Manager",
"allow_self_approval": 0,
},
{
"state": "Pending Approval",
"action": "Reject",
"next_state": "Rejected",
"allowed": "Purchase Manager",
},
{
"state": "Rejected",
"action": "Submit for Review",
"next_state": "Pending Approval",
"allowed": "Purchase User",
},
{
"state": "Approved",
"action": "Cancel",
"next_state": "Cancelled",
"allowed": "Purchase Manager",
},
],
})
workflow.insert()
第 4 步:配置高级功能
条件转换
添加 Python 条件,仅在符合条件时显示转换:
# Only allow approval for orders above 50000 by Senior Manager
{
"state": "Pending Approval",
"action": "Approve",
"next_state": "Approved",
"allowed": "Senior Manager",
"condition": "doc.grand_total > 50000",
}
# Standard approval for orders up to 50000
{
"state": "Pending Approval",
"action": "Approve",
"next_state": "Approved",
"allowed": "Purchase Manager",
"condition": "doc.grand_total <= 50000",
}
始终在条件中使用 doc.fieldname 语法(文档以字典形式提供)。
条件中可用:frappe.db.get_value()、frappe.db.get_list()、frappe.session.user、frappe.utils.now_datetime()、frappe.utils.add_to_date()、frappe.utils.get_datetime()。
阻止自我审批
在审批转换中设置 allow_self_approval = 0。这意味着:
- 文档所有者(创建者)不能执行此操作
- 管理员始终不受此限制
- 具有所需角色的其他用户可以执行此操作
电子邮件通知
- 在工作流上设置
send_email_alert = 1 - 在每个状态行中设置
send_email = 1(默认值) - 可选:通过
next_action_email_template关联Email Template - 在状态行中添加自定义
message,作为内联通知文本
状态变更时更新字段
使用状态行上的 update_field 和 update_value 自动设置文档字段:
# Set approval_status when entering "Approved" state
{"state": "Approved", "doc_status": "1",
"update_field": "approval_status", "update_value": "Approved"}
# Use expression to set approval date dynamically
{"state": "Approved", "doc_status": "1",
"update_field": "custom_approved_on", "update_value": "frappe.utils.now()",
"evaluate_as_expression": 1}
第 5 步:测试工作流
手动测试检查清单
- 创建测试文档 — 确认其初始状态为第一个状态(草稿)
- 检查可用操作 — 只有具有从草稿状态出发的转换权限的角色才会看到按钮
- 执行每个转换 — 确认状态正确变更
- 测试拒绝路径 — 确认文档返回到正确状态
- 测试自我审批 — 以文档所有者身份登录,确认转换被阻止
- 测试条件 — 创建符合/不符合条件的文档,确认按钮的显示情况
- 测试电子邮件通知 — 确认状态变更时已发送电子邮件
- 使用不可提交的 DocType 测试 — 确认所有
doc_status = 0
程序化测试
# Get available transitions for a document
from frappe.model.workflow import get_transitions, apply_workflow
doc = frappe.get_doc("Purchase Order", "PO-00001")
transitions = get_transitions(doc)
# Returns list of dicts with action, next_state, allowed, etc.
# Apply a workflow action
updated_doc = apply_workflow(doc, "Approve")
# Returns the updated document after state change
常见工作流模式
模式 1:顺序审批链
Draft → Level 1 Review → Level 2 Review → Approved → Submitted
每个级别都有自己的角色。文档按顺序通过各级审批。
模式 2:按金额进行条件路由
Draft → Pending Approval
├─[amount <= 10000 / Team Lead]─→ Approved
├─[amount <= 50000 / Manager]──→ Approved
└─[amount > 50000 / Director]──→ Approved
在每个转换上使用 condition,根据文档值进行路由。
模式 3:带拒绝循环的审核
Draft ←──[Reject]── Pending Review ──[Approve]──→ Approved
└──[Submit for Review]──→ Pending Review
被拒绝的文档会返回草稿状态以供修改。创建者重新提交。这是最常见的审批模式。
模式 4:休假审批
Applied (doc_status=0, allow_edit=Employee)
└─[Approve / Leave Approver]─→ Approved (doc_status=1)
└─[Reject / Leave Approver]─→ Rejected (doc_status=0)
Approved
└─[Cancel / HR Manager]─→ Cancelled (doc_status=2)
模式 5:文档审核(不可提交)
对于不可提交的 DocType,所有状态的 doc_status = 0:
Draft → Under Review → Reviewed → Published
(all doc_status = 0)
从手动 DocStatus 迁移到工作流
如果你的 DocType 目前使用手动提交/取消按钮,并且想添加工作流:
- 映射现有文档 — 创建工作流时,工作流引擎会根据现有文档的
docstatus自动将其映射到状态 - 为每个 docstatus 定义一个状态 — 对于文档当前使用的每个
docstatus值,始终至少定义一个状态 - 使用现有数据进行测试 — 确认现有已提交文档显示正确的工作流状态
- 更新列表视图 — 如果使用
override_status,工作流状态将替代 Status 列
切勿在没有 docstatus=0 对应状态的情况下启用工作流。新文档将没有有效的初始状态。
决策树
Starting a new workflow implementation?
│
├── What type of DocType?
│ ├── Submittable → can use doc_status 0, 1, 2
│ └── Non-submittable → ALL states must be doc_status = 0
│
├── How many approval levels?
│ ├── Single → Two-state: Draft → Approved
│ ├── Sequential → Chain: Draft → L1 → L2 → Approved
│ └── Conditional → Route by field values using conditions
│
├── Need self-approval blocking?
│ └── Set allow_self_approval = 0 on approval transitions
│
├── Need rejection/revision loop?
│ └── Add Reject transition back to Draft or previous state
│
├── Need email notifications?
│ ├── Enable send_email_alert on Workflow
│ └── Link Email Template on each state
│
└── Need automated field updates?
└── Use update_field + update_value on target state
故障排除
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 看不到操作按钮 | 用户缺少所需角色 | 为用户添加角色,或为用户的角色添加转换 |
| “不允许自行审批” | 用户是文档所有者,且 allow_self_approval=0 | 由其他用户审批,或将标志设为 1 |
| “未设置工作流状态” | 文档在启用工作流前创建 | 运行 update_default_workflow_status 或手动设置状态 |
| 文档卡在某个状态 | 当前状态和用户角色没有对应的后续转换 | 添加缺少的转换 |
| “提交前无法取消” | 转换从 doc_status=0 指向 doc_status=2 | 添加中间的已提交状态 |
| 操作显示给了错误的用户 | 角色分配范围太广 | 使用更具体的角色,或添加条件 |