From fdc2cae6bac0daa7b1bfe640c487c8e9b5c48842 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 28 Feb 2022 23:31:12 +1100 Subject: [PATCH] Fix some existing problems with the extract_serial_numbers helper function - Serial numbers don't really have to be "numbers" - Allow any text value once other higher-level checks have been performed --- InvenTree/InvenTree/helpers.py | 44 ++++++++++++++++------------------ 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 2595f8b5c3..e260f71906 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -407,14 +407,16 @@ def DownloadFile(data, filename, content_type='application/text', inline=False): def extract_serial_numbers(serials, expected_quantity, next_number: int): - """ Attempt to extract serial numbers from an input string. - - Serial numbers must be integer values - - Serial numbers must be positive - - Serial numbers can be split by whitespace / newline / commma chars - - Serial numbers can be supplied as an inclusive range using hyphen char e.g. 10-20 - - Serial numbers can be defined as ~ for getting the next available serial number - - Serial numbers can be supplied as + for getting all expecteded numbers starting from - - Serial numbers can be supplied as + for getting numbers starting from + """ + Attempt to extract serial numbers from an input string: + + Requirements: + - Serial numbers can be either strings, or integers + - Serial numbers can be split by whitespace / newline / commma chars + - Serial numbers can be supplied as an inclusive range using hyphen char e.g. 10-20 + - Serial numbers can be defined as ~ for getting the next available serial number + - Serial numbers can be supplied as + for getting all expecteded numbers starting from + - Serial numbers can be supplied as + for getting numbers starting from Args: serials: input string with patterns @@ -428,17 +430,18 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): if '~' in serials: serials = serials.replace('~', str(next_number)) + # Split input string by whitespace or comma (,) characters groups = re.split("[\s,]+", serials) numbers = [] errors = [] - # helpers - def number_add(n): - if n in numbers: - errors.append(_('Duplicate serial: {n}').format(n=n)) + # Helper function to check for duplicated numbers + def add_sn(sn): + if sn in numbers: + errors.append(_('Duplicate serial: {sn}').format(n=n)) else: - numbers.append(n) + numbers.append(sn) try: expected_quantity = int(expected_quantity) @@ -466,7 +469,7 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): if a < b: for n in range(a, b + 1): - number_add(n) + add_sn(n) else: errors.append(_("Invalid group: {g}").format(g=group)) @@ -495,21 +498,16 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): end = start + expected_quantity for n in range(start, end): - number_add(n) + add_sn(n) # no case else: errors.append(_("Invalid group: {g}").format(g=group)) - # Group should be a number + # At this point, we assume that the "group" is just a single serial value + # Note: At this point it is treated only as a string elif group: - # try conversion - try: - number = int(group) - except: - # seem like it is not a number - raise ValidationError(_(f"Invalid group {group}")) - number_add(number) + add_sn(group) # No valid input group detected else: