From 00a5fde3ade6c458a669d3275835209d7aac389b Mon Sep 17 00:00:00 2001 From: P-Froggy <60393001+P-Froggy@users.noreply.github.com> Date: Fri, 11 Jul 2025 14:33:00 +0200 Subject: [PATCH] feat: Enable _doc_before_save for child documents (#33279) * Initial Commit * Apply suggestion from @ankush * refactor: move unrelated code out of try-except block * test: child table level value change detection --------- Co-authored-by: Ankush Menat Co-authored-by: Ankush Menat --- frappe/model/document.py | 8 +++++++- frappe/tests/test_document.py | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/frappe/model/document.py b/frappe/model/document.py index 732d4c81e0..3c2d601d1d 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -1303,7 +1303,13 @@ class Document(BaseDocument): if raise_exception: raise - frappe.clear_last_message() + return frappe.clear_last_message() + + for fieldname in self._table_fieldnames: + for row in self.get(fieldname): + row._doc_before_save = next( + (d for d in (self._doc_before_save.get(fieldname) or []) if d.name == row.name), None + ) def run_post_save_methods(self): """Run standard methods after `INSERT` or `UPDATE`. Standard Methods are: diff --git a/frappe/tests/test_document.py b/frappe/tests/test_document.py index bf88ea0a7c..c52a5e15af 100644 --- a/frappe/tests/test_document.py +++ b/frappe/tests/test_document.py @@ -143,6 +143,16 @@ class TestDocument(IntegrationTestCase): self.assertFalse(d.has_value_changed("creation")) self.assertFalse(d.has_value_changed("event_type")) + user = frappe.get_doc("User", "Administrator") + user.load_doc_before_save() + role1 = user.roles[0] + role2 = user.roles[1] + + role1.role = "New Role" + + self.assertTrue(role1.has_value_changed("role")) + self.assertFalse(role2.has_value_changed("role")) + def test_mandatory(self): # TODO: recheck if it is OK to force delete frappe.delete_doc_if_exists("User", "test_mandatory@example.com", 1)