From 16dca0b1c1c9293f0afe80127341f58f747f38df Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt Date: Mon, 18 Oct 2021 14:04:53 +0200 Subject: [PATCH] feat: add consecutive calendar week (WW) for naming series The calendar week is based on ISO 8601 but behaves slightly different for the first and last days of a year to ensure consecutiveness: * If the first days of a year would be in week 53 then 00 is used instead. * if the last days of a year would be in week 01 then 53 is used instead. Closes #14413 --- frappe/model/naming.py | 15 ++++++++++ frappe/tests/test_naming.py | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/frappe/model/naming.py b/frappe/model/naming.py index deea6698b3..f3d68f3715 100644 --- a/frappe/model/naming.py +++ b/frappe/model/naming.py @@ -175,6 +175,8 @@ def parse_naming_series(parts, doctype='', doc=''): part = today.strftime("%d") elif e == 'YYYY': part = today.strftime('%Y') + elif e == 'WW': + part = determine_consecutive_week_number(today) elif e == 'timestamp': part = str(today) elif e == 'FY': @@ -193,6 +195,19 @@ def parse_naming_series(parts, doctype='', doc=''): return n +def determine_consecutive_week_number(datetime): + """Determines the consecutive calendar week""" + m = datetime.month + # ISO 8601 calandar week + w = datetime.strftime('%V') + # Ensure consecutiveness for the first and last days of a year + if m == 1 and int(w) >= 52: + w = '00' + elif m == 12 and int(w) <= 1: + w = '53' + return w + + def getseries(key, digits): # series created ? # Using frappe.qb as frappe.get_values does not allow order_by=None diff --git a/frappe/tests/test_naming.py b/frappe/tests/test_naming.py index 4435a8bb20..3031d3e344 100644 --- a/frappe/tests/test_naming.py +++ b/frappe/tests/test_naming.py @@ -7,6 +7,7 @@ from frappe.utils import now_datetime from frappe.model.naming import getseries from frappe.model.naming import append_number_if_name_exists, revert_series_if_last +from frappe.model.naming import determine_consecutive_week_number, parse_naming_series class TestNaming(unittest.TestCase): def tearDown(self): @@ -60,6 +61,34 @@ class TestNaming(unittest.TestCase): self.assertEqual(todo.name, 'TODO-{month}-{status}-{series}'.format( month=now_datetime().strftime('%m'), status=todo.status, series=series)) + def test_format_autoname_for_consecutive_week_number(self): + ''' + Test if braced params are replaced for consecutive week number in format autoname + ''' + doctype = 'ToDo' + + todo_doctype = frappe.get_doc('DocType', doctype) + todo_doctype.autoname = 'format:TODO-{WW}-{##}' + todo_doctype.save() + + description = 'Format' + + todo = frappe.new_doc(doctype) + todo.description = description + todo.insert() + + series = getseries('', 2) + + series = str(int(series)-1) + + if len(series) < 2: + series = '0' + series + + week = determine_consecutive_week_number(now_datetime()) + + self.assertEqual(todo.name, 'TODO-{week}-{series}'.format( + week=week, series=series)) + def test_revert_series(self): from datetime import datetime year = datetime.now().year @@ -150,3 +179,32 @@ class TestNaming(unittest.TestCase): self.assertEqual(amended_doc.name, "{}-CANC-1".format(original_name)) submittable_doctype.delete() + + def test_parse_naming_series_for_consecutive_week_number(self): + week = determine_consecutive_week_number(now_datetime()) + name = parse_naming_series('PREFIX-.WW.-SUFFIX') + expected_name = 'PREFIX-{}-SUFFIX'.format(week) + self.assertEqual(name, expected_name) + + def test_determine_consecutive_week_number(self): + from datetime import datetime + + dt = datetime.fromisoformat("2019-12-31") + w = determine_consecutive_week_number(dt) + self.assertEqual(w, "53") + + dt = datetime.fromisoformat("2020-01-01") + w = determine_consecutive_week_number(dt) + self.assertEqual(w, "01") + + dt = datetime.fromisoformat("2020-01-15") + w = determine_consecutive_week_number(dt) + self.assertEqual(w, "03") + + dt = datetime.fromisoformat("2021-01-01") + w = determine_consecutive_week_number(dt) + self.assertEqual(w, "00") + + dt = datetime.fromisoformat("2021-12-31") + w = determine_consecutive_week_number(dt) + self.assertEqual(w, "52")