mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-11 08:53:03 +00:00
fix: update items respects workflow "Only Allow Edit For" role (#55667)
This commit is contained in:
@@ -8,7 +8,7 @@ from collections import defaultdict
|
||||
import frappe
|
||||
from frappe import _, bold, qb, throw
|
||||
from frappe.contacts.doctype.address.address import get_address_display
|
||||
from frappe.model.workflow import get_workflow_name, is_transition_condition_satisfied
|
||||
from frappe.model.workflow import get_workflow_name
|
||||
from frappe.query_builder import Criterion, DocType
|
||||
from frappe.query_builder.custom import ConstantColumn
|
||||
from frappe.query_builder.functions import Abs, Sum
|
||||
@@ -3853,7 +3853,9 @@ def validate_and_delete_children(parent, data, ordered_item=None) -> bool:
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
|
||||
def update_child_qty_rate(
|
||||
parent_doctype: str, trans_items: str, parent_doctype_name: str, child_docname: str = "items"
|
||||
):
|
||||
from erpnext.buying.doctype.supplier_quotation.supplier_quotation import get_purchased_items
|
||||
from erpnext.selling.doctype.quotation.quotation import get_ordered_items
|
||||
|
||||
@@ -3879,14 +3881,12 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
current_state = doc.get(workflow_doc.workflow_state_field)
|
||||
roles = frappe.get_roles()
|
||||
|
||||
transitions = []
|
||||
for transition in workflow_doc.transitions:
|
||||
if transition.next_state == current_state and transition.allowed in roles:
|
||||
if not is_transition_condition_satisfied(transition, doc):
|
||||
continue
|
||||
transitions.append(transition.as_dict())
|
||||
allowed = any(
|
||||
state.state == current_state and (not state.allow_edit or state.allow_edit in roles)
|
||||
for state in workflow_doc.states
|
||||
)
|
||||
|
||||
if not transitions:
|
||||
if not allowed:
|
||||
frappe.throw(
|
||||
_("You are not allowed to update as per the conditions set in {} Workflow.").format(
|
||||
get_link_to_form("Workflow", workflow)
|
||||
|
||||
@@ -721,6 +721,40 @@ class TestSalesOrder(ERPNextTestSuite):
|
||||
workflow.is_active = 0
|
||||
workflow.save()
|
||||
|
||||
def test_update_child_qty_rate_follows_allow_edit(self):
|
||||
from frappe.model.workflow import apply_workflow
|
||||
|
||||
workflow = make_sales_order_edit_perm_workflow()
|
||||
so = make_sales_order(item_code="_Test Item", qty=1, rate=150, do_not_submit=1)
|
||||
apply_workflow(so, "Approve")
|
||||
|
||||
trans_item = json.dumps(
|
||||
[{"item_code": "_Test Item", "rate": 150, "qty": 2, "docname": so.items[0].name}]
|
||||
)
|
||||
|
||||
mover = "test@example.com"
|
||||
mover_user = frappe.get_doc("User", mover)
|
||||
mover_user.add_roles("Sales User", "Test Junior Approver")
|
||||
with self.set_user(mover):
|
||||
# transitioned the doc into Approved but is not the configured editor
|
||||
self.assertRaises(
|
||||
frappe.ValidationError, update_child_qty_rate, "Sales Order", trans_item, so.name
|
||||
)
|
||||
|
||||
editor = "test2@example.com"
|
||||
editor_user = frappe.get_doc("User", editor)
|
||||
editor_user.add_roles("Sales User", "Test Approver")
|
||||
with self.set_user(editor):
|
||||
# Test Approver is the "Only Allow Edit For" role on Approved
|
||||
update_child_qty_rate("Sales Order", trans_item, so.name)
|
||||
so.reload()
|
||||
self.assertEqual(so.items[0].qty, 2)
|
||||
|
||||
mover_user.remove_roles("Sales User", "Test Junior Approver", "Test Approver")
|
||||
editor_user.remove_roles("Sales User", "Test Junior Approver", "Test Approver")
|
||||
workflow.is_active = 0
|
||||
workflow.save()
|
||||
|
||||
def test_material_request_for_product_bundle(self):
|
||||
# Create the Material Request from the sales order for the Packing Items
|
||||
# Check whether the material request has the correct packing item or not.
|
||||
@@ -2888,3 +2922,41 @@ def make_sales_order_workflow():
|
||||
workflow.insert(ignore_permissions=True)
|
||||
|
||||
return workflow
|
||||
|
||||
|
||||
def make_sales_order_edit_perm_workflow():
|
||||
if frappe.db.exists("Workflow", "SO Edit Perm Workflow"):
|
||||
doc = frappe.get_doc("Workflow", "SO Edit Perm Workflow")
|
||||
doc.set("is_active", 1)
|
||||
doc.save()
|
||||
return doc
|
||||
|
||||
frappe.get_doc(doctype="Role", role_name="Test Junior Approver").insert(ignore_if_duplicate=True)
|
||||
frappe.get_doc(doctype="Role", role_name="Test Approver").insert(ignore_if_duplicate=True)
|
||||
frappe.cache().hdel("roles", frappe.session.user)
|
||||
|
||||
workflow = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Workflow",
|
||||
"workflow_name": "SO Edit Perm Workflow",
|
||||
"document_type": "Sales Order",
|
||||
"workflow_state_field": "workflow_state",
|
||||
"is_active": 1,
|
||||
"send_email_alert": 0,
|
||||
}
|
||||
)
|
||||
workflow.append("states", dict(state="Pending", allow_edit="All"))
|
||||
workflow.append("states", dict(state="Approved", allow_edit="Test Approver", doc_status=1))
|
||||
workflow.append(
|
||||
"transitions",
|
||||
dict(
|
||||
state="Pending",
|
||||
action="Approve",
|
||||
next_state="Approved",
|
||||
allowed="Test Junior Approver",
|
||||
allow_self_approval=1,
|
||||
),
|
||||
)
|
||||
workflow.insert(ignore_permissions=True)
|
||||
|
||||
return workflow
|
||||
|
||||
Reference in New Issue
Block a user