Generate state machine logic for Frappe DocTypes. Use when implementing complex status workflows, state transitions, or document lifecycle management.
View on GitHubVenkateshvenki404224/frappe-apps-manager
frappe-apps-manager
frappe-apps-manager/skills/frappe-state-machine-helper/SKILL.md
January 21, 2026
Select agents to install to:
npx add-skill https://github.com/Venkateshvenki404224/frappe-apps-manager/blob/main/frappe-apps-manager/skills/frappe-state-machine-helper/SKILL.md -a claude-code --skill frappe-state-machine-helperInstallation paths:
.claude/skills/frappe-state-machine-helper/# Frappe State Machine Helper
Generate state machine logic for managing complex document states and transitions in Frappe DocTypes.
## When to Use This Skill
Claude should invoke this skill when:
- User wants to implement document status management
- User needs state transition logic
- User mentions state machine, status workflow, or document lifecycle
- User wants to validate state transitions
- User needs state-dependent behavior
## Capabilities
### 1. State Transition Logic
**Order Status State Machine:**
```python
class SalesOrder(Document):
def validate(self):
self.validate_state_transition()
def validate_state_transition(self):
"""Validate allowed state transitions"""
if not self.is_new():
old_status = frappe.db.get_value('Sales Order', self.name, 'status')
# Define allowed transitions
allowed_transitions = {
'Draft': ['Pending', 'Cancelled'],
'Pending': ['Confirmed', 'Cancelled'],
'Confirmed': ['In Progress', 'Cancelled'],
'In Progress': ['Completed', 'On Hold'],
'On Hold': ['In Progress', 'Cancelled'],
'Completed': [], # Terminal state
'Cancelled': [] # Terminal state
}
if old_status != self.status:
allowed = allowed_transitions.get(old_status, [])
if self.status not in allowed:
frappe.throw(
_(f'Cannot transition from {old_status} to {self.status}')
)
def on_submit(self):
self.status = 'Confirmed'
def on_cancel(self):
self.status = 'Cancelled'
```
### 2. State-Dependent Actions
**Actions Based on State:**
```python
class PaymentEntry(Document):
def validate(self):
if self.status == 'Draft':
self.validate_draft_entry()
elif self.status == 'Submitted':
self.validate_submitted_entry(