From 0ef8001102d75bd2ae09e53e448efc44d6ad6912 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 30 Nov 2024 14:58:15 +0530 Subject: [PATCH 1/7] fix: allow renaming autoincrement documents --- frappe/core/doctype/doctype/doctype.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index 27e0ab8209..ba546dc037 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -193,7 +193,6 @@ class DocType(Document): self.validate_name() self.set_defaults_for_single_and_table() - self.set_defaults_for_autoincremented() self.scrub_field_names() self.set_default_in_list_view() self.set_default_translatable() @@ -279,10 +278,6 @@ class DocType(Document): self.allow_import = 0 self.permissions = [] - def set_defaults_for_autoincremented(self): - if self.autoname and self.autoname == "autoincrement": - self.allow_rename = 0 - def set_default_in_list_view(self): """Set default in-list-view for first 4 mandatory fields""" not_allowed_in_list_view = get_fields_not_allowed_in_list_view(self.meta) From e76c33cdbcc6a896f4e35287884bf64f995c00df Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 30 Nov 2024 14:59:59 +0530 Subject: [PATCH 2/7] fix: cast values for renaming autoincrement documents - cast `name` values to integer - cast `link_field` values to string --- frappe/model/rename_doc.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index 5579c2c108..d69fb81a6b 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -11,7 +11,7 @@ from frappe.model.dynamic_links import get_dynamic_link_map from frappe.model.naming import validate_name from frappe.model.utils.user_settings import sync_user_settings, update_user_settings_data from frappe.query_builder import Field -from frappe.utils.data import sbool +from frappe.utils.data import sbool, cint, cstr from frappe.utils.password import rename_password from frappe.utils.scheduler import is_scheduler_inactive @@ -118,8 +118,8 @@ def update_document_title( def rename_doc( doctype: str | None = None, - old: str | None = None, - new: str | None = None, + old: str | int | None = None, + new: str | int | None = None, force: bool = False, merge: bool = False, ignore_permissions: bool = False, @@ -157,6 +157,10 @@ def rename_doc( merge = sbool(merge) meta = frappe.get_meta(doctype) + if meta.naming_rule == 'Autoincrement': + old = cint(old) + new = cint(new) + if validate: old_doc = doc or frappe.get_doc(doctype, old) out = old_doc.run_method("before_rename", old, new, merge) or {} @@ -350,8 +354,8 @@ def update_autoname_field(doctype: str, new: str, meta: "Meta") -> None: def validate_rename( doctype: str, - old: str, - new: str, + old: str | int, + new: str | int, meta: "Meta", merge: bool, force: bool = False, @@ -453,7 +457,9 @@ def update_link_field_values(link_fields: list[dict], old: str, new: str, doctyp if parent == new and doctype == "DocType": parent = old - frappe.db.set_value(parent, {docfield: old}, docfield, new, update_modified=False) + # when a document with autoincrement naming is renamed, the old and new values are int + # but link field values are always stored as varchar, so casting the values to string + frappe.db.set_value(parent, {docfield: cstr(old)}, docfield, cstr(new), update_modified=False) # update cached link_fields as per new if doctype == "DocType" and field["parent"] == old: From 46022ff25748e157143a7b497f025afca9d15db2 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 30 Nov 2024 16:08:10 +0530 Subject: [PATCH 3/7] chore: formatting --- frappe/model/rename_doc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index d69fb81a6b..5c33d52d48 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -11,7 +11,7 @@ from frappe.model.dynamic_links import get_dynamic_link_map from frappe.model.naming import validate_name from frappe.model.utils.user_settings import sync_user_settings, update_user_settings_data from frappe.query_builder import Field -from frappe.utils.data import sbool, cint, cstr +from frappe.utils.data import cint, cstr, sbool from frappe.utils.password import rename_password from frappe.utils.scheduler import is_scheduler_inactive @@ -157,7 +157,7 @@ def rename_doc( merge = sbool(merge) meta = frappe.get_meta(doctype) - if meta.naming_rule == 'Autoincrement': + if meta.naming_rule == "Autoincrement": old = cint(old) new = cint(new) From 188f9f9650c95a0ee8eeb54d1428b9df7c3e268f Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 30 Nov 2024 16:48:49 +0530 Subject: [PATCH 4/7] fix: show Allow Rename field always --- frappe/core/doctype/doctype/doctype.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frappe/core/doctype/doctype/doctype.json b/frappe/core/doctype/doctype/doctype.json index fd9d2e061a..ab8374d47e 100644 --- a/frappe/core/doctype/doctype/doctype.json +++ b/frappe/core/doctype/doctype/doctype.json @@ -276,7 +276,6 @@ }, { "default": "1", - "depends_on": "eval:doc.naming_rule !== \"Autoincrement\"", "fieldname": "allow_rename", "fieldtype": "Check", "label": "Allow Rename", @@ -754,7 +753,7 @@ "link_fieldname": "reference_doctype" } ], - "modified": "2024-08-14 17:04:47.278892", + "modified": "2024-11-30 16:09:21.536704", "modified_by": "Administrator", "module": "Core", "name": "DocType", From 3b014a25480303690c4ce7a2cf536348917697e6 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 30 Nov 2024 16:49:04 +0530 Subject: [PATCH 5/7] test: rename autoincrement document --- frappe/__init__.py | 4 +-- frappe/tests/test_rename_doc.py | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index de0604c508..001fb92406 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -1481,8 +1481,8 @@ def reload_doc( @whitelist(methods=["POST", "PUT"]) def rename_doc( doctype: str, - old: str, - new: str, + old: str | int, + new: str | int, force: bool = False, merge: bool = False, *, diff --git a/frappe/tests/test_rename_doc.py b/frappe/tests/test_rename_doc.py index a72525187b..2e9ff0b692 100644 --- a/frappe/tests/test_rename_doc.py +++ b/frappe/tests/test_rename_doc.py @@ -279,3 +279,46 @@ class TestRenameDoc(IntegrationTestCase): self.assertEqual(len(parent_a_instance.test_table), 1) self.assertEqual(len(parent_b_instance.test_table), 1) + + def test_rename_autoincrement_doc(self): + if not frappe.db.exists("DocType", "Autoincrement DocType"): + new_doctype( + "Autoincrement DocType", + naming_rule="Autoincrement", + autoname="autoincrement", + fields=[ + { + "label": "First Name", + "fieldname": "first_name", + "fieldtype": "Data", + } + ], + ).insert() + + if not frappe.db.exists("DocType", "Autoincrement Linked DocType"): + new_doctype( + "Autoincrement Linked DocType", + fields=[ + { + "label": "Autoincrement DocType", + "fieldname": "autoincrement_doctype", + "fieldtype": "Link", + "options": "Autoincrement DocType", + } + ], + ).insert() + + # create records + mary = frappe.new_doc("Autoincrement DocType", first_name="Mary").insert() + marilyn = frappe.new_doc("Autoincrement DocType", first_name="Marilyn").insert() + linked_with_marilyn = frappe.new_doc( + "Autoincrement Linked DocType", autoincrement_doctype=marilyn.name + ).insert() + self.assertEqual(marilyn.name, linked_with_marilyn.autoincrement_doctype) + + # rename marilyn to mary + frappe.rename_doc("Autoincrement DocType", marilyn.name, mary.name, merge=True) + linked_with_marilyn.reload() + + self.assertTrue(frappe.db.exists("Autoincrement DocType", marilyn.name) is None) + self.assertEqual(linked_with_marilyn.autoincrement_doctype, frappe.utils.cstr(mary.name)) \ No newline at end of file From 94b051e05f8aedbb64248af1bdae522db52db4ab Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 2 Dec 2024 13:29:36 +0530 Subject: [PATCH 6/7] fix: cast name in UserSettings query --- frappe/model/rename_doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index 5c33d52d48..df00593e06 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -287,7 +287,7 @@ def update_user_settings(old: str, new: str, link_fields: list[dict]) -> None: user_settings_details = ( frappe.qb.from_(UserSettings) .select("user", "doctype", "data") - .where(UserSettings.data.like(old) & UserSettings.doctype.isin(linked_doctypes)) + .where(UserSettings.data.like(cstr(old)) & UserSettings.doctype.isin(linked_doctypes)) .run(as_dict=True) ) From d33b1ac695944877a999314d74f0e3825abcc08e Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 2 Dec 2024 13:40:16 +0530 Subject: [PATCH 7/7] chore: formatting --- frappe/tests/test_rename_doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/tests/test_rename_doc.py b/frappe/tests/test_rename_doc.py index 2e9ff0b692..d4e50211e1 100644 --- a/frappe/tests/test_rename_doc.py +++ b/frappe/tests/test_rename_doc.py @@ -321,4 +321,4 @@ class TestRenameDoc(IntegrationTestCase): linked_with_marilyn.reload() self.assertTrue(frappe.db.exists("Autoincrement DocType", marilyn.name) is None) - self.assertEqual(linked_with_marilyn.autoincrement_doctype, frappe.utils.cstr(mary.name)) \ No newline at end of file + self.assertEqual(linked_with_marilyn.autoincrement_doctype, frappe.utils.cstr(mary.name))