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