diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index b9a4d73740..8c5d59181d 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -120,6 +120,59 @@ def normalize(d): return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize() +def increment(n): + """ + Attempt to increment an integer (or a string that looks like an integer!) + + e.g. + + 001 -> 002 + 2 -> 3 + AB01 -> AB02 + QQQ -> QQQ + + """ + + value = str(n).strip() + + # Ignore empty strings + if not value: + return value + + pattern = r"(.*?)(\d+)?$" + + result = re.search(pattern, value) + + # No match! + if result is None: + return value + + groups = result.groups() + + # If we cannot match the regex, then simply return the provided value + if not len(groups) == 2: + return value + + prefix, number = groups + + # No number extracted? Simply return the prefix (without incrementing!) + if not number: + return prefix + + # Record the width of the number + width = len(number) + + try: + number = int(number) + 1 + number = str(number) + except ValueError: + pass + + number = number.zfill(width) + + return prefix + number + + def decimal2string(d): """ Format a Decimal number as a string, diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 203748de3e..877adab919 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -108,6 +108,29 @@ class TestQuoteWrap(TestCase): self.assertEqual(helpers.WrapWithQuotes('hello"'), '"hello"') +class TestIncrement(TestCase): + + def tests(self): + """ Test 'intelligent' incrementing function """ + + tests = [ + ("", ""), + (1, "2"), + ("001", "002"), + ("1001", "1002"), + ("ABC123", "ABC124"), + ("XYZ0", "XYZ1"), + ("123Q", "123Q"), + ("QQQ", "QQQ"), + ] + + for test in tests: + a, b = test + + result = helpers.increment(a) + self.assertEqual(result, b) + + class TestMakeBarcode(TestCase): """ Tests for barcode string creation """