How to access and programmatically change docstatus in Frappe

Hi everyone,

I’m working on a Frappe app where I need to have finer control over the workflow and approval process. Specifically, I want to:

  1. Access the docstatus of a document (0 = Draft, 1 = Submitted, 2 = Cancelled) programmatically.

  2. Change the docstatus under certain conditions (e.g., auto-submit or cancel after certain validations).

  3. Possibly trigger additional server-side logic whenever docstatus changes (like updating other fields, sending notifications, or logging).

My current challenges:

  • Frappe prevents direct updates to docstatus because submitted documents (docstatus=1) cannot be modified without unsubmission.

  • I’m trying to automate certain workflow steps without manually clicking buttons, while ensuring data integrity.

  • I’d like to know the best practices for safely updating docstatus and related fields, ideally using server scripts or hooks.

Some specific questions:

  • Can we safely submit/unsubmit a document programmatically in server scripts?

  • How can I update fields or trigger actions after a workflow changes docstatus?

I’d appreciate any guidance, sample patterns, or references for handling docstatus programmatically while keeping workflow integrity intact.

Thanks in advance!

To submit a document programmatically, it’s just doc.submit(). Once a document is submitted, there’s no way to unsubmit it, programmatically or manually. The “correct” approach is to cancel it and create a new document. You can also change fields manually with set_value calls, but this can lead to data integrity problems. The system assumes that a document will generally be immutable once it has been submitted.

Instead of this, Define Workflow States such as Saved, Submitted, Rejected, etc as docstatus= 0, then, in your client script, you can use the workflow_state field to control whether the form should be editable.
frappe.ui.form.on(‘Your Doctype Name’, {
refresh(frm) {
// Disable form if not in ‘Saved’ state
if (frm.doc.workflow_state !== “Saved”) {
frm.disable_form();
} else {
frm.enable_form();
}
}
});

That’s working bro thanks @tousiff

1 Like