Note: This feature is available v16 onwards.
Custom Permission Types let you create permission flags beyond the built-in ones read, write, create, delete, submit). Use them for action-specific permissions like "approve record", "download file", or "impersonate user".
How it works
There are three steps:
- Developer creates the permission type in dev mode for a DocType
- Developer adds permission checks in code where the action happens
- System Manager assigns the permission to roles in the Desk UI
The permission type is saved as a fixture and shipped with your app.
Example: Creating an "approve" permission on Invoice
Step 1: Create the permission type (Developer)
- Enable developer mode and log in as Administrator
- Create a new Permission Type record
- Set Perm Type as
approveand DocType asInvoice - Save
The permission type is now created and will be exported with your app.
Step 2: Add permission checks in your code (Developer)
In your Invoice controller or in functions that handle approvals, check for the permission:
@frappe.whitelist()
def approve_invoice(invoice_name):
invoice = frappe.get_doc("Invoice", invoice_name)
if not frappe.has_permission(invoice, "approve"):
frappe.throw("Not permitted to approve", frappe.PermissionError)
invoice.approval_status = "Approved"
invoice.save()
You can also check without throwing an error:
if frappe.has_permission(invoice, "approve"):
# show approve button on frontend
Step 3: Assign to roles (System Manager)
After your app is installed, system managers assign the permission to roles:
- Open Role Permission Manager
- Select the Invoice DocType
- For each role, check or uncheck the "Approve" column, just like other permissions
- The permission is now applied to all users with that role
That's it. Users with the "approve" permission can now perform the action. Users without it will see an error.
How to check the permission
Use frappe.has_permission() in your Python code:
# Check document-level permission
if frappe.has_permission(invoice_doc, "approve"):
# User can approve this invoice
# Check DocType-level permission
if frappe.has_permission("Invoice", "approve"):
# User can approve any invoice