diff --git a/erpnext/setup/doctype/naming_series/naming_series.js b/erpnext/setup/doctype/naming_series/naming_series.js
index 861b2b3983..0fb72abba6 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.js
+++ b/erpnext/setup/doctype/naming_series/naming_series.js
@@ -54,5 +54,35 @@ frappe.ui.form.on("Naming Series", {
frm.events.get_doc_and_prefix(frm);
}
});
- }
+ },
+
+ naming_series_to_check(frm) {
+ frappe.call({
+ method: "preview_series",
+ doc: frm.doc,
+ callback: function(r) {
+ if (!r.exc) {
+ frm.set_value("preview", r.message);
+ } else {
+ frm.set_value("preview", __("Failed to generate preview of series"));
+ }
+ }
+ });
+ },
+
+ add_series(frm) {
+ const series = frm.doc.naming_series_to_check;
+
+ if (!series) {
+ frappe.show_alert(__("Please type a valid series."));
+ return;
+ }
+
+ if (!frm.doc.set_options.includes(series)) {
+ const current_series = frm.doc.set_options;
+ frm.set_value("set_options", `${current_series}\n${series}`);
+ } else {
+ frappe.show_alert(__("Series already added to transaction."));
+ }
+ },
});
diff --git a/erpnext/setup/doctype/naming_series/naming_series.json b/erpnext/setup/doctype/naming_series/naming_series.json
index f936dcf3c9..c65a6f0ae4 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.json
+++ b/erpnext/setup/doctype/naming_series/naming_series.json
@@ -1,360 +1,132 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2013-01-25 11:35:08",
- "custom": 0,
- "description": "Set prefix for numbering series on your transactions",
- "docstatus": 0,
- "doctype": "DocType",
- "editable_grid": 0,
+ "actions": [],
+ "creation": "2022-05-26 03:12:49.087648",
+ "description": "Set prefix for numbering series on your transactions",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+ "setup_series",
+ "select_doc_for_series",
+ "help_html",
+ "naming_series_to_check",
+ "preview",
+ "add_series",
+ "set_options",
+ "user_must_always_select",
+ "update",
+ "column_break_13",
+ "update_series",
+ "prefix",
+ "current_value",
+ "update_series_start"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Set prefix for numbering series on your transactions",
- "fieldname": "setup_series",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Setup Series",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "description": "Set prefix for numbering series on your transactions",
+ "fieldname": "setup_series",
+ "fieldtype": "Section Break",
+ "label": "Setup Series"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "select_doc_for_series",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Select Transaction",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "select_doc_for_series",
+ "fieldtype": "Select",
+ "label": "Select Transaction"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "select_doc_for_series",
- "fieldname": "help_html",
- "fieldtype": "HTML",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Help HTML",
- "length": 0,
- "no_copy": 0,
- "options": "
\nEdit list of Series in the box below. Rules:\n
\n- Each Series Prefix on a new line.
\n- Allowed special characters are \"/\" and \"-\"
\n- Optionally, set the number of digits in the series using dot (.) followed by hashes (#). For example, \".####\" means that the series will have four digits. Default is five digits.
\n
\nExamples:
\nINV-
\nINV-10-
\nINVK-
\nINV-.####
\n
",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "depends_on": "select_doc_for_series",
+ "fieldname": "help_html",
+ "fieldtype": "HTML",
+ "label": "Help HTML",
+ "options": "\n Edit list of Series in the box below. Rules:\n
\n - Each Series Prefix on a new line.
\n - Allowed special characters are \"/\" and \"-\"
\n - \n Optionally, set the number of digits in the series using dot (.)\n followed by hashes (#). For example, \".####\" means that the series\n will have four digits. Default is five digits.\n
\n - \n You can also use variables in the series name by putting them\n between (.) dots\n
\n Support Variables:\n \n .YYYY.
- Year in 4 digits \n .YY.
- Year in 2 digits \n .MM.
- Month \n .DD.
- Day of month \n .WW.
- Week of the year \n .FY.
- Fiscal Year \n - \n
.{fieldname}.
- fieldname on the document e.g.\n branch
\n \n
\n \n
\n Examples:\n
\n - INV-
\n - INV-10-
\n - INVK-
\n - INV-.YYYY.-.{branch}.-.MM.-.####
\n
\n
\n
\n"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "select_doc_for_series",
- "fieldname": "set_options",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Series List for this Transaction",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "depends_on": "select_doc_for_series",
+ "fieldname": "set_options",
+ "fieldtype": "Text",
+ "label": "Series List for this Transaction"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "select_doc_for_series",
- "description": "Check this if you want to force the user to select a series before saving. There will be no default if you check this.",
- "fieldname": "user_must_always_select",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "User must always select",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "default": "0",
+ "depends_on": "select_doc_for_series",
+ "description": "Check this if you want to force the user to select a series before saving. There will be no default if you check this.",
+ "fieldname": "user_must_always_select",
+ "fieldtype": "Check",
+ "label": "User must always select"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "select_doc_for_series",
- "fieldname": "update",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Update",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "depends_on": "select_doc_for_series",
+ "fieldname": "update",
+ "fieldtype": "Button",
+ "label": "Update"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Change the starting / current sequence number of an existing series.",
- "fieldname": "update_series",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Update Series",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "description": "Change the starting / current sequence number of an existing series.",
+ "fieldname": "update_series",
+ "fieldtype": "Section Break",
+ "label": "Update Series"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "prefix",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Prefix",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "prefix",
+ "fieldtype": "Select",
+ "label": "Prefix"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "This is the number of the last created transaction with this prefix",
- "fieldname": "current_value",
- "fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Current Value",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "description": "This is the number of the last created transaction with this prefix",
+ "fieldname": "current_value",
+ "fieldtype": "Int",
+ "label": "Current Value"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "update_series_start",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Update Series Number",
- "length": 0,
- "no_copy": 0,
- "options": "update_series_start",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
+ "fieldname": "update_series_start",
+ "fieldtype": "Button",
+ "label": "Update Series Number",
+ "options": "update_series_start"
+ },
+ {
+ "fieldname": "naming_series_to_check",
+ "fieldtype": "Data",
+ "label": "Try a naming Series"
+ },
+ {
+ "default": " ",
+ "fieldname": "preview",
+ "fieldtype": "Text",
+ "label": "Preview of generated names",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_13",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "add_series",
+ "fieldtype": "Button",
+ "label": "Add this Series"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 1,
- "icon": "fa fa-sort-by-order",
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 1,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2017-08-17 03:41:37.685910",
- "modified_by": "Administrator",
- "module": "Setup",
- "name": "Naming Series",
- "owner": "Administrator",
+ ],
+ "hide_toolbar": 1,
+ "icon": "fa fa-sort-by-order",
+ "idx": 1,
+ "issingle": 1,
+ "links": [],
+ "modified": "2022-05-26 06:06:42.109504",
+ "modified_by": "Administrator",
+ "module": "Setup",
+ "name": "Naming Series",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 0,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "System Manager",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 1,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "track_changes": 0,
- "track_seen": 0
+ ],
+ "read_only": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 4fba776cb5..eafc264f30 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -6,7 +6,7 @@ import frappe
from frappe import _, msgprint, throw
from frappe.core.doctype.doctype.doctype import validate_series
from frappe.model.document import Document
-from frappe.model.naming import parse_naming_series
+from frappe.model.naming import make_autoname, parse_naming_series
from frappe.permissions import get_doctypes_with_read
from frappe.utils import cint, cstr
@@ -206,6 +206,35 @@ class NamingSeries(Document):
prefix = parse_naming_series(parts)
return prefix
+ @frappe.whitelist()
+ def preview_series(self) -> str:
+ """Preview what the naming series will generate."""
+
+ generated_names = []
+ series = self.naming_series_to_check
+ if not series:
+ return ""
+
+ try:
+ doc = self._fetch_last_doc_if_available()
+ for _count in range(3):
+ generated_names.append(make_autoname(series, doc=doc))
+ except Exception as e:
+ if frappe.message_log:
+ frappe.message_log.pop()
+ return _("Failed to generate names from the series") + f"\n{str(e)}"
+
+ # Explcitly rollback in case any changes were made to series table.
+ frappe.db.rollback() # nosemgrep
+ return "\n".join(generated_names)
+
+ def _fetch_last_doc_if_available(self):
+ """Fetch last doc for evaluating naming series with fields."""
+ try:
+ return frappe.get_last_doc(self.select_doc_for_series)
+ except Exception:
+ return None
+
def set_by_naming_series(
doctype, fieldname, naming_series, hide_name_field=True, make_mandatory=1
diff --git a/erpnext/setup/doctype/naming_series/test_naming_series.py b/erpnext/setup/doctype/naming_series/test_naming_series.py
new file mode 100644
index 0000000000..fce663e4c5
--- /dev/null
+++ b/erpnext/setup/doctype/naming_series/test_naming_series.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+import frappe
+from frappe.tests.utils import FrappeTestCase
+
+from erpnext.setup.doctype.naming_series.naming_series import NamingSeries
+
+
+class TestNamingSeries(FrappeTestCase):
+ def setUp(self):
+ self.ns: NamingSeries = frappe.get_doc("Naming Series")
+
+ def tearDown(self):
+ frappe.db.rollback()
+
+ def test_naming_preview(self):
+ self.ns.select_doc_for_series = "Sales Invoice"
+
+ self.ns.naming_series_to_check = "AXBZ.####"
+ serieses = self.ns.preview_series().split("\n")
+ self.assertEqual(["AXBZ0001", "AXBZ0002", "AXBZ0003"], serieses)
+
+ self.ns.naming_series_to_check = "AXBZ-.{currency}.-"
+ serieses = self.ns.preview_series().split("\n")
+
+ def test_get_transactions(self):
+
+ naming_info = self.ns.get_transactions()
+ self.assertIn("Sales Invoice", naming_info["transactions"])
+
+ existing_naming_series = frappe.get_meta("Sales Invoice").get_field("naming_series").options
+
+ for series in existing_naming_series.split("\n"):
+ self.assertIn(series, naming_info["prefixes"])