diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index cbcfa350f5..3edb66bd42 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -67,7 +67,7 @@ class DocType(Document): self.scrub_field_names() self.set_default_in_list_view() self.set_default_translatable() - self.validate_series() + validate_series(self) self.validate_document_type() validate_fields(self) @@ -238,44 +238,6 @@ class DocType(Document): # unique is automatically an index if d.unique: d.search_index = 0 - def validate_series(self, autoname=None, name=None): - """Validate if `autoname` property is correctly set.""" - if not autoname: autoname = self.autoname - if not name: name = self.name - - if not autoname and self.get("fields", {"fieldname":"naming_series"}): - self.autoname = "naming_series:" - elif self.autoname == "naming_series:" and not self.get("fields", {"fieldname":"naming_series"}): - frappe.throw(_("Invalid fieldname '{0}' in autoname").format(self.autoname)) - - # validate field name if autoname field:fieldname is used - # Create unique index on autoname field automatically. - if autoname and autoname.startswith('field:'): - field = autoname.split(":")[1] - if not field or field not in [ df.fieldname for df in self.fields ]: - frappe.throw(_("Invalid fieldname '{0}' in autoname").format(field)) - else: - for df in self.fields: - if df.fieldname == field: - df.unique = 1 - break - - if autoname and (not autoname.startswith('field:')) \ - and (not autoname.startswith('eval:')) \ - and (not autoname.lower() in ('prompt', 'hash')) \ - and (not autoname.startswith('naming_series:')) \ - and (not autoname.startswith('format:')): - - prefix = autoname.split('.')[0] - used_in = frappe.db.sql(""" - SELECT `name` - FROM `tabDocType` - WHERE `autoname` LIKE CONCAT(%s, '.%%') - AND `name`!=%s - """, (prefix, name)) - if used_in: - frappe.throw(_("Series {0} already used in {1}").format(prefix, used_in[0][0])) - def on_update(self): """Update database schema, make controller templates if `custom` is not set and clear cache.""" try: @@ -666,6 +628,40 @@ class DocType(Document): validate_route_conflict(self.doctype, self.name) +def validate_series(dt): + if not dt.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)) + + # validate field name if autoname field:fieldname is used + # Create unique index on autoname field automatically. + if dt.autoname and dt.autoname.startswith('field:'): + field = dt.autoname.split(":")[1] + if not field or field not in [ df.fieldname for df in dt.fields ]: + frappe.throw(_("Invalid fieldname '{0}' in autoname").format(field)) + else: + for df in dt.fields: + if df.fieldname == field: + df.unique = 1 + break + + if dt.autoname and (not dt.autoname.startswith('field:')) \ + and (not dt.autoname.startswith('eval:')) \ + and (not dt.autoname.lower() in ('prompt', 'hash')) \ + and (not dt.autoname.startswith('naming_series:')) \ + and (not dt.autoname.startswith('format:')): + + prefix = dt.autoname.split('.')[0] + used_in = frappe.db.sql(""" + SELECT `name` + FROM `tabDocType` + WHERE `autoname` LIKE CONCAT(%s, '.%%') + AND `name`!=%s + """, (prefix, dt.name)) + if used_in: + frappe.throw(_("Series {0} already used in {1}").format(prefix, used_in[0][0])) + def validate_links_table_fieldnames(meta): """Validate fieldnames in Links table""" if frappe.flags.in_patch: return diff --git a/frappe/custom/doctype/customize_form/customize_form.json b/frappe/custom/doctype/customize_form/customize_form.json index ff102b3c08..77f62b3ec3 100644 --- a/frappe/custom/doctype/customize_form/customize_form.json +++ b/frappe/custom/doctype/customize_form/customize_form.json @@ -23,6 +23,8 @@ "allow_import", "fields_section_break", "fields", + "naming_section", + "autoname", "view_settings_section", "title_field", "image_field", @@ -261,6 +263,18 @@ "fieldtype": "Table", "label": "Actions", "options": "DocType Action" + }, + { + "collapsible": 1, + "fieldname": "naming_section", + "fieldtype": "Section Break", + "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.
", + "fieldname": "autoname", + "fieldtype": "Data", + "label": "Auto Name" } ], "hide_toolbar": 1, @@ -269,7 +283,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2020-09-24 14:16:49.594012", + "modified": "2021-02-16 15:22:11.108256", "modified_by": "Administrator", "module": "Custom", "name": "Customize Form", diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 50acab46b5..74742551a4 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -17,6 +17,7 @@ from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype, che from frappe.custom.doctype.custom_field.custom_field import create_custom_field from frappe.custom.doctype.property_setter.property_setter import delete_property_setter from frappe.model.docfield import supports_translation +from frappe.core.doctype.doctype.doctype import validate_series class CustomizeForm(Document): def on_update(self): @@ -135,7 +136,7 @@ class CustomizeForm(Document): def save_customization(self): if not self.doc_type: return - + validate_series(self) self.flags.update_db = False self.flags.rebuild_doctype_for_global_search = False self.set_property_setters() @@ -485,7 +486,8 @@ doctype_properties = { 'show_preview_popup': 'Check', 'email_append_to': 'Check', 'subject_field': 'Data', - 'sender_field': 'Data' + 'sender_field': 'Data', + 'autoname': 'Data' } docfield_properties = {