Approval Policy
Approval Policy is the central configuration DocType that defines when, how, and by whom approval workflows are triggered. Each policy specifies the conditions under which approvals are required and the behavior of the resulting approval process.
Overview
Approval Policies act as templates that automatically create System Approvals when specific conditions are met. They provide complete control over:
- Triggering conditions - Which DocType events should initiate approvals
- Filter criteria - Business conditions that must be satisfied
- Approval requirements - Who must approve and in what manner
- Lock behavior - Whether documents should be locked during approval
- Post-decision effects - Actions to take after approval completion
- SLA management - Timing, reminders, and escalation rules
Field Reference
Basic Configuration
| Field | Type | Required | Description |
|---|---|---|---|
| Policy Name | Data | Yes | Unique identifier for this approval policy |
| Reference DocType | Link → DocType | Yes | Target DocType this policy applies to |
| DocType Event | Select | Yes | Document event that triggers this policy |
| Application | Link → My Application | Yes | Application scope for this policy |
| Active | Check | No | Enable/disable this policy (default: unchecked) |
DocType Event Options
- After Insert - Triggers when new documents are created
- After Save - Triggers when documents are saved (new or existing)
- After Submit - Triggers when documents are submitted
- After Cancel - Triggers when submitted documents are cancelled
- After Delete - Triggers when documents are deleted
- After Save (Submitted Document) - Triggers when submitted documents are modified
Filter Conditions
| Field | Type | Required | Description |
|---|---|---|---|
| Filter List | HTML | No | Interactive filter builder interface |
| Filter Conditions | Text | No | JSON representation of filter conditions (hidden) |
The filter system uses the same interface as Business Rules, allowing complex conditional logic based on document field values.
⚠️ Critical for Preventing Circular Loops: Filter conditions must be carefully designed to avoid re-triggering approvals when post-decision effects modify the document.
Approval Configuration
| Field | Type | Required | Description |
|---|---|---|---|
| Lock Behavior | Select | Yes | Document lock strategy during approval |
| Approval Mode | Select | Yes | Determines how many approvals are required |
| Approval Count | Int | Conditional | Number of approvals needed (when mode is Count(n)) |
| Approval Source | Select | Yes | Source of approver assignments |
| Approval Users | Table MultiSelect | Conditional | Specific users who can approve |
| Approval Groups | Link → User Group | Conditional | User groups containing potential approvers |
Lock Behavior Options
- Hard Lock - Document cannot be modified until approval is complete
- None - Document remains editable during approval process (Note: Only one approval per document allowed regardless of lock behavior)
Approval Mode Options
- All - Every designated approver must approve
- Any One - Only one approval from any designated approver is required
- Count(n) - Specific number of approvals required (set via Approval Count field)
Approval Source Options
- Users - Approvers selected from specific user list
- User Groups - Approvers selected from user group members at runtime
Post-Decision Effects
| Field | Type | Required | Description |
|---|---|---|---|
| On Approve Set Field | Table | No | Fields to update when approval is granted |
| On Approve Call Script | Link → Script Function | No | Script to execute when approval is granted |
| On Reject Set Field | Table | No | Fields to update when approval is rejected |
| On Reject Call Script | Link → Script Function | No | Script to execute when approval is rejected |
Field Setter Configuration
Each field setter row contains: - Field: Target field name in the reference document - Value: Value to set in the target field
⚠️ Critical Warning - Preventing Circular Loops: Field setters can inadvertently trigger the same approval policy again, creating circular loops. Always ensure filter conditions exclude the values you're setting.
SLA and Escalation
| Field | Type | Required | Description |
|---|---|---|---|
| Due In Hours | Int | No | Hours from creation until approval is due |
| Reminder Every Hours | Int | No | Frequency of reminder notifications |
| Escalate After Hours | Int | No | Hours after due date to trigger escalation |
| Escalate To User | Link → User | No | User to receive escalated requests |
| Escalate To Role | Link → Role | No | Role members to receive escalated requests |
Notification Settings
| Field | Type | Required | Description |
|---|---|---|---|
| Send Email Notification | Check | No | Enable email notifications for this policy |
| Send SMS | Check | No | Enable SMS notifications for this policy |
| Send Slack | Check | No | Enable Slack notifications for this policy |
Procedure
Creating an Approval Policy
- Navigate to Policies: Go to Approval Policy list in the Develop workspace
- Create New: Click Add Approval Policy
Basic Setup:
- Enter a descriptive Policy Name
- Select the target Reference DocType
- Choose the triggering DocType Event
- Link to appropriate Application
- Check Active to enable the policy
Configure Conditions (Critical for Loop Prevention):
- Use the Filter List interface to define when the policy should trigger
- Important: Include conditions that exclude documents modified by post-decision effects
- Leave empty to trigger for all documents of the target DocType (not recommended)
Set Approval Requirements:
- Choose Lock Behavior (Hard Lock recommended for critical processes)
- Select Approval Mode based on your requirements
- Set Approval Count if using Count(n) mode
- Choose Approval Source (Users or User Groups)
- Configure specific approvers based on your source selection
Configure Effects (Critical for Loop Prevention):
- Add field setters for On Approve and On Reject scenarios
- Ensure filter conditions exclude the values you're setting
- Link Script Functions for complex post-decision processing
- Script functions must not modify fields that could re-trigger the policy
Set SLA Rules (Optional):
- Define Due In Hours for approval deadlines
- Configure Reminder Every Hours for periodic notifications
- Set escalation rules with Escalate After Hours and targets
Enable Notifications:
- Check desired notification channels (Email, SMS, Slack)
- Ensure proper configuration in system settings for chosen channels
Save and Test: Save the policy and test with sample documents
Policy Validation
The system automatically validates policies during save:
Approval Mode Validation
- Count(n) mode requires a valid Approval Count
- Approval Count cannot exceed the number of available approvers
- Approval Count must be at least 1
Approver Validation
- Users source requires at least one user in Approval Users table
- User Groups source requires at least one group with active members
- Groups are validated to ensure they contain active users
Escalation Validation
- Escalate After Hours requires either Escalate To User or Escalate To Role
- Escalation targets are validated for existence and active status
Loop Prevention Examples with Filter Conditions
# If setting approval_status = "Approved" on approve
approval_status != "Approved"
# If setting workflow_state = "Pending Approval"
workflow_state != "Pending Approval"
# Multiple field considerations
approval_status != "Approved" AND approval_status != "Rejected" AND processed != 1
Critical Best Practices for Loop Prevention
Field Setter Design
- Always Exclude Target Values: If setting
status = "Approved", add conditionstatus != "Approved" - Consider All Modified Fields: Include all fields being set in your exclusion logic
- Use Status/Flag Fields: Create dedicated fields like
approval_processedto prevent re-triggering - Test Thoroughly: Always test post-decision effects to ensure they don't create loops
Script Function Design
- Check Processing Flags: Use flags to prevent duplicate processing
- Avoid Triggering Events: Be careful when calling
doc.save()from scripts - Use Conditional Logic: Check approval status before making changes
- Document Modifications: Clearly document what fields your scripts modify
Example Safe Patterns
Safe Field Setter Configuration
Policy: Sales Order approval when amount > 10000
Filter: amount > 10000 AND approval_status != "Approved" AND approval_status != "Rejected"
On Approve Set Field: approval_status = "Approved"
On Reject Set Field: approval_status = "Rejected"
Safe Script Function Pattern
# Script Function: process_approval_completion
if not doc.get('approval_processed') and approval.status in ['Approved', 'Rejected']:
# Safe to process since we check the flag
doc.approval_processed = 1
if approval.status == 'Approved':
doc.state = 'Approved'
doc.approved_by = approval.completed_on
else:
doc.state = 'Rejected'
doc.rejection_reason = 'Failed approval process'
doc.save()
Single Approval Per Document
Important Restriction: The system enforces one active approval per document at a time, regardless of lock behavior:
Hard Lock Policies
- If a hard lock approval exists, no additional approvals will be created
- This prevents conflicting lock states and user confusion
Advisory (None) Policies
- Even non-blocking policies are limited to one approval per document
- This prevents duplicate notification spam and workflow confusion
- Multiple policies may match, but only the first to execute will create an approval
Policy Priority
- Policies are evaluated in the order they are processed
- The first matching policy creates the approval
- Subsequent matching policies are ignored until the approval is resolved
- Consider policy design carefully to ensure the most important policy triggers first
Best Practices
Policy Design
- Specific Targeting: Create focused policies for specific business scenarios
- Clear Naming: Use descriptive policy names that indicate purpose and scope
- Incremental Rollout: Start with non-critical processes and expand gradually
- Loop Prevention: Always design filters and effects to prevent circular triggering
Approval Configuration
- Hard Lock for Critical: Use Hard Lock for processes requiring strict control
- Balanced Approval Modes: Choose modes that balance security with efficiency
- Group-based Flexibility: Use User Groups for easier approver management
Performance Considerations
- Targeted Conditions: Use filter conditions to limit policy execution
- Efficient Escalation: Set reasonable escalation timeframes
- Notification Optimization: Enable only necessary notification channels
Change Management
- User Training: Ensure approvers understand their responsibilities
- Testing Protocol: Test policy changes in development environments
- Loop Testing: Specifically test post-decision effects to prevent infinite loops
Integration with Other Components
System Approval Creation
When a policy matches document conditions, it automatically creates:
- One System Approval record for overall tracking
- Multiple Approval Request records for individual approvers
Script Function Integration
Post-decision scripts receive context including:
doc: The original document that triggered approvalapproval: The System Approval recordrequests: List of all Approval Request records
Update Set Tracking
All policy changes are tracked through the Update Set system, enabling:
- Change history and audit trails
- Cross-environment deployment of approval configurations