From 8cd372d90b97343c8ac09c396932dc12efcd852e Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 18 Apr 2022 11:08:07 +0530 Subject: [PATCH] refactor: Commonify autoname validation - Validate autoname for Customize Form --- frappe/core/doctype/doctype/doctype.js | 78 +--------------- frappe/core/doctype/doctype/doctype.json | 2 +- frappe/core/doctype/doctype/doctype.py | 15 ++-- .../customize_form/customize_form.json | 10 ++- frappe/public/js/frappe/doctype/index.js | 90 ++++++++++++++++++- 5 files changed, 110 insertions(+), 85 deletions(-) diff --git a/frappe/core/doctype/doctype/doctype.js b/frappe/core/doctype/doctype/doctype.js index 88cc5577a6..514e3a9455 100644 --- a/frappe/core/doctype/doctype/doctype.js +++ b/frappe/core/doctype/doctype/doctype.js @@ -57,8 +57,8 @@ frappe.ui.form.on('DocType', { frm.get_docfield('fields', 'in_list_view').label = frm.doc.istable ? __('In Grid View') : __('In List View'); - frm.events.autoname(frm); - frm.events.set_naming_rule_description(frm); + frm.cscript.autoname(frm); + frm.cscript.set_naming_rule_description(frm); }, istable: (frm) => { @@ -67,80 +67,6 @@ frappe.ui.form.on('DocType', { frm.set_value('allow_rename', 0); } }, - - naming_rule: function(frm) { - // set the "autoname" property based on naming_rule - if (frm.doc.naming_rule && !frm.__from_autoname) { - - // flag to avoid recursion - frm.__from_naming_rule = true; - - if (frm.doc.naming_rule=='Set by user') { - frm.set_value('autoname', 'Prompt'); - } else if (frm.doc.naming_rule === 'Autoincrement') { - frm.set_value('autoname', 'autoincrement'); - // set allow rename to be false when using autoincrement - frm.set_value('allow_rename', 0); - } else if (frm.doc.naming_rule=='By fieldname') { - frm.set_value('autoname', 'field:'); - } else if (frm.doc.naming_rule=='By "Naming Series" field') { - frm.set_value('autoname', 'naming_series:'); - } else if (frm.doc.naming_rule=='Expression') { - frm.set_value('autoname', 'format:'); - } else if (frm.doc.naming_rule=='Expression (old style)') { - // pass - } else if (frm.doc.naming_rule=='Random') { - frm.set_value('autoname', 'hash'); - } - setTimeout(() =>frm.__from_naming_rule = false, 500); - - frm.events.set_naming_rule_description(frm); - } - - }, - - set_naming_rule_description(frm) { - let naming_rule_description = { - 'Set by user': '', - 'Autoincrement': 'Uses Auto Increment feature of database.
WARNING: After using this option, any other naming option will not be accessible.', - 'By fieldname': 'Format: field:[fieldname]. Valid fieldname must exist', - 'By "Naming Series" field': 'Format: naming_series:[fieldname]. Fieldname called naming_series must exist', - 'Expression': 'Format: format:EXAMPLE-{MM}morewords{fieldname1}-{fieldname2}-{#####} - Replace all braced words (fieldnames, date words (DD, MM, YY), series) with their value. Outside braces, any characters can be used.', - 'Expression (old style)': 'Format: EXAMPLE-.##### Series by prefix (separated by a dot)', - 'Random': '', - 'By script': '' - }; - - if (frm.doc.naming_rule) { - frm.get_field('autoname').set_description(naming_rule_description[frm.doc.naming_rule]); - } - }, - - autoname: function(frm) { - // set naming_rule based on autoname (for old doctypes where its not been set) - if (frm.doc.autoname && !frm.doc.naming_rule && !frm.__from_naming_rule) { - // flag to avoid recursion - frm.__from_autoname = true; - if (frm.doc.autoname.toLowerCase() === 'prompt') { - frm.set_value('naming_rule', 'Set by user'); - } else if (frm.doc.autoname.toLowerCase() === 'autoincrement') { - frm.set_value('naming_rule', 'Autoincrement'); - } else if (frm.doc.autoname.startsWith('field:')) { - frm.set_value('naming_rule', 'By fieldname'); - } else if (frm.doc.autoname.startsWith('naming_series:')) { - frm.set_value('naming_rule', 'By "Naming Series" field'); - } else if (frm.doc.autoname.startsWith('format:')) { - frm.set_value('naming_rule', 'Expression'); - } else if (frm.doc.autoname.toLowerCase() === 'hash') { - frm.set_value('naming_rule', 'Random'); - } else { - frm.set_value('naming_rule', 'Expression (old style)'); - } - setTimeout(() => frm.__from_autoname = false, 500); - } - - frm.set_df_property('fields', 'reqd', frm.doc.autoname !== 'Prompt'); - }, }); frappe.ui.form.on("DocField", { diff --git a/frappe/core/doctype/doctype/doctype.json b/frappe/core/doctype/doctype/doctype.json index 8169a59566..b1579f35cd 100644 --- a/frappe/core/doctype/doctype/doctype.json +++ b/frappe/core/doctype/doctype/doctype.json @@ -208,7 +208,7 @@ "label": "Naming" }, { - "description": "Naming Options:\n
  1. field:[fieldname] - By Field
  2. autoincrement - Uses Databases' Auto Increment feature
  3. naming_series: - By Naming Series (field called naming_series must be present
  4. Prompt - Prompt user for a name
  5. [series] - Series by prefix (separated by a dot); for example PRE.#####
  6. \n
  7. format:EXAMPLE-{MM}morewords{fieldname1}-{fieldname2}-{#####} - Replace all braced words (fieldnames, date words (DD, MM, YY), series) with their value. Outside braces, any characters can be used.
", + "description": "Naming Options:\n
  1. field:[fieldname] - By Field
  2. autoincrement - Uses Databases' Auto Increment feature
  3. naming_series: - By Naming Series (field called naming_series must be present)
  4. Prompt - Prompt user for a name
  5. [series] - Series by prefix (separated by a dot); for example PRE.#####
  6. \n
  7. format:EXAMPLE-{MM}morewords{fieldname1}-{fieldname2}-{#####} - Replace all braced words (fieldnames, date words (DD, MM, YY), series) with their value. Outside braces, any characters can be used.
", "fieldname": "autoname", "fieldtype": "Data", "label": "Auto Name", diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index 1d02f09820..3a73eb9d42 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -817,10 +817,8 @@ class DocType(Document): self.autoname != "autoincrement" and doc_before_save.autoname == "autoincrement" ): frappe.throw(_("Cannot change to/from Autoincrement naming rule")) - - else: - if self.autoname == "autoincrement": - self.allow_rename = 0 + if self.autoname == "autoincrement": + self.allow_rename = 0 def validate_name(self, name=None): if not name: @@ -865,8 +863,13 @@ def validate_series(dt, autoname=None, name=None): if not autoname and dt.get("fields", {"fieldname": "naming_series"}): dt.autoname = "naming_series:" - elif dt.autoname == "naming_series:" and not dt.get("fields", {"fieldname": "naming_series"}): - frappe.throw(_("Invalid fieldname '{0}' in autoname").format(dt.autoname)) + elif dt.autoname.startswith("naming_series:"): + fieldname = dt.autoname.split("naming_series:")[0] or "naming_series" + if not dt.get("fields", {"fieldname": fieldname}): + frappe.throw( + _("Fieldname called {0} must exist to enable autonaming").format(frappe.bold(fieldname)), + title=_("Field Missing"), + ) # validate field name if autoname field:fieldname is used # Create unique index on autoname field automatically. diff --git a/frappe/custom/doctype/customize_form/customize_form.json b/frappe/custom/doctype/customize_form/customize_form.json index 1ee9d4a02a..d51762effa 100644 --- a/frappe/custom/doctype/customize_form/customize_form.json +++ b/frappe/custom/doctype/customize_form/customize_form.json @@ -24,6 +24,7 @@ "fields_section_break", "fields", "naming_section", + "naming_rule", "autoname", "view_settings_section", "title_field", @@ -50,6 +51,13 @@ "sort_order" ], "fields": [ + { + "fieldname": "naming_rule", + "fieldtype": "Select", + "label": "Naming Rule", + "length": 40, + "options": "\nSet by user\nAutoincrement\nBy fieldname\nBy \"Naming Series\" field\nExpression\nExpression (old style)\nRandom\nBy script" + }, { "fieldname": "doc_type", "fieldtype": "Link", @@ -279,7 +287,7 @@ "label": "Naming" }, { - "description": "Naming Options:\n
  1. field:[fieldname] - By Field
  2. naming_series: - By Naming Series (field called naming_series must be present
  3. Prompt - Prompt user for a name
  4. [series] - Series by prefix (separated by a dot); for example PRE.#####
  5. \n
  6. format:EXAMPLE-{MM}morewords{fieldname1}-{fieldname2}-{#####} - Replace all braced words (fieldnames, date words (DD, MM, YY), series) with their value. Outside braces, any characters can be used.
", + "description": "Naming Options:\n
  1. field:[fieldname] - By Field
  2. autoincrement - Uses Databases' Auto Increment feature
  3. naming_series: - By Naming Series (field called naming_series must be present)
  4. Prompt - Prompt user for a name
  5. [series] - Series by prefix (separated by a dot); for example PRE.#####
  6. \n
  7. format:EXAMPLE-{MM}morewords{fieldname1}-{fieldname2}-{#####} - Replace all braced words (fieldnames, date words (DD, MM, YY), series) with their value. Outside braces, any characters can be used.
", "fieldname": "autoname", "fieldtype": "Data", "label": "Auto Name" diff --git a/frappe/public/js/frappe/doctype/index.js b/frappe/public/js/frappe/doctype/index.js index 9fe8957c60..e71f0b6f09 100644 --- a/frappe/public/js/frappe/doctype/index.js +++ b/frappe/public/js/frappe/doctype/index.js @@ -20,4 +20,92 @@ frappe.model.DocTypeController = class DocTypeController extends frappe.ui.form. __("Number of attachment fields are more than {}, limit updated to {}.", [label, no_of_attach_fields])); } } -} + + naming_rule() { + // set the "autoname" property based on naming_rule + if (this.frm.doc.naming_rule && !this.frm.__from_autoname) { + + // flag to avoid recursion + this.frm.__from_naming_rule = true; + + switch (this.frm.doc.naming_rule) { + case "Set by user": + this.frm.set_value("autoname", "Prompt"); + break; + case "Autoincrement": + this.frm.set_value("autoname", "autoincrement"); + break; + case "By fieldname": + this.frm.set_value("autoname", "field:"); + break; + case 'By "Naming Series" field': + this.frm.set_value("autoname", "naming_series:"); + break; + case "Expression": + this.frm.set_value("autoname", "format:"); + break; + case "Expression (old style)": + break; + case "Random": + this.frm.set_value("autoname", "hash"); + break; + } + setTimeout(() =>this.frm.__from_naming_rule = false, 500); + + this.set_naming_rule_description(); + } + + } + + set_naming_rule_description() { + let naming_rule_description = { + 'Set by user': '', + 'Autoincrement': 'Uses Auto Increment feature of database.
WARNING: After using this option, any other naming option will not be accessible.', + 'By fieldname': 'Format: field:[fieldname]. Valid fieldname must exist', + 'By "Naming Series" field': 'Format: naming_series:[fieldname]. Default fieldname is naming_series', + 'Expression': 'Format: format:EXAMPLE-{MM}morewords{fieldname1}-{fieldname2}-{#####} - Replace all braced words (fieldnames, date words (DD, MM, YY), series) with their value. Outside braces, any characters can be used.', + 'Expression (old style)': 'Format: EXAMPLE-.##### Series by prefix (separated by a dot)', + 'Random': '', + 'By script': '' + }; + + if (this.frm.doc.naming_rule) { + this.frm.get_field('autoname').set_description(naming_rule_description[this.frm.doc.naming_rule]); + } + } + + autoname() { + // set naming_rule based on autoname (for old doctypes where its not been set) + if (this.frm.doc.autoname && !this.frm.doc.naming_rule && !this.frm.__from_naming_rule) { + // flag to avoid recursion + this.frm.__from_autoname = true; + const autoname = this.frm.doc.autoname.toLowerCase(); + + switch (autoname) { + case 'prompt': + this.frm.set_value('naming_rule', 'Set by user'); + break; + case 'autoincrement': + this.frm.set_value('naming_rule', 'Autoincrement'); + break; + case (autoname.startsWith('field:')): + this.frm.set_value('naming_rule', 'By fieldname'); + break; + case (autoname.startsWith('naming_series:')): + this.frm.set_value('naming_rule', 'By "Naming Series" field'); + break; + case (autoname.startsWith('format:')): + this.frm.set_value('naming_rule', 'Expression'); + break; + case 'hash': + this.frm.set_value('naming_rule', 'Random'); + break; + default: + this.frm.set_value('naming_rule', 'Expression (old style)'); + } + setTimeout(() => this.frm.__from_autoname = false, 500); + } + + this.frm.set_df_property('fields', 'reqd', this.frm.doc.autoname !== 'Prompt'); + } +};