diff --git a/frappe/core/doctype/version/version.py b/frappe/core/doctype/version/version.py index 99eeb8c2b0..6571400f81 100644 --- a/frappe/core/doctype/version/version.py +++ b/frappe/core/doctype/version/version.py @@ -80,24 +80,30 @@ def get_diff(old, new, for_child=False): updater_reference=updater_reference, ) + if not for_child: + amended_from = new.get("amended_from") + old_row_name_field = "_amended_from" if (amended_from and amended_from == old.name) else "name" + for df in new.meta.fields: if df.fieldtype in no_value_fields and df.fieldtype not in table_fields: continue old_value, new_value = old.get(df.fieldname), new.get(df.fieldname) - if df.fieldtype in table_fields: - # make maps - old_row_by_name, new_row_by_name = {}, {} + if not for_child and df.fieldtype in table_fields: + old_rows_by_name = {} for d in old_value: - old_row_by_name[d.name] = d - for d in new_value: - new_row_by_name[d.name] = d + old_rows_by_name[d.name] = d + + found_rows = set() # check rows for additions, changes for i, d in enumerate(new_value): - if d.name in old_row_by_name: - diff = get_diff(old_row_by_name[d.name], d, for_child=True) + old_row_name = getattr(d, old_row_name_field, None) + if old_row_name and old_row_name in old_rows_by_name: + found_rows.add(old_row_name) + + diff = get_diff(old_rows_by_name[old_row_name], d, for_child=True) if diff and diff.changed: out.row_changed.append((df.fieldname, i, d.name, diff.changed)) else: @@ -105,7 +111,7 @@ def get_diff(old, new, for_child=False): # check for deletions for d in old_value: - if not d.name in new_row_by_name: + if d.name not in found_rows: out.removed.append([df.fieldname, d.as_dict()]) elif old_value != new_value: diff --git a/frappe/model/document.py b/frappe/model/document.py index 0968dea0f0..d503bdc176 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -1236,9 +1236,12 @@ class Document(BaseDocument): ): return - version = frappe.new_doc("Version") + doc_to_compare = self._doc_before_save + if not doc_to_compare and (amended_from := self.get("amended_from")): + doc_to_compare = frappe.get_doc(self.doctype, amended_from) - if is_useful_diff := version.update_version_info(self._doc_before_save, self): + version = frappe.new_doc("Version") + if is_useful_diff := version.update_version_info(doc_to_compare, self): version.insert(ignore_permissions=True) if not frappe.flags.in_migrate: diff --git a/frappe/public/js/frappe/model/create_new.js b/frappe/public/js/frappe/model/create_new.js index 5deccaeb9b..4d1b293c78 100644 --- a/frappe/public/js/frappe/model/create_new.js +++ b/frappe/public/js/frappe/model/create_new.js @@ -309,6 +309,10 @@ $.extend(frappe.model, { newdoc.lft = null; newdoc.rgt = null; + if (from_amend && parent_doc) { + newdoc._amended_from = doc.name; + } + return newdoc; },