mcpField
F
frappe-impl-workflow

frappe-impl-workflow

github.com/impertio-studio开发198111 次安装30 周前更新
代码仓库

关于 frappe-impl-workflow

为 Frappe 开发者提供的文档工作流实施指南,覆盖设计、配置、测试和常见审批模式。内容也说明状态、角色、条件及文档状态之间的配置关系。

主要功能

  1. 01工作流状态与转换设计
  2. 02按角色配置审批权限
  3. 03设置条件转换与自审批限制
  4. 04配置通知及状态字段更新
  5. 05手动与程序化测试

适用场景

  1. 01为采购订单设置多级审批
  2. 02按金额将文档路由至不同审批人
  3. 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/
.gitkeep
anti-patterns.md
decision-tree.md
examples.md
workflows.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:

  1. 设置 Workflow Name(例如,“采购订单审批”)
  2. 设置 Document Type(例如,“Purchase Order”)
  3. 勾选 Is Active
  4. 在 States 表格中添加状态
  5. 在 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。这意味着:

  • 文档所有者(创建者)不能执行此操作
  • 管理员始终不受此限制
  • 具有所需角色的其他用户可以执行此操作
电子邮件通知
  1. 在工作流上设置 send_email_alert = 1
  2. 在每个状态行中设置 send_email = 1(默认值)
  3. 可选:通过 next_action_email_template 关联 Email Template
  4. 在状态行中添加自定义 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 步:测试工作流

手动测试检查清单
  1. 创建测试文档 — 确认其初始状态为第一个状态(草稿)
  2. 检查可用操作 — 只有具有从草稿状态出发的转换权限的角色才会看到按钮
  3. 执行每个转换 — 确认状态正确变更
  4. 测试拒绝路径 — 确认文档返回到正确状态
  5. 测试自我审批 — 以文档所有者身份登录,确认转换被阻止
  6. 测试条件 — 创建符合/不符合条件的文档,确认按钮的显示情况
  7. 测试电子邮件通知 — 确认状态变更时已发送电子邮件
  8. 使用不可提交的 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 目前使用手动提交/取消按钮,并且想添加工作流:

  1. 映射现有文档 — 创建工作流时,工作流引擎会根据现有文档的 docstatus 自动将其映射到状态
  2. 为每个 docstatus 定义一个状态 — 对于文档当前使用的每个 docstatus 值,始终至少定义一个状态
  3. 使用现有数据进行测试 — 确认现有已提交文档显示正确的工作流状态
  4. 更新列表视图 — 如果使用 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添加中间的已提交状态
操作显示给了错误的用户角色分配范围太广使用更具体的角色,或添加条件

另请参阅

  • 工作流模式 — 详细的分步工作流示例
  • 决策树 — 扩展版工作流设计决策树
  • 示例 — 常见场景的代码示例
  • 反模式 — 应避免的错误
  • frappe-core-workflow — 工作流引擎内部机制和 API 参考

评论

支持 Markdown