Merge pull request #9773 from surajshetty3416/fix-workflow-action-eval

refactor: Commonify transition condition evaluation
This commit is contained in:
Suraj Shetty 2020-03-31 14:24:05 +05:30 committed by GitHub
commit 391f3da184
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 15 deletions

View file

@ -45,20 +45,29 @@ def get_transitions(doc, workflow = None, raise_exception=False):
transitions = []
for transition in workflow.transitions:
if transition.state == current_state and transition.allowed in roles:
if transition.condition:
# if condition, evaluate
# access to frappe.db.get_value and frappe.db.get_list
success = frappe.safe_eval(transition.condition,
dict(frappe = frappe._dict(
db = frappe._dict(get_value = frappe.db.get_value, get_list=frappe.db.get_list),
session = frappe.session
)),
dict(doc = doc))
if not success:
continue
if not is_transition_condition_satisfied(transition, doc):
continue
transitions.append(transition.as_dict())
return transitions
def get_workflow_safe_globals():
# access to frappe.db.get_value and frappe.db.get_list
return dict(
frappe=frappe._dict(
db=frappe._dict(
get_value=frappe.db.get_value,
get_list=frappe.db.get_list
),
session=frappe.session
)
)
def is_transition_condition_satisfied(transition, doc):
if not transition.condition:
return True
else:
return frappe.safe_eval(transition.condition, get_workflow_safe_globals(), dict(doc=doc.as_dict()))
@frappe.whitelist()
def apply_workflow(doc, action):
'''Allow workflow action on the current doc'''

View file

@ -9,8 +9,8 @@ from frappe.utils import get_url, get_datetime
from frappe.desk.form.utils import get_pdf_link
from frappe.utils.verified_command import get_signed_params, verify_request
from frappe import _
from frappe.model.workflow import apply_workflow, get_workflow_name, \
has_approval_access, get_workflow_state_field, send_email_alert, get_workflow_field_value
from frappe.model.workflow import apply_workflow, get_workflow_name, has_approval_access, \
get_workflow_state_field, send_email_alert, get_workflow_field_value, is_transition_condition_satisfied
from frappe.desk.notifications import clear_doctype_notifications
from frappe.utils.user import get_users_with_role
@ -155,10 +155,10 @@ def get_next_possible_transitions(workflow_name, state, doc=None):
for transition in transitions:
is_next_state_optional = get_state_optional_field_value(workflow_name, transition.next_state)
# skip transition if next state of the transition is optional
if transition.condition and not frappe.safe_eval(transition.condition, None, {'doc': doc.as_dict()}):
continue
if is_next_state_optional:
continue
if not is_transition_condition_satisfied(transition, doc):
continue
transitions_to_return.append(transition)
return transitions_to_return