frappe-core-workflow について
Frappe 開発者向けのワークフローエンジン解説です。状態、遷移、ロール権限によるドキュメントライフサイクルの管理を説明し、条件判定、承認、ドキュメントステータスの規則も扱います。
主な機能
- 01状態とロールによる遷移制御
- 02条件によるアクションの絞り込み
- 03状態更新とメール通知の設定
- 04承認と自己承認ルールの管理
- 05ドキュメントステータス遷移の制約説明
- 06一般的なワークフローエラーの特定
活用シーン
- 01DocType の承認プロセス設定
- 02ロールによるドキュメント操作の制限
- 03ドキュメント項目に基づく条件付き遷移
- 04状態または権限エラーの調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ impertio-studio/ frappe_claude_skill_package --skill frappe-core-workflowインストール後、Claude Code で/frappe-core-workflowを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/.gitkeepanti-patterns.mdapi-reference.mdexamples.md詳細
ワークフローエンジン
Frappe ワークフローエンジンは、設定可能な状態、遷移、ロールベースの権限を通じてドキュメントのライフサイクルを制御するステートマシンです。ドキュメントのステータスがいつ、どのように変更されるか、誰がアクションを実行できるか、各遷移でどのような副作用が発生するかを管理します。
クイックリファレンス
Workflow DocType → Defines the state machine for a specific DocType
├── states (child table) → Workflow Document State rows
│ ├── state → Link to Workflow State
│ ├── doc_status → 0 (Draft), 1 (Submitted), 2 (Cancelled)
│ ├── allow_edit → Role that can edit in this state
│ ├── update_field → Field to update when entering state
│ ├── update_value → Value to set (literal or expression)
│ └── next_action_email_template → Email Template link
└── transitions (child table) → Workflow Transition rows
├── state → Source state (Link to Workflow State)
├── action → Link to Workflow Action Master
├── next_state → Target state (Link to Workflow State)
├── allowed → Role that can perform this action
├── allow_self_approval → Check (default: 1)
├── condition → Python expression (optional)
└── transition_tasks → Link to Workflow Transition Tasks
Workflow DocType の主なフィールド
| フィールド | 型 | 用途 |
|---|---|---|
workflow_name | Data | 一意の識別子 |
document_type | Link → DocType | 対象の DocType |
is_active | Check | DocType ごとに有効にできるワークフローは 1 つのみです |
workflow_state_field | Data | デフォルト:workflow_state |
override_status | Check | ワークフローによるリストビューのステータスの上書きを防止します |
send_email_alert | Check | 次に実行可能なアクションを含むメール通知 |
エンジンの仕組み
1. 有効化とフィールドの作成
is_active = 1 で Workflow を保存すると、次の処理が行われます。
- 同じ DocType の他のすべてのワークフローが自動的に無効化されます
- 対象の DocType に非表示の Custom Field(
workflow_state_field、デフォルトはworkflow_state)が存在しない場合、作成されます - フィールドの型は
Workflow StateへのLinkで、hidden=1、allow_on_submit=1、no_copy=1が設定されます - ワークフロー状態が空の既存ドキュメントは、現在の
docstatusに基づいて状態が設定されます
2. 状態の解決
ワークフロー対象のすべてのドキュメントには、workflow_state フィールドがあります。エンジンは次の手順で利用可能な遷移を解決します。
- ドキュメントから現在の
workflow_stateを読み取ります transition.state == current_stateに該当するworkflow.transitionsを絞り込みます- ユーザーのロールで絞り込みます:
transition.allowed in frappe.get_roles() - 設定されている場合は
transition.conditionをfrappe.safe_eval()で評価します - 条件に一致した遷移を利用可能なアクションとして返します
3. 遷移の適用
apply_workflow(doc, action) が呼び出されると、次の処理が行われます。
- DB からドキュメントを読み込みます(最新の状態を取得)
- 現在のユーザーが利用できる遷移を取得します
- 要求された
actionに一致する遷移を見つけます - 自己承認を確認します:
allow_self_approval=0かつユーザーがドキュメントの所有者の場合はブロックされます workflow_state_fieldにtransition.next_stateを設定します- 対象の状態に
update_fieldが設定されている場合、そのフィールドを更新します - 遷移タスクを実行します(同期処理を先に実行し、その後
frappe.enqueueで非同期処理を実行) - 遷移元と遷移先の状態の
doc_status値に基づいて、docstatus の変更を処理します - それに応じてドキュメントを保存、送信、またはキャンセルします
- ワークフローコメントを追加します
ワークフローと DocStatus の連携
重要:docstatus の遷移はワークフローエンジンが制御します。ワークフローで制御されているドキュメントに対して、doc.submit() や doc.cancel() を直接呼び出してはいけません。これらの処理はワークフローが行います。
DocStatus 遷移ルール
| 遷移元の doc_status | 遷移先の doc_status | エンジンのアクション | 有効? |
|---|---|---|---|
| 0(下書き) | 0(下書き) | doc.save() | はい |
| 0(下書き) | 1(送信済み) | doc.submit() | はい |
| 1(送信済み) | 1(送信済み) | doc.save() | はい |
| 1(送信済み) | 2(キャンセル済み) | doc.cancel() | はい |
| 2(キャンセル済み) | 任意 | ブロック | いいえ |
| 1(送信済み) | 0(下書き) | ブロック | いいえ |
| 0(下書き) | 2(キャンセル済み) | ブロック | いいえ |
docstatus が常に前方向にのみ進むよう、状態を定義してください:0→0、0→1、1→1、1→2。 キャンセル済みの状態からの遷移や、送信済みから下書きに戻る遷移は作成しないでください。
送信不可の DocType
対象の DocType が送信不可の場合、すべての状態で doc_status = 0 にする必要があります。エンジンはこれを検証し、送信不可の DocType に doc_status = 1 または 2 の状態があるとエラーを発生させます。
ワークフロー状態
Workflow State は、マスターリストとして使用される独立した DocType です。各状態には次の項目があります。
| フィールド | 用途 |
|---|---|
state | 状態の表示名 |
style | バッジ表示用の CSS クラス(Primary、Success、Warning、Danger、Info、Inverse) |
icon | Font Awesome のアイコンクラス |
状態行のフィールド(ワークフロードキュメントの状態)
| フィールド | 目的 |
|---|---|
state | ワークフロー状態へのリンク |
doc_status | 選択:0、1、または2 |
allow_edit | ロールへのリンク — この状態でドキュメントを編集できるのはこのロールのみです |
update_field | ドキュメントがこの状態に入るときに更新するフィールド |
update_value | 設定する値(文字列、または evaluate_as_expression=1 の場合は Python 式) |
is_optional_state | チェック — オプションの状態は get_next_possible_transitions でスキップされます |
send_email | チェック(デフォルトは1)— この状態に入ったときにメール通知を送信します |
next_action_email_template | メールテンプレートへのリンク |
message | メール通知のテキストメッセージ |
ワークフロー遷移
各遷移行は、可能なアクションを1つ定義します。
| フィールド | 目的 |
|---|---|
state | 遷移元の状態(状態テーブルに存在する必要があります) |
action | ワークフローアクションマスターへのリンク(例:「承認」、「却下」、「レビュー」) |
next_state | 遷移先の状態(状態テーブルに存在する必要があります) |
allowed | ロールへのリンク — このアクションが表示されるのは、このロールを持つユーザーのみです |
allow_self_approval | チェック(デフォルトは1)— 0の場合、ドキュメントの所有者はこのアクションを実行できません |
condition | frappe.safe_eval() で評価される Python 式 |
transition_tasks | ワークフロー遷移タスクへのリンク(v15以降) |
条件式
条件は、サンドボックス環境で評価される Python 式です。利用可能なグローバル変数:
# Available in condition expressions:
frappe.db.get_value(doctype, name, fieldname)
frappe.db.get_list(doctype, filters, fields)
frappe.session.user
frappe.session.roles # NOT available — use frappe.get_roles() outside conditions
frappe.utils.now_datetime()
frappe.utils.add_to_date(date, **kwargs)
frappe.utils.get_datetime(datetime_str)
frappe.utils.now()
doc.fieldname # Access any field on the document (as dict)
条件の例:
doc.grand_total > 50000
doc.department == "HR"
doc.grand_total > 50000 and doc.department != "Finance"
ワークフローアクション
ワークフローアクションマスター
workflow_action_name フィールドのみを持つシンプルな DocType です。一般的なアクションは、承認、却下、レビュー、差し戻し、キャンセルです。遷移を定義する前に、これらを作成してください。
ワークフローアクション DocType
ユーザーの保留中のアクションを追跡します。ドキュメントが、遷移先が設定された状態に入ると自動的に作成されます。
| フィールド | 目的 |
|---|---|
status | オープンまたは完了 |
reference_doctype | ドキュメントの DocType |
reference_name | ドキュメント名 |
workflow_state | 現在のワークフロー状態 |
user | 割り当てられたユーザー |
permitted_roles | 操作可能なロールのテーブル複数選択 |
completed_by | アクションを完了したユーザー |
completed_by_role | 完了に使用したロール |
ワークフローアクションはユーザーの「ワークフローアクション」リストに表示され、メール内のリンクから実行できます。
自己承認の制御
def has_approval_access(user, doc, transition):
return (user == "Administrator"
or transition.get("allow_self_approval")
or user != doc.get("owner"))
- Administrator は設定にかかわらず、常に承認権限を持ちます
allow_self_approval = 1(デフォルト)の場合:ドキュメントの所有者は承認できますallow_self_approval = 0の場合:ドキュメントの所有者は自分のドキュメントを承認できません
判断ツリー
Need workflow on a DocType?
├── Is DocType submittable?
│ ├── YES → States can use doc_status 0, 1, 2
│ └── NO → ALL states MUST have doc_status = 0
├── Define states → Create Workflow State records first
├── Define transitions → Need Workflow Action Master records first
├── Who can edit in each state? → Set allow_edit per state
├── Need conditional transitions?
│ └── Use Python expressions with doc.field access
├── Need to block self-approval?
│ └── Set allow_self_approval = 0 on specific transitions
└── Need email notifications?
└── Set send_email_alert on Workflow + email templates on states
よくあるエラー
| エラー | 原因 | 対処方法 |
|---|---|---|
WorkflowStateError | ドキュメントに workflow_state が設定されていません | 作成時にワークフローで初期状態が設定されることを確認してください |
WorkflowTransitionError | 現在の状態またはロールでは無効なアクションです | 遷移テーブルに必要な経路がすべて含まれていることを確認してください |
WorkflowPermissionError | ユーザーに遷移に必要なロールがない、または自己承認が禁止されています | allowed ロールと allow_self_approval を確認してください |
| "Illegal Document Status" | 無効な docstatus の遷移です(例:0→2) | 状態の doc_status 値を修正してください |
| "Cannot cancel before submitting" | 下書き(0)からキャンセル(2)への遷移です | 中間の送信済み(1)状態を追加してください |
関連項目
- API リファレンス — ワークフローの Python API 全般
- 例 — ワークフロー設定の例
- アンチパターン — よくある間違いとその回避方法
frappe-impl-workflow— 実装手順ガイド