From f8ce23217e617d6b7e3df666ef49bfe1f46d0d6f Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 02:22:10 +0100 Subject: [PATCH 01/67] simplify call --- InvenTree/stock/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 9961bb7bae..d69c94b4a8 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -471,7 +471,7 @@ class StockList(generics.ListCreateAPIView): if serial_numbers: # If serial numbers are specified, check that they match! try: - serials = extract_serial_numbers(serial_numbers, data['quantity']) + serials = extract_serial_numbers(serial_numbers, quantity) except DjangoValidationError as e: raise ValidationError({ 'quantity': e.messages, From c9f0528dfc255425b2a15257d4236259c5878d1f Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 02:24:00 +0100 Subject: [PATCH 02/67] append api call --- InvenTree/InvenTree/helpers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index fd86306627..a97b32a9ba 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -404,17 +404,19 @@ def DownloadFile(data, filename, content_type='application/text', inline=False): return response -def extract_serial_numbers(serials, expected_quantity): +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 Args: expected_quantity: The number of (unique) serial numbers we expect + next_number(int): the next possible serial number """ serials = serials.strip() From 750e3297ccc68a579e0611ebceeef15c52d68932 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 02:24:13 +0100 Subject: [PATCH 03/67] expand docstring --- InvenTree/InvenTree/helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index a97b32a9ba..42dae832c8 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -415,6 +415,7 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): - Serial numbers can be supplied as + for getting numbers starting from Args: + serials: input string with patterns expected_quantity: The number of (unique) serial numbers we expect next_number(int): the next possible serial number """ From 7ef0e7941e15c8c26e3ba9f5927c1736191fb1fe Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 02:24:57 +0100 Subject: [PATCH 04/67] expand tests TDD for the win? --- InvenTree/InvenTree/tests.py | 40 +++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 06dcad9797..91b94deb1c 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -237,52 +237,68 @@ class TestSerialNumberExtraction(TestCase): e = helpers.extract_serial_numbers - sn = e("1-5", 5) - self.assertEqual(len(sn), 5) + sn = e("1-5", 5, 1) + self.assertEqual(len(sn), 5, 1) for i in range(1, 6): self.assertIn(i, sn) - sn = e("1, 2, 3, 4, 5", 5) + sn = e("1, 2, 3, 4, 5", 5, 1) self.assertEqual(len(sn), 5) - sn = e("1-5, 10-15", 11) + sn = e("1-5, 10-15", 11, 1) self.assertIn(3, sn) self.assertIn(13, sn) - sn = e("1+", 10) + sn = e("1+", 10, 1) self.assertEqual(len(sn), 10) self.assertEqual(sn, [_ for _ in range(1, 11)]) - sn = e("4, 1+2", 4) + sn = e("4, 1+2", 4, 1) self.assertEqual(len(sn), 4) self.assertEqual(sn, ["4", 1, 2, 3]) + sn = e("~", 1, 1) + self.assertEqual(len(sn), 1) + self.assertEqual(sn, [1]) + + sn = e("~", 1, 3) + self.assertEqual(len(sn), 1) + self.assertEqual(sn, [3]) + + sn = e("~+", 2, 5) + self.assertEqual(len(sn), 2) + self.assertEqual(sn, [5, 6]) + + sn = e("~+3", 2, 5) + self.assertEqual(len(sn), 4) + self.assertEqual(sn, [5, 6, 7, 8]) + def test_failures(self): e = helpers.extract_serial_numbers # Test duplicates with self.assertRaises(ValidationError): - e("1,2,3,3,3", 5) + e("1,2,3,3,3", 5, 1) # Test invalid length with self.assertRaises(ValidationError): - e("1,2,3", 5) + e("1,2,3", 5, 1) # Test empty string with self.assertRaises(ValidationError): - e(", , ,", 0) + e(", , ,", 0, 1) # Test incorrect sign in group with self.assertRaises(ValidationError): - e("10-2", 8) + e("10-2", 8, 1) # Test invalid group with self.assertRaises(ValidationError): - e("1-5-10", 10) + e("1-5-10", 10, 1) with self.assertRaises(ValidationError): - e("10, a, 7-70j", 4) + e("10, a, 7-70j", 4, 1) class TestVersionNumber(TestCase): From 771f3d6b7b8deaa77bc1a12c2a57fa362c40b3cd Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 02:38:32 +0100 Subject: [PATCH 05/67] add fnc for new matcher --- InvenTree/InvenTree/helpers.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 42dae832c8..e030d51abf 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -422,6 +422,10 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): serials = serials.strip() + # fill in the next serial number into the serial + if '~' in serials: + serials = serials.replace('~', next_number) + groups = re.split("[\s,]+", serials) numbers = [] From 1d0aa900e8b6bfb4d5ccd5ec94cbffb902cc8ad8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 02:50:23 +0100 Subject: [PATCH 06/67] add helper fnc to get latest SN as int --- InvenTree/part/models.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 5c6c07d9d8..4f06d43e60 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -583,6 +583,26 @@ class Part(MPTTModel): # No serial numbers found return None + def getLatestSerialNumberInt(self): + """ + Return the "latest" serial number for this Part as a integer. + If it is not an integer the result is 0 + """ + + latest = self.getLatestSerialNumber() + + # No serial number = > 0 + if latest is None: + latest = 0 + + # Attempt to turn into an integer and return + try: + latest = int(latest) + return latest + except: + # not an integer so 0 + return 0 + def getSerialNumberString(self, quantity=1): """ Return a formatted string representing the next available serial numbers, From 2ec41b02f82336a121110611e277e2a0dd82f4b5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 03:01:52 +0100 Subject: [PATCH 07/67] append information about next serial numbe to fnc call Fixes #2484 --- InvenTree/build/views.py | 4 ++-- InvenTree/order/serializers.py | 2 +- InvenTree/stock/api.py | 25 +++++++++++++------------ InvenTree/stock/serializers.py | 3 ++- InvenTree/stock/views.py | 4 ++-- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/InvenTree/build/views.py b/InvenTree/build/views.py index fd730b6a7e..1d28cb8d50 100644 --- a/InvenTree/build/views.py +++ b/InvenTree/build/views.py @@ -109,7 +109,7 @@ class BuildOutputCreate(AjaxUpdateView): # Check that the serial numbers are valid if serials: try: - extracted = extract_serial_numbers(serials, quantity) + extracted = extract_serial_numbers(serials, quantity, build.part.getLatestSerialNumberInt()) if extracted: # Check for conflicting serial numbers @@ -143,7 +143,7 @@ class BuildOutputCreate(AjaxUpdateView): serials = data.get('serial_numbers', None) if serials: - serial_numbers = extract_serial_numbers(serials, quantity) + serial_numbers = extract_serial_numbers(serials, quantity, build.part.getLatestSerialNumberInt()) else: serial_numbers = None diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 32e50943b1..6097a707c7 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -861,7 +861,7 @@ class SOSerialAllocationSerializer(serializers.Serializer): part = line_item.part try: - data['serials'] = extract_serial_numbers(serial_numbers, quantity) + data['serials'] = extract_serial_numbers(serial_numbers, quantity, part.getLatestSerialNumberInt()) except DjangoValidationError as e: raise ValidationError({ 'serial_numbers': e.messages, diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index d69c94b4a8..fa15708b6d 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -466,18 +466,6 @@ class StockList(generics.ListCreateAPIView): notes = data.get('notes', '') - serials = None - - if serial_numbers: - # If serial numbers are specified, check that they match! - try: - serials = extract_serial_numbers(serial_numbers, quantity) - except DjangoValidationError as e: - raise ValidationError({ - 'quantity': e.messages, - 'serial_numbers': e.messages, - }) - with transaction.atomic(): # Create an initial stock item @@ -493,6 +481,19 @@ class StockList(generics.ListCreateAPIView): if item.part.default_expiry > 0: item.expiry_date = datetime.now().date() + timedelta(days=item.part.default_expiry) + # fetch serial numbers + serials = None + + if serial_numbers: + # If serial numbers are specified, check that they match! + try: + serials = extract_serial_numbers(serial_numbers, quantity, item.part.getLatestSerialNumberInt()) + except DjangoValidationError as e: + raise ValidationError({ + 'quantity': e.messages, + 'serial_numbers': e.messages, + }) + # Finally, save the item (with user information) item.save(user=user) diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index e69cd90f82..5379273a2e 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -350,7 +350,7 @@ class SerializeStockItemSerializer(serializers.Serializer): serial_numbers = data['serial_numbers'] try: - serials = InvenTree.helpers.extract_serial_numbers(serial_numbers, quantity) + serials = InvenTree.helpers.extract_serial_numbers(serial_numbers, quantity, item.part.getLatestSerialNumberInt()) except DjangoValidationError as e: raise ValidationError({ 'serial_numbers': e.messages, @@ -379,6 +379,7 @@ class SerializeStockItemSerializer(serializers.Serializer): serials = InvenTree.helpers.extract_serial_numbers( data['serial_numbers'], data['quantity'], + item.part.getLatestSerialNumberInt() ) item.serializeStock( diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 27801f0ed6..6c89db0f2f 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -1241,7 +1241,7 @@ class StockItemCreate(AjaxCreateView): if len(sn) > 0: try: - serials = extract_serial_numbers(sn, quantity) + serials = extract_serial_numbers(sn, quantity, part.getLatestSerialNumberInt()) except ValidationError as e: serials = None form.add_error('serial_numbers', e.messages) @@ -1283,7 +1283,7 @@ class StockItemCreate(AjaxCreateView): # Create a single stock item for each provided serial number if len(sn) > 0: - serials = extract_serial_numbers(sn, quantity) + serials = extract_serial_numbers(sn, quantity, part.getLatestSerialNumberInt()) for serial in serials: item = StockItem( From a745aa500e79789af3a19fba12116dec700b64b9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 03:02:43 +0100 Subject: [PATCH 08/67] replace must be str --- InvenTree/InvenTree/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index e030d51abf..4848b49e33 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -424,7 +424,7 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): # fill in the next serial number into the serial if '~' in serials: - serials = serials.replace('~', next_number) + serials = serials.replace('~', str(next_number)) groups = re.split("[\s,]+", serials) From b1188be019c3ac4f84b98e0f19e74932e3d84df6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 15:34:03 +0100 Subject: [PATCH 09/67] fix test assertations --- InvenTree/InvenTree/tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 91b94deb1c..843cf0db3c 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -259,17 +259,17 @@ class TestSerialNumberExtraction(TestCase): sn = e("~", 1, 1) self.assertEqual(len(sn), 1) - self.assertEqual(sn, [1]) + self.assertEqual(sn, ['1']) sn = e("~", 1, 3) self.assertEqual(len(sn), 1) - self.assertEqual(sn, [3]) + self.assertEqual(sn, ['3']) sn = e("~+", 2, 5) self.assertEqual(len(sn), 2) self.assertEqual(sn, [5, 6]) - sn = e("~+3", 2, 5) + sn = e("~+3", 4, 5) self.assertEqual(len(sn), 4) self.assertEqual(sn, [5, 6, 7, 8]) From 1eb9b395bc976f1e3d7fabf1e7dadd6f9096fc96 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 15:43:34 +0100 Subject: [PATCH 10/67] more complicated tests --- InvenTree/InvenTree/tests.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 843cf0db3c..e4ab3c7a0c 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -301,6 +301,26 @@ class TestSerialNumberExtraction(TestCase): e("10, a, 7-70j", 4, 1) + def test_combinations(self): + e = helpers.extract_serial_numbers + + sn = e("1 3-5 9+2", 7, 1) + self.assertEqual(len(sn), 7) + self.assertEqual(sn, ['1', 3, 4, 5, 9, 10, 11]) + + sn = e("1,3-5,9+2", 7, 1) + self.assertEqual(len(sn), 7) + self.assertEqual(sn, ['1', 3, 4, 5, 9, 10, 11]) + + sn = e("~+2", 3, 14) + self.assertEqual(len(sn), 3) + self.assertEqual(sn, [14, 15, 16]) + + sn = e("~+", 2, 14) + self.assertEqual(len(sn), 2) + self.assertEqual(sn, [14, 15]) + + class TestVersionNumber(TestCase): """ Unit tests for version number functions From 624b16a4192d76a3342774ded2aaaa06e869cef6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 15:51:44 +0100 Subject: [PATCH 11/67] fix pep style --- InvenTree/InvenTree/tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index e4ab3c7a0c..0e99962afb 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -300,7 +300,6 @@ class TestSerialNumberExtraction(TestCase): with self.assertRaises(ValidationError): e("10, a, 7-70j", 4, 1) - def test_combinations(self): e = helpers.extract_serial_numbers From 972f93f6d82898eeeba690a9afb1b4773659088f Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 15:53:04 +0100 Subject: [PATCH 12/67] always return a number --- InvenTree/InvenTree/helpers.py | 2 +- InvenTree/InvenTree/tests.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 4848b49e33..44d49c445f 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -504,7 +504,7 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): if group in numbers: errors.append(_("Duplicate serial: {g}".format(g=group))) else: - numbers.append(group) + numbers.append(int(group)) if len(errors) > 0: raise ValidationError(errors) diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 0e99962afb..7fd62908a0 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -255,15 +255,15 @@ class TestSerialNumberExtraction(TestCase): sn = e("4, 1+2", 4, 1) self.assertEqual(len(sn), 4) - self.assertEqual(sn, ["4", 1, 2, 3]) + self.assertEqual(sn, [4, 1, 2, 3]) sn = e("~", 1, 1) self.assertEqual(len(sn), 1) - self.assertEqual(sn, ['1']) + self.assertEqual(sn, [1]) sn = e("~", 1, 3) self.assertEqual(len(sn), 1) - self.assertEqual(sn, ['3']) + self.assertEqual(sn, [3]) sn = e("~+", 2, 5) self.assertEqual(len(sn), 2) @@ -305,11 +305,11 @@ class TestSerialNumberExtraction(TestCase): sn = e("1 3-5 9+2", 7, 1) self.assertEqual(len(sn), 7) - self.assertEqual(sn, ['1', 3, 4, 5, 9, 10, 11]) + self.assertEqual(sn, [1, 3, 4, 5, 9, 10, 11]) sn = e("1,3-5,9+2", 7, 1) self.assertEqual(len(sn), 7) - self.assertEqual(sn, ['1', 3, 4, 5, 9, 10, 11]) + self.assertEqual(sn, [1, 3, 4, 5, 9, 10, 11]) sn = e("~+2", 3, 14) self.assertEqual(len(sn), 3) From 410c190ddfb4033b6189278f34eff9826ae3c086 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 15:53:23 +0100 Subject: [PATCH 13/67] more docs --- InvenTree/InvenTree/helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 44d49c445f..669cc56029 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -500,6 +500,7 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): errors.append(_("Invalid group: {g}").format(g=group)) continue + # Group is a number else: if group in numbers: errors.append(_("Duplicate serial: {g}".format(g=group))) From ed09d5015a07739e2fa22849f6aef7bef77fff75 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 16:13:44 +0100 Subject: [PATCH 14/67] better group handeling --- InvenTree/InvenTree/helpers.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 669cc56029..96fa5c7608 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -11,6 +11,7 @@ from PIL import Image from decimal import Decimal, InvalidOperation from wsgiref.util import FileWrapper +from django.db.models.expressions import RawSQL from django.http import StreamingHttpResponse from django.core.exceptions import ValidationError, FieldError from django.utils.translation import ugettext_lazy as _ @@ -500,12 +501,20 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int): errors.append(_("Invalid group: {g}").format(g=group)) continue - # Group is a number + # Group should be a number + 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) + + # No valid input group detected else: - if group in numbers: - errors.append(_("Duplicate serial: {g}".format(g=group))) - else: - numbers.append(int(group)) + raise ValidationError(_(f"Invalid/no group {group}")) if len(errors) > 0: raise ValidationError(errors) From f2c1fe1f9513ab6f05ee4338d362b0a2042fcb7b Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Dec 2021 16:16:20 +0100 Subject: [PATCH 15/67] damm vscode intellisense adding stuff I do not need --- InvenTree/InvenTree/helpers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 96fa5c7608..1418fddd41 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -11,7 +11,6 @@ from PIL import Image from decimal import Decimal, InvalidOperation from wsgiref.util import FileWrapper -from django.db.models.expressions import RawSQL from django.http import StreamingHttpResponse from django.core.exceptions import ValidationError, FieldError from django.utils.translation import ugettext_lazy as _ From 67d9d9413f5e75111b409568e7b5b9ddf2fb951a Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 Dec 2021 22:58:11 +1100 Subject: [PATCH 16/67] Plugin code bug fix - handle case where self.plugin is None --- InvenTree/plugin/models.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/InvenTree/plugin/models.py b/InvenTree/plugin/models.py index b8178440af..811ed5b431 100644 --- a/InvenTree/plugin/models.py +++ b/InvenTree/plugin/models.py @@ -54,7 +54,11 @@ class PluginConfig(models.Model): # extra attributes from the registry def mixins(self): - return self.plugin._mixinreg + + if self.plugin: + return self.plugin._mixinreg + else: + return {} # functions From 690ba811efc70d76584eab8520f8fc97504cf5fd Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 Dec 2021 22:58:52 +1100 Subject: [PATCH 17/67] require gnupg in docker image --- docker/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/Dockerfile b/docker/Dockerfile index 0978e43075..673792a22f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -59,6 +59,7 @@ RUN apk -U upgrade # Install required system packages RUN apk add --no-cache git make bash \ gcc libgcc g++ libstdc++ \ + gnupg \ libjpeg-turbo libjpeg-turbo-dev jpeg jpeg-dev \ libffi libffi-dev \ zlib zlib-dev \ From 04820c894b35ad70910f53ee29eb2424129d6145 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 Dec 2021 23:04:08 +1100 Subject: [PATCH 18/67] getattr should look for "SETTINGS" and not "GLOBALSETTINGS" --- InvenTree/plugin/builtin/integration/mixins.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 3a6b558db7..0af66333cb 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -1,14 +1,19 @@ -"""default mixins for IntegrationMixins""" +""" +Plugin mixin classes +""" + from django.conf.urls import url, include from plugin.urls import PLUGIN_BASE class GlobalSettingsMixin: - """Mixin that enables global settings for the plugin""" + """ + Mixin that enables global settings for the plugin + """ + class MixinMeta: - """meta options for this mixin""" - MIXIN_NAME = 'Global settings' + MIXIN_NAME = 'Settings' def __init__(self): super().__init__() @@ -19,7 +24,7 @@ class GlobalSettingsMixin: """ setup global settings for this plugin """ - return getattr(self, 'GLOBALSETTINGS', None) + return getattr(self, 'SETTINGS', None) @property def has_globalsettings(self): From be3bb05eddff6f202affeb0753dc17d9cfc69f7e Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 Dec 2021 23:06:28 +1100 Subject: [PATCH 19/67] Improve docstrings --- .../plugin/builtin/integration/mixins.py | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 0af66333cb..03922603a7 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -11,7 +11,7 @@ class GlobalSettingsMixin: """ Mixin that enables global settings for the plugin """ - + class MixinMeta: MIXIN_NAME = 'Settings' @@ -22,28 +22,30 @@ class GlobalSettingsMixin: def setup_globalsettings(self): """ - setup global settings for this plugin + Setup global settings for this plugin """ return getattr(self, 'SETTINGS', None) @property def has_globalsettings(self): """ - does this plugin use custom global settings + Does this plugin use custom global settings """ return bool(self.globalsettings) @property def globalsettingspatterns(self): """ - get patterns for InvenTreeSetting defintion + Get patterns for InvenTreeSetting defintion """ if self.has_globalsettings: return {f'PLUGIN_{self.slug.upper()}_{key}': value for key, value in self.globalsettings.items()} return None def _globalsetting_name(self, key): - """get global name of setting""" + """ + Get global name of setting + """ return f'PLUGIN_{self.slug.upper()}_{key}' def get_globalsetting(self, key): @@ -62,9 +64,11 @@ class GlobalSettingsMixin: class UrlsMixin: - """Mixin that enables urls for the plugin""" + """ + Mixin that enables custom URLs for the plugin + """ + class MixinMeta: - """meta options for this mixin""" MIXIN_NAME = 'URLs' def __init__(self): @@ -110,7 +114,10 @@ class UrlsMixin: class NavigationMixin: - """Mixin that enables adding navigation links with the plugin""" + """ + Mixin that enables custom navigation links with the plugin + """ + NAVIGATION_TAB_NAME = None NAVIGATION_TAB_ICON = "fas fa-question" @@ -157,7 +164,10 @@ class NavigationMixin: class AppMixin: - """Mixin that enables full django app functions for a plugin""" + """ + Mixin that enables full django app functions for a plugin + """ + class MixinMeta: """meta options for this mixin""" MIXIN_NAME = 'App registration' From f97ffaf9c3d89a0a13ec43cc9db85014cdc7e168 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 Dec 2021 23:08:33 +1100 Subject: [PATCH 20/67] Visual tweak to settings page --- InvenTree/templates/InvenTree/settings/plugin.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/templates/InvenTree/settings/plugin.html b/InvenTree/templates/InvenTree/settings/plugin.html index e9f33bedaf..ac3129eddc 100644 --- a/InvenTree/templates/InvenTree/settings/plugin.html +++ b/InvenTree/templates/InvenTree/settings/plugin.html @@ -70,7 +70,7 @@ {% if mixin_list %} {% for mixin in mixin_list %} - {% blocktrans with name=mixin.human_name %}has {{name}}{% endblocktrans %} + {{ mixin.human_name }} {% endfor %} {% endif %} From 76fe774b6e3edc4a8a35cdc4ebf8f1897f55c383 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 Dec 2021 23:11:12 +1100 Subject: [PATCH 21/67] Visual tweaks --- InvenTree/templates/InvenTree/settings/plugin_settings.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/InvenTree/templates/InvenTree/settings/plugin_settings.html b/InvenTree/templates/InvenTree/settings/plugin_settings.html index e3b1f18046..f8ab02de3e 100644 --- a/InvenTree/templates/InvenTree/settings/plugin_settings.html +++ b/InvenTree/templates/InvenTree/settings/plugin_settings.html @@ -67,7 +67,10 @@ {% if plugin.is_package == False %} -

{% trans 'The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running.' %}

+
+ {% trans 'The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running.' %} +
+ {% endif %}
From 572f4a21b3a40b2c3ca90160b2ea0f4478276f6b Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 Dec 2021 23:13:33 +1100 Subject: [PATCH 22/67] capitalization --- InvenTree/templates/InvenTree/settings/mixins/urls.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/templates/InvenTree/settings/mixins/urls.html b/InvenTree/templates/InvenTree/settings/mixins/urls.html index 1f317b5dc0..4bebfbce89 100644 --- a/InvenTree/templates/InvenTree/settings/mixins/urls.html +++ b/InvenTree/templates/InvenTree/settings/mixins/urls.html @@ -18,7 +18,7 @@ {{key}} {{entry.1}} - {% trans 'open in new tab' %} + {% trans 'Open in new tab' %} {% endif %}{% endfor %} From e02a2cef1b5c6e3f6fd76bf9bef68bd998525da7 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 31 Dec 2021 14:18:27 +1100 Subject: [PATCH 23/67] Fixes unit test --- InvenTree/plugin/test_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/plugin/test_integration.py b/InvenTree/plugin/test_integration.py index df80016dc8..fa585d0a40 100644 --- a/InvenTree/plugin/test_integration.py +++ b/InvenTree/plugin/test_integration.py @@ -21,7 +21,7 @@ class BaseMixinDefinition: class GlobalSettingsMixinTest(BaseMixinDefinition, TestCase): - MIXIN_HUMAN_NAME = 'Global settings' + MIXIN_HUMAN_NAME = 'Settings' MIXIN_NAME = 'globalsettings' MIXIN_ENABLE_CHECK = 'has_globalsettings' From 02e0ea6e3aeda8b8a27726eed16ab39bd5700320 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 31 Dec 2021 14:25:22 +1100 Subject: [PATCH 24/67] Rename "GlobalSettingsPlugin" -> "SettingsPlugin" --- InvenTree/plugin/builtin/integration/mixins.py | 2 +- InvenTree/plugin/mixins/__init__.py | 7 +++++-- InvenTree/plugin/samples/integration/sample.py | 11 +++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 03922603a7..7ddfeeccb8 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -7,7 +7,7 @@ from django.conf.urls import url, include from plugin.urls import PLUGIN_BASE -class GlobalSettingsMixin: +class SettingsMixin: """ Mixin that enables global settings for the plugin """ diff --git a/InvenTree/plugin/mixins/__init__.py b/InvenTree/plugin/mixins/__init__.py index feb6bc3466..ceb5de5885 100644 --- a/InvenTree/plugin/mixins/__init__.py +++ b/InvenTree/plugin/mixins/__init__.py @@ -1,6 +1,9 @@ """utility class to enable simpler imports""" -from ..builtin.integration.mixins import AppMixin, GlobalSettingsMixin, UrlsMixin, NavigationMixin +from ..builtin.integration.mixins import AppMixin, SettingsMixin, UrlsMixin, NavigationMixin __all__ = [ - 'AppMixin', 'GlobalSettingsMixin', 'UrlsMixin', 'NavigationMixin', + 'AppMixin', + 'NavigationMixin', + 'SettingsMixin', + 'UrlsMixin', ] diff --git a/InvenTree/plugin/samples/integration/sample.py b/InvenTree/plugin/samples/integration/sample.py index d7321f8a88..afc4a8fe8a 100644 --- a/InvenTree/plugin/samples/integration/sample.py +++ b/InvenTree/plugin/samples/integration/sample.py @@ -1,15 +1,18 @@ -"""sample implementations for IntegrationPlugin""" +""" +Sample implementations for IntegrationPlugin +""" + from plugin import IntegrationPluginBase -from plugin.mixins import AppMixin, GlobalSettingsMixin, UrlsMixin, NavigationMixin +from plugin.mixins import AppMixin, SettingsMixin, UrlsMixin, NavigationMixin from django.http import HttpResponse from django.utils.translation import ugettext_lazy as _ from django.conf.urls import url, include -class SampleIntegrationPlugin(AppMixin, GlobalSettingsMixin, UrlsMixin, NavigationMixin, IntegrationPluginBase): +class SampleIntegrationPlugin(AppMixin, SettingsMixin, UrlsMixin, NavigationMixin, IntegrationPluginBase): """ - An full integration plugin + A full integration plugin example """ PLUGIN_NAME = "SampleIntegrationPlugin" From 4b4d4be13ecbf57a526978b4f14230bb17052599 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 31 Dec 2021 14:28:16 +1100 Subject: [PATCH 25/67] Registry name fixes --- InvenTree/plugin/builtin/integration/mixins.py | 10 ++-------- InvenTree/plugin/registry.py | 2 +- InvenTree/plugin/test_integration.py | 10 +++++----- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 7ddfeeccb8..c7edc8ac36 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -17,14 +17,8 @@ class SettingsMixin: def __init__(self): super().__init__() - self.add_mixin('globalsettings', 'has_globalsettings', __class__) - self.globalsettings = self.setup_globalsettings() - - def setup_globalsettings(self): - """ - Setup global settings for this plugin - """ - return getattr(self, 'SETTINGS', None) + self.add_mixin('settings', 'has_globalsettings', __class__) + self.globalsettings = getattr(self, 'SETTINGS', None) @property def has_globalsettings(self): diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index 4fc5330f8b..d858d6c7f0 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -251,7 +251,7 @@ class Plugins: if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_GLOBALSETTING'): logger.info('Registering IntegrationPlugin global settings') for slug, plugin in plugins: - if plugin.mixin_enabled('globalsettings'): + if plugin.mixin_enabled('settings'): plugin_setting = plugin.globalsettingspatterns self.mixins_globalsettings[slug] = plugin_setting diff --git a/InvenTree/plugin/test_integration.py b/InvenTree/plugin/test_integration.py index fa585d0a40..c83be385a6 100644 --- a/InvenTree/plugin/test_integration.py +++ b/InvenTree/plugin/test_integration.py @@ -8,7 +8,7 @@ from django.contrib.auth import get_user_model from datetime import datetime from plugin import IntegrationPluginBase -from plugin.mixins import AppMixin, GlobalSettingsMixin, UrlsMixin, NavigationMixin +from plugin.mixins import AppMixin, SettingsMixin, UrlsMixin, NavigationMixin from plugin.urls import PLUGIN_BASE @@ -20,19 +20,19 @@ class BaseMixinDefinition: self.assertEqual(self.mixin.registered_mixins[0]['human_name'], self.MIXIN_HUMAN_NAME) -class GlobalSettingsMixinTest(BaseMixinDefinition, TestCase): +class SettingsMixinTest(BaseMixinDefinition, TestCase): MIXIN_HUMAN_NAME = 'Settings' - MIXIN_NAME = 'globalsettings' + MIXIN_NAME = 'settings' MIXIN_ENABLE_CHECK = 'has_globalsettings' TEST_SETTINGS = {'SETTING1': {'default': '123', }} def setUp(self): - class SettingsCls(GlobalSettingsMixin, IntegrationPluginBase): + class SettingsCls(SettingsMixin, IntegrationPluginBase): GLOBALSETTINGS = self.TEST_SETTINGS self.mixin = SettingsCls() - class NoSettingsCls(GlobalSettingsMixin, IntegrationPluginBase): + class NoSettingsCls(SettingsMixin, IntegrationPluginBase): pass self.mixin_nothing = NoSettingsCls() From 78120bb0207866fa4277866f8c179b20fc6c4697 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 31 Dec 2021 14:54:19 +1100 Subject: [PATCH 26/67] Fixes for unit tests --- InvenTree/plugin/test_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/plugin/test_integration.py b/InvenTree/plugin/test_integration.py index c83be385a6..1371535cfa 100644 --- a/InvenTree/plugin/test_integration.py +++ b/InvenTree/plugin/test_integration.py @@ -29,7 +29,7 @@ class SettingsMixinTest(BaseMixinDefinition, TestCase): def setUp(self): class SettingsCls(SettingsMixin, IntegrationPluginBase): - GLOBALSETTINGS = self.TEST_SETTINGS + SETTINGS = self.TEST_SETTINGS self.mixin = SettingsCls() class NoSettingsCls(SettingsMixin, IntegrationPluginBase): From 9b468ba92e8f67cf9da2c127248f0ac72258a3e3 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 31 Dec 2021 15:20:32 +1100 Subject: [PATCH 27/67] Second fix for the first fix --- InvenTree/plugin/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InvenTree/plugin/models.py b/InvenTree/plugin/models.py index 811ed5b431..93c6335497 100644 --- a/InvenTree/plugin/models.py +++ b/InvenTree/plugin/models.py @@ -55,9 +55,9 @@ class PluginConfig(models.Model): # extra attributes from the registry def mixins(self): - if self.plugin: + try: return self.plugin._mixinreg - else: + except (AttributeError, ValueError): return {} # functions From 553b998c9cfa2f962537653c1087a3ba3565dca2 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 31 Dec 2021 15:23:44 +1100 Subject: [PATCH 28/67] CSS fixes --- InvenTree/templates/InvenTree/settings/mixins/settings.html | 5 ++++- InvenTree/templates/InvenTree/settings/mixins/urls.html | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/InvenTree/templates/InvenTree/settings/mixins/settings.html b/InvenTree/templates/InvenTree/settings/mixins/settings.html index 3c87da8678..910d4bbfbb 100644 --- a/InvenTree/templates/InvenTree/settings/mixins/settings.html +++ b/InvenTree/templates/InvenTree/settings/mixins/settings.html @@ -1,7 +1,10 @@ {% load i18n %} {% load plugin_extras %} -

{% trans "Settings" %}

+
+

{% trans "Settings" %}

+
+ {% plugin_globalsettings plugin_key as plugin_settings %} diff --git a/InvenTree/templates/InvenTree/settings/mixins/urls.html b/InvenTree/templates/InvenTree/settings/mixins/urls.html index 4bebfbce89..0a7b029762 100644 --- a/InvenTree/templates/InvenTree/settings/mixins/urls.html +++ b/InvenTree/templates/InvenTree/settings/mixins/urls.html @@ -1,7 +1,9 @@ {% load i18n %} {% load inventree_extras %} -

{% trans "URLs" %}

+
+

{% trans "URLs" %}

+
{% define plugin.base_url as base %}

{% blocktrans %}The Base-URL for this plugin is {{ base }}.{% endblocktrans %}

From 182849e16087773177424651eb110556e62a919f Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 31 Dec 2021 15:24:56 +1100 Subject: [PATCH 29/67] Fix for settings template --- InvenTree/templates/InvenTree/settings/plugin_settings.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InvenTree/templates/InvenTree/settings/plugin_settings.html b/InvenTree/templates/InvenTree/settings/plugin_settings.html index f8ab02de3e..59178300ac 100644 --- a/InvenTree/templates/InvenTree/settings/plugin_settings.html +++ b/InvenTree/templates/InvenTree/settings/plugin_settings.html @@ -127,8 +127,8 @@ -{% mixin_enabled plugin 'globalsettings' as globalsettings %} -{% if globalsettings %} +{% mixin_enabled plugin 'settings' as settings %} +{% if settings %} {% include 'InvenTree/settings/mixins/settings.html' %} {% endif %} From 547db3322fb3f67e3c6f9fbef329c7c6bd73501d Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 1 Jan 2022 22:00:43 +1100 Subject: [PATCH 30/67] Adds new "PluginSetting" class - Adds settings which are unique to a particular plugin --- InvenTree/common/models.py | 168 ++++++++++++++++++------------------- InvenTree/plugin/admin.py | 12 ++- InvenTree/plugin/models.py | 52 ++++++++++-- 3 files changed, 136 insertions(+), 96 deletions(-) diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index c514d7c4a9..0babfaa8e3 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -65,13 +65,13 @@ class BaseInvenTreeSetting(models.Model): self.key = str(self.key).upper() - self.clean() + self.clean(**kwargs) self.validate_unique() super().save() @classmethod - def allValues(cls, user=None, exclude_hidden=False): + def allValues(cls, user=None, plugin=None, exclude_hidden=False): """ Return a dict of "all" defined global settings. @@ -82,9 +82,14 @@ class BaseInvenTreeSetting(models.Model): results = cls.objects.all() + # Optionally filter by user if user is not None: results = results.filter(user=user) + # Optionally filter by plugin + if plugin is not None: + results = results.filter(plugin=plugin) + # Query the database settings = {} @@ -123,98 +128,92 @@ class BaseInvenTreeSetting(models.Model): return settings @classmethod - def get_setting_name(cls, key): + def get_setting_definition(cls, key, **kwargs): + """ + Return the 'definition' of a particular settings value, as a dict object. + + - The 'settings' dict can be passed as a kwarg + - If not passed, look for cls.GLOBAL_SETTINGS + - Returns an empty dict if the key is not found + """ + + settings = kwargs.get('settings', cls.GLOBAL_SETTINGS) + + key = str(key).strip().upper() + + if settings is not None and key in settings: + return settings[key] + else: + return {} + + @classmethod + def get_setting_name(cls, key, **kwargs): """ Return the name of a particular setting. If it does not exist, return an empty string. """ - key = str(key).strip().upper() - - if key in cls.GLOBAL_SETTINGS: - setting = cls.GLOBAL_SETTINGS[key] - return setting.get('name', '') - else: - return '' + setting = cls.get_setting_definition(key, **kwargs) + return setting.get('name', '') @classmethod - def get_setting_description(cls, key): + def get_setting_description(cls, key, **kwargs): """ Return the description for a particular setting. If it does not exist, return an empty string. """ - key = str(key).strip().upper() + setting = cls.get_setting_definition(key, **kwargs) - if key in cls.GLOBAL_SETTINGS: - setting = cls.GLOBAL_SETTINGS[key] - return setting.get('description', '') - else: - return '' + return setting.get('description', '') @classmethod - def get_setting_units(cls, key): + def get_setting_units(cls, key, **kwargs): """ Return the units for a particular setting. If it does not exist, return an empty string. """ - key = str(key).strip().upper() + setting = cls.get_setting_definition(key, **kwargs) - if key in cls.GLOBAL_SETTINGS: - setting = cls.GLOBAL_SETTINGS[key] - return setting.get('units', '') - else: - return '' + return setting.get('units', '') @classmethod - def get_setting_validator(cls, key): + def get_setting_validator(cls, key, **kwargs): """ Return the validator for a particular setting. If it does not exist, return None """ - key = str(key).strip().upper() + setting = cls.get_setting_definition(key, **kwargs) - if key in cls.GLOBAL_SETTINGS: - setting = cls.GLOBAL_SETTINGS[key] - return setting.get('validator', None) - else: - return None + return setting.get('validator', None) @classmethod - def get_setting_default(cls, key): + def get_setting_default(cls, key, **kwargs): """ Return the default value for a particular setting. If it does not exist, return an empty string """ - key = str(key).strip().upper() + setting = cls.get_setting_definition(key, **kwargs) - if key in cls.GLOBAL_SETTINGS: - setting = cls.GLOBAL_SETTINGS[key] - return setting.get('default', '') - else: - return '' + return setting.get('default', '') @classmethod - def get_setting_choices(cls, key): + def get_setting_choices(cls, key, **kwargs): """ Return the validator choices available for a particular setting. """ - key = str(key).strip().upper() + setting = cls.get_setting_definition(key, **kwargs) - if key in cls.GLOBAL_SETTINGS: - setting = cls.GLOBAL_SETTINGS[key] - choices = setting.get('choices', None) - else: - choices = None + choices = setting.get('choices', None) if callable(choices): # Evaluate the function (we expect it will return a list of tuples...) @@ -237,8 +236,20 @@ class BaseInvenTreeSetting(models.Model): key = str(key).strip().upper() + settings = cls.objects.all() + + user = kwargs.get('user', None) + + if user is not None: + settings = settings.filter(user=user) + + plugin = kwargs.get('plugin', None) + + if plugin is not None: + settings = settings.filter(plugin=plugin) + try: - setting = cls.objects.filter(**cls.get_filters(key, **kwargs)).first() + setting = settings.filter(**cls.get_filters(key, **kwargs)).first() except (ValueError, cls.DoesNotExist): setting = None except (IntegrityError, OperationalError): @@ -247,7 +258,12 @@ class BaseInvenTreeSetting(models.Model): # Setting does not exist! (Try to create it) if not setting: - setting = cls(key=key, value=cls.get_setting_default(key), **kwargs) + # Attempt to create a new settings object + setting = cls( + key=key, + value=cls.get_setting_default(key, **kwargs), + **kwargs + ) try: # Wrap this statement in "atomic", so it can be rolled back if it fails @@ -259,21 +275,6 @@ class BaseInvenTreeSetting(models.Model): return setting - @classmethod - def get_setting_pk(cls, key): - """ - Return the primary-key value for a given setting. - - If the setting does not exist, return None - """ - - setting = cls.get_setting_object(cls) - - if setting: - return setting.pk - else: - return None - @classmethod def get_setting(cls, key, backup_value=None, **kwargs): """ @@ -283,18 +284,19 @@ class BaseInvenTreeSetting(models.Model): # If no backup value is specified, atttempt to retrieve a "default" value if backup_value is None: - backup_value = cls.get_setting_default(key) + backup_value = cls.get_setting_default(key, **kwargs) setting = cls.get_setting_object(key, **kwargs) if setting: value = setting.value - # If the particular setting is defined as a boolean, cast the value to a boolean - if setting.is_bool(): + # Cast to boolean if necessary + if setting.is_bool(**kwargs): value = InvenTree.helpers.str2bool(value) - if setting.is_int(): + # Cast to integer if necessary + if setting.is_int(**kwargs): try: value = int(value) except (ValueError, TypeError): @@ -357,7 +359,7 @@ class BaseInvenTreeSetting(models.Model): def units(self): return self.__class__.get_setting_units(self.key) - def clean(self): + def clean(self, **kwargs): """ If a validator (or multiple validators) are defined for a particular setting key, run them against the 'value' field. @@ -365,7 +367,7 @@ class BaseInvenTreeSetting(models.Model): super().clean() - validator = self.__class__.get_setting_validator(self.key) + validator = self.__class__.get_setting_validator(self.key, **kwargs) if self.is_bool(): self.value = InvenTree.helpers.str2bool(self.value) @@ -459,12 +461,12 @@ class BaseInvenTreeSetting(models.Model): return [opt[0] for opt in choices] - def is_bool(self): + def is_bool(self, **kwargs): """ Check if this setting is required to be a boolean value """ - validator = self.__class__.get_setting_validator(self.key) + validator = self.__class__.get_setting_validator(self.key, **kwargs) return self.__class__.validator_is_bool(validator) @@ -477,15 +479,15 @@ class BaseInvenTreeSetting(models.Model): return InvenTree.helpers.str2bool(self.value) - def setting_type(self): + def setting_type(self, **kwargs): """ Return the field type identifier for this setting object """ - if self.is_bool(): + if self.is_bool(**kwargs): return 'boolean' - elif self.is_int(): + elif self.is_int(**kwargs): return 'integer' else: @@ -504,12 +506,12 @@ class BaseInvenTreeSetting(models.Model): return False - def is_int(self): + def is_int(self, **kwargs): """ Check if the setting is required to be an integer value: """ - validator = self.__class__.get_setting_validator(self.key) + validator = self.__class__.get_setting_validator(self.key, **kwargs) return self.__class__.validator_is_int(validator) @@ -541,17 +543,14 @@ class BaseInvenTreeSetting(models.Model): return value @classmethod - def is_protected(cls, key): + def is_protected(cls, key, **kwargs): """ Check if the setting value is protected """ - key = str(key).strip().upper() + setting = cls.get_setting_definition(key, **kwargs) - if key in cls.GLOBAL_SETTINGS: - return cls.GLOBAL_SETTINGS[key].get('protected', False) - else: - return False + return setting.get('protected', False) def settings_group_options(): @@ -977,13 +976,6 @@ class InvenTreeSetting(BaseInvenTreeSetting): 'validator': bool, 'requires_restart': True, }, - 'ENABLE_PLUGINS_GLOBALSETTING': { - 'name': _('Enable global setting integration'), - 'description': _('Enable plugins to integrate into inventree global settings'), - 'default': False, - 'validator': bool, - 'requires_restart': True, - }, 'ENABLE_PLUGINS_APP': { 'name': _('Enable app integration'), 'description': _('Enable plugins to add apps'), diff --git a/InvenTree/plugin/admin.py b/InvenTree/plugin/admin.py index 3a96a4b9ea..4bd4664212 100644 --- a/InvenTree/plugin/admin.py +++ b/InvenTree/plugin/admin.py @@ -35,12 +35,20 @@ def plugin_deactivate(modeladmin, request, queryset): plugin_update(queryset, False) +class PluginSettingInline(admin.TabularInline): + """ + Inline admin class for PluginSetting + """ + + model = models.PluginSetting + + class PluginConfigAdmin(admin.ModelAdmin): """Custom admin with restricted id fields""" readonly_fields = ["key", "name", ] - list_display = ['active', '__str__', 'key', 'name', ] + list_display = ['name', 'key', '__str__', 'active', ] list_filter = ['active'] actions = [plugin_activate, plugin_deactivate, ] - + inlines = [PluginSettingInline,] admin.site.register(models.PluginConfig, PluginConfigAdmin) diff --git a/InvenTree/plugin/models.py b/InvenTree/plugin/models.py index 93c6335497..b001798544 100644 --- a/InvenTree/plugin/models.py +++ b/InvenTree/plugin/models.py @@ -8,16 +8,17 @@ from __future__ import unicode_literals from django.utils.translation import gettext_lazy as _ from django.db import models +import common.models + from plugin import plugin_reg class PluginConfig(models.Model): - """ A PluginConfig object holds settings for plugins. - - It is used to designate a Part as 'subscribed' for a given User. + """ + A PluginConfig object holds settings for plugins. Attributes: - key: slug of the plugin - must be unique + key: slug of the plugin (this must be unique across all installed plugins!) name: PluginName of the plugin - serves for a manual double check if the right plugin is used active: Should the plugin be loaded? """ @@ -63,7 +64,10 @@ class PluginConfig(models.Model): # functions def __init__(self, *args, **kwargs): - """override to set original state of""" + """ + Override to set original state of the plugin-config instance + """ + super().__init__(*args, **kwargs) self.__org_active = self.active @@ -82,7 +86,9 @@ class PluginConfig(models.Model): } def save(self, force_insert=False, force_update=False, *args, **kwargs): - """extend save method to reload plugins if the 'active' status changes""" + """ + Extend save method to reload plugins if the 'active' status changes + """ reload = kwargs.pop('no_reload', False) # check if no_reload flag is set ret = super().save(force_insert, force_update, *args, **kwargs) @@ -95,3 +101,37 @@ class PluginConfig(models.Model): plugin_reg.reload_plugins() return ret + + +class PluginSetting(common.models.BaseInvenTreeSetting): + """ + This model represents settings for individual plugins + """ + + class Meta: + unique_together = [ + ('plugin', 'key'), + ] + + @classmethod + def get_filters(cls, key, **kwargs): + """ + Override filters method to ensure settings are filtered by plugin id + """ + + filters = super().get_filters(key, **kwargs) + + plugin = kwargs.get('plugin', None) + + if plugin: + filters['plugin'] = plugin + + return filters + + plugin = models.ForeignKey( + PluginConfig, + related_name='settings', + null=False, + verbose_name=_('Plugin'), + on_delete=models.CASCADE, + ) From 7f08c75a08047ccb8a3edbcbe9b06a86f3046d4f Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 1 Jan 2022 22:00:58 +1100 Subject: [PATCH 31/67] Add missing migration file --- .../plugin/migrations/0003_pluginsetting.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 InvenTree/plugin/migrations/0003_pluginsetting.py diff --git a/InvenTree/plugin/migrations/0003_pluginsetting.py b/InvenTree/plugin/migrations/0003_pluginsetting.py new file mode 100644 index 0000000000..83e744fa6b --- /dev/null +++ b/InvenTree/plugin/migrations/0003_pluginsetting.py @@ -0,0 +1,26 @@ +# Generated by Django 3.2.10 on 2022-01-01 10:52 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('plugin', '0002_alter_pluginconfig_options'), + ] + + operations = [ + migrations.CreateModel( + name='PluginSetting', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.CharField(help_text='Settings key (must be unique - case insensitive', max_length=50)), + ('value', models.CharField(blank=True, help_text='Settings value', max_length=200)), + ('plugin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='settings', to='plugin.pluginconfig', verbose_name='Plugin')), + ], + options={ + 'unique_together': {('plugin', 'key')}, + }, + ), + ] From 7cb029e7c39773b6567ad9437ff73fc1d04fb6ee Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 1 Jan 2022 22:20:21 +1100 Subject: [PATCH 32/67] Refactor: Rename "GLOBAL_SETTINGS" to "SETTINGS" --- .../management/commands/clean_settings.py | 17 +++++++++++------ InvenTree/common/models.py | 16 ++++++++-------- InvenTree/common/tests.py | 8 ++++---- InvenTree/plugin/admin.py | 5 +++-- InvenTree/plugin/registry.py | 4 ++-- InvenTree/users/models.py | 3 ++- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/InvenTree/InvenTree/management/commands/clean_settings.py b/InvenTree/InvenTree/management/commands/clean_settings.py index e0fd09e6c7..283416de29 100644 --- a/InvenTree/InvenTree/management/commands/clean_settings.py +++ b/InvenTree/InvenTree/management/commands/clean_settings.py @@ -2,9 +2,14 @@ Custom management command to cleanup old settings that are not defined anymore """ +import logging + from django.core.management.base import BaseCommand +logger = logging.getLogger('inventree') + + class Command(BaseCommand): """ Cleanup old (undefined) settings in the database @@ -12,27 +17,27 @@ class Command(BaseCommand): def handle(self, *args, **kwargs): - print("Collecting settings") + logger.info("Collecting settings") from common.models import InvenTreeSetting, InvenTreeUserSetting # general settings db_settings = InvenTreeSetting.objects.all() - model_settings = InvenTreeSetting.GLOBAL_SETTINGS + model_settings = InvenTreeSetting.SETTINGS # check if key exist and delete if not for setting in db_settings: if setting.key not in model_settings: setting.delete() - print(f"deleted setting '{setting.key}'") + logger.info(f"deleted setting '{setting.key}'") # user settings db_settings = InvenTreeUserSetting.objects.all() - model_settings = InvenTreeUserSetting.GLOBAL_SETTINGS + model_settings = InvenTreeUserSetting.SETTINGS # check if key exist and delete if not for setting in db_settings: if setting.key not in model_settings: setting.delete() - print(f"deleted user setting '{setting.key}'") + logger.info(f"deleted user setting '{setting.key}'") - print("checked all settings") + logger.info("checked all settings") diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 0babfaa8e3..ecddd17de8 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -53,7 +53,7 @@ class BaseInvenTreeSetting(models.Model): single values (e.g. one-off settings values). """ - GLOBAL_SETTINGS = {} + SETTINGS = {} class Meta: abstract = True @@ -98,13 +98,13 @@ class BaseInvenTreeSetting(models.Model): settings[setting.key.upper()] = setting.value # Specify any "default" values which are not in the database - for key in cls.GLOBAL_SETTINGS.keys(): + for key in cls.SETTINGS.keys(): if key.upper() not in settings: settings[key.upper()] = cls.get_setting_default(key) if exclude_hidden: - hidden = cls.GLOBAL_SETTINGS[key].get('hidden', False) + hidden = cls.SETTINGS[key].get('hidden', False) if hidden: # Remove hidden items @@ -133,11 +133,11 @@ class BaseInvenTreeSetting(models.Model): Return the 'definition' of a particular settings value, as a dict object. - The 'settings' dict can be passed as a kwarg - - If not passed, look for cls.GLOBAL_SETTINGS + - If not passed, look for cls.SETTINGS - Returns an empty dict if the key is not found """ - settings = kwargs.get('settings', cls.GLOBAL_SETTINGS) + settings = kwargs.get('settings', cls.SETTINGS) key = str(key).strip().upper() @@ -594,7 +594,7 @@ class InvenTreeSetting(BaseInvenTreeSetting): The keys must be upper-case """ - GLOBAL_SETTINGS = { + SETTINGS = { 'SERVER_RESTART_REQUIRED': { 'name': _('Restart required'), @@ -1009,7 +1009,7 @@ class InvenTreeSetting(BaseInvenTreeSetting): Return True if this setting requires a server restart after changing """ - options = InvenTreeSetting.GLOBAL_SETTINGS.get(self.key, None) + options = InvenTreeSetting.SETTINGS.get(self.key, None) if options: return options.get('requires_restart', False) @@ -1022,7 +1022,7 @@ class InvenTreeUserSetting(BaseInvenTreeSetting): An InvenTreeSetting object with a usercontext """ - GLOBAL_SETTINGS = { + SETTINGS = { 'HOMEPAGE_PART_STARRED': { 'name': _('Show subscribed parts'), 'description': _('Show subscribed parts on the homepage'), diff --git a/InvenTree/common/tests.py b/InvenTree/common/tests.py index c20dc5d126..8bd5b6ffba 100644 --- a/InvenTree/common/tests.py +++ b/InvenTree/common/tests.py @@ -49,9 +49,9 @@ class SettingsTest(TestCase): - Ensure that every global setting has a description. """ - for key in InvenTreeSetting.GLOBAL_SETTINGS.keys(): + for key in InvenTreeSetting.SETTINGS.keys(): - setting = InvenTreeSetting.GLOBAL_SETTINGS[key] + setting = InvenTreeSetting.SETTINGS[key] name = setting.get('name', None) @@ -64,14 +64,14 @@ class SettingsTest(TestCase): raise ValueError(f'Missing GLOBAL_SETTING description for {key}') if not key == key.upper(): - raise ValueError(f"GLOBAL_SETTINGS key '{key}' is not uppercase") + raise ValueError(f"SETTINGS key '{key}' is not uppercase") def test_defaults(self): """ Populate the settings with default values """ - for key in InvenTreeSetting.GLOBAL_SETTINGS.keys(): + for key in InvenTreeSetting.SETTINGS.keys(): value = InvenTreeSetting.get_setting_default(key) diff --git a/InvenTree/plugin/admin.py b/InvenTree/plugin/admin.py index 4bd4664212..839dac305a 100644 --- a/InvenTree/plugin/admin.py +++ b/InvenTree/plugin/admin.py @@ -40,7 +40,7 @@ class PluginSettingInline(admin.TabularInline): Inline admin class for PluginSetting """ - model = models.PluginSetting + model = models.PluginSetting class PluginConfigAdmin(admin.ModelAdmin): @@ -49,6 +49,7 @@ class PluginConfigAdmin(admin.ModelAdmin): list_display = ['name', 'key', '__str__', 'active', ] list_filter = ['active'] actions = [plugin_activate, plugin_deactivate, ] - inlines = [PluginSettingInline,] + inlines = [PluginSettingInline, ] + admin.site.register(models.PluginConfig, PluginConfigAdmin) diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index d858d6c7f0..79892616c4 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -256,7 +256,7 @@ class Plugins: self.mixins_globalsettings[slug] = plugin_setting # Add to settings dir - InvenTreeSetting.GLOBAL_SETTINGS.update(plugin_setting) + InvenTreeSetting.SETTINGS.update(plugin_setting) def deactivate_integration_globalsettings(self): from common.models import InvenTreeSetting @@ -268,7 +268,7 @@ class Plugins: # remove settings for setting in plugin_settings: - InvenTreeSetting.GLOBAL_SETTINGS.pop(setting) + InvenTreeSetting.SETTINGS.pop(setting) # clear cache self.mixins_globalsettings = {} diff --git a/InvenTree/users/models.py b/InvenTree/users/models.py index 5f2109da82..490f87f75a 100644 --- a/InvenTree/users/models.py +++ b/InvenTree/users/models.py @@ -76,7 +76,8 @@ class RuleSet(models.Model): 'otp_totp_totpdevice', 'otp_static_statictoken', 'otp_static_staticdevice', - 'plugin_pluginconfig' + 'plugin_pluginconfig', + 'plugin_pluginsetting', ], 'part_category': [ 'part_partcategory', From 737467a1fdd79c9f16b6ba00c30415e44dc8d0ac Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 1 Jan 2022 23:14:34 +1100 Subject: [PATCH 33/67] Rename "has_globalsettings" -> "has_settings" --- InvenTree/plugin/builtin/integration/mixins.py | 6 +++--- InvenTree/plugin/test_integration.py | 12 +++--------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index c7edc8ac36..c3437b7f8d 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -17,11 +17,11 @@ class SettingsMixin: def __init__(self): super().__init__() - self.add_mixin('settings', 'has_globalsettings', __class__) + self.add_mixin('settings', 'has_settings', __class__) self.globalsettings = getattr(self, 'SETTINGS', None) @property - def has_globalsettings(self): + def has_settings(self): """ Does this plugin use custom global settings """ @@ -32,7 +32,7 @@ class SettingsMixin: """ Get patterns for InvenTreeSetting defintion """ - if self.has_globalsettings: + if self.has_settings: return {f'PLUGIN_{self.slug.upper()}_{key}': value for key, value in self.globalsettings.items()} return None diff --git a/InvenTree/plugin/test_integration.py b/InvenTree/plugin/test_integration.py index 1371535cfa..5cf00f7c86 100644 --- a/InvenTree/plugin/test_integration.py +++ b/InvenTree/plugin/test_integration.py @@ -23,7 +23,7 @@ class BaseMixinDefinition: class SettingsMixinTest(BaseMixinDefinition, TestCase): MIXIN_HUMAN_NAME = 'Settings' MIXIN_NAME = 'settings' - MIXIN_ENABLE_CHECK = 'has_globalsettings' + MIXIN_ENABLE_CHECK = 'has_settings' TEST_SETTINGS = {'SETTING1': {'default': '123', }} @@ -44,21 +44,15 @@ class SettingsMixinTest(BaseMixinDefinition, TestCase): # settings variable self.assertEqual(self.mixin.globalsettings, self.TEST_SETTINGS) - # settings pattern - target_pattern = {f'PLUGIN_{self.mixin.slug.upper()}_{key}': value for key, value in self.mixin.globalsettings.items()} - self.assertEqual(self.mixin.globalsettingspatterns, target_pattern) - - # no settings - self.assertIsNone(self.mixin_nothing.globalsettings) - self.assertIsNone(self.mixin_nothing.globalsettingspatterns) - # calling settings # not existing self.assertEqual(self.mixin.get_globalsetting('ABCD'), '') self.assertEqual(self.mixin_nothing.get_globalsetting('ABCD'), '') + # right setting self.mixin.set_globalsetting('SETTING1', '12345', self.test_user) self.assertEqual(self.mixin.get_globalsetting('SETTING1'), '12345') + # no setting self.assertEqual(self.mixin_nothing.get_globalsetting(''), '') From f3bfe6e7ca1c61e9971519540722d51fd81f60e6 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 2 Jan 2022 11:21:06 +1100 Subject: [PATCH 34/67] More refactoring: - Rename "mixins_globalsettings" to "mixing_settings" - Fix translation on settings page template --- InvenTree/plugin/admin.py | 12 +++-- .../plugin/builtin/integration/mixins.py | 53 +++++++++++-------- InvenTree/plugin/integration.py | 8 +-- InvenTree/plugin/plugin.py | 24 ++++++++- InvenTree/plugin/registry.py | 10 ++-- .../plugin/samples/integration/sample.py | 9 ++++ .../plugin/templatetags/plugin_extras.py | 6 +-- InvenTree/plugin/test_integration.py | 10 ++-- InvenTree/plugin/test_plugin.py | 6 +-- .../InvenTree/settings/mixins/settings.html | 2 +- .../templates/InvenTree/settings/setting.html | 4 +- 11 files changed, 91 insertions(+), 53 deletions(-) diff --git a/InvenTree/plugin/admin.py b/InvenTree/plugin/admin.py index 839dac305a..f13444f274 100644 --- a/InvenTree/plugin/admin.py +++ b/InvenTree/plugin/admin.py @@ -4,8 +4,7 @@ from __future__ import unicode_literals from django.contrib import admin import plugin.models as models -from plugin import plugin_reg - +import plugin.registry as registry def plugin_update(queryset, new_status: bool): """general function for bulk changing plugins""" @@ -20,7 +19,7 @@ def plugin_update(queryset, new_status: bool): # reload plugins if they changed if apps_changed: - plugin_reg.reload_plugins() + registry.plugin_registry.reload_plugins() @admin.action(description='Activate plugin(s)') @@ -42,6 +41,13 @@ class PluginSettingInline(admin.TabularInline): model = models.PluginSetting + read_only_fields = [ + 'key', + ] + + def has_add_permission(self, request, obj): + return False + class PluginConfigAdmin(admin.ModelAdmin): """Custom admin with restricted id fields""" diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index c3437b7f8d..47e9ff630d 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -3,7 +3,9 @@ Plugin mixin classes """ from django.conf.urls import url, include +from django.db.utils import OperationalError, ProgrammingError +from plugin.models import PluginConfig, PluginSetting from plugin.urls import PLUGIN_BASE @@ -18,43 +20,48 @@ class SettingsMixin: def __init__(self): super().__init__() self.add_mixin('settings', 'has_settings', __class__) - self.globalsettings = getattr(self, 'SETTINGS', None) + self.settings = getattr(self, 'SETTINGS', {}) @property def has_settings(self): """ Does this plugin use custom global settings """ - return bool(self.globalsettings) + return bool(self.settings) - @property - def globalsettingspatterns(self): + def get_setting(self, key): """ - Get patterns for InvenTreeSetting defintion + Return the 'value' of the setting associated with this plugin """ - if self.has_settings: - return {f'PLUGIN_{self.slug.upper()}_{key}': value for key, value in self.globalsettings.items()} - return None - def _globalsetting_name(self, key): - """ - Get global name of setting - """ - return f'PLUGIN_{self.slug.upper()}_{key}' + # Find the plugin configuration associated with this plugin - def get_globalsetting(self, key): - """ - get plugin global setting by key - """ - from common.models import InvenTreeSetting - return InvenTreeSetting.get_setting(self._globalsetting_name(key)) + try: + plugin, _ = PluginConfig.objects.get_or_create(key=self.plugin_slug(), name=self.plugin_name()) + except (OperationalError, ProgrammingError) as error: + plugin = None + + if not plugin: + # Plugin cannot be found, return default value + return PluginSetting.get_setting_default(key, settings=self.settings) - def set_globalsetting(self, key, value, user): + return PluginSetting.get_setting(key, plugin=plugin, settings=self.settings) + + def set_setting(self, key, value, user): """ - set plugin global setting by key + Set plugin setting value by key """ - from common.models import InvenTreeSetting - return InvenTreeSetting.set_setting(self._globalsetting_name(key), value, user) + + try: + plugin, _ = PluginConfig.objects.get_or_create(key=self.plugin_slug(), name=self.plugin_name()) + except (OperationalError, ProgrammingError) as error: + plugin = None + + if not plugin: + # Cannot find associated plugin model, return + return + + PluginSetting.set_setting(key, value, user, plugin=plugin, settings=self.settings) class UrlsMixin: diff --git a/InvenTree/plugin/integration.py b/InvenTree/plugin/integration.py index 3cd8ae86d2..d66ab79c26 100644 --- a/InvenTree/plugin/integration.py +++ b/InvenTree/plugin/integration.py @@ -59,8 +59,6 @@ class IntegrationPluginBase(MixinBase, plugin.InvenTreePlugin): """ The IntegrationPluginBase class is used to integrate with 3rd party software """ - PLUGIN_SLUG = None - PLUGIN_TITLE = None AUTHOR = None DESCRIPTION = None @@ -84,11 +82,7 @@ class IntegrationPluginBase(MixinBase, plugin.InvenTreePlugin): # region properties @property def slug(self): - """slug for the plugin""" - slug = getattr(self, 'PLUGIN_SLUG', None) - if not slug: - slug = self.plugin_name() - return slugify(slug) + return self.plugin_slug() @property def human_name(self): diff --git a/InvenTree/plugin/plugin.py b/InvenTree/plugin/plugin.py index 93199df7b7..dbafda0aea 100644 --- a/InvenTree/plugin/plugin.py +++ b/InvenTree/plugin/plugin.py @@ -2,6 +2,9 @@ """Base Class for InvenTree plugins""" +from django.utils.text import slugify + + class InvenTreePlugin(): """ Base class for a plugin @@ -10,9 +13,28 @@ class InvenTreePlugin(): # Override the plugin name for each concrete plugin instance PLUGIN_NAME = '' + PLUGIN_SLUG = '' + + PLUGIN_TITLE = '' + def plugin_name(self): - """get plugin name""" + """ + Return the name of this plugin plugin + """ return self.PLUGIN_NAME + def plugin_slug(self): + + slug = getattr(self, 'PLUGIN_SLUG', None) + + if slug is None: + slug = self.plugin_name() + + return slugify(slug) + + def plugin_title(self): + + return self.PLUGIN_TITLE + def __init__(self): pass diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index 79892616c4..e0b25ecc65 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -50,7 +50,7 @@ class Plugins: # integration specific self.installed_apps = [] # Holds all added plugin_paths # mixins - self.mixins_globalsettings = {} + self.mixins_settings = {} # region public plugin functions def load_plugins(self): @@ -252,8 +252,8 @@ class Plugins: logger.info('Registering IntegrationPlugin global settings') for slug, plugin in plugins: if plugin.mixin_enabled('settings'): - plugin_setting = plugin.globalsettingspatterns - self.mixins_globalsettings[slug] = plugin_setting + plugin_setting = plugin.settings + self.mixins_settings[slug] = plugin_setting # Add to settings dir InvenTreeSetting.SETTINGS.update(plugin_setting) @@ -263,7 +263,7 @@ class Plugins: # collect all settings plugin_settings = {} - for _, plugin_setting in self.mixins_globalsettings.items(): + for _, plugin_setting in self.mixins_settings.items(): plugin_settings.update(plugin_setting) # remove settings @@ -271,7 +271,7 @@ class Plugins: InvenTreeSetting.SETTINGS.pop(setting) # clear cache - self.mixins_globalsettings = {} + self.mixins_Fsettings = {} # endregion # region integration_app diff --git a/InvenTree/plugin/samples/integration/sample.py b/InvenTree/plugin/samples/integration/sample.py index afc4a8fe8a..682726718f 100644 --- a/InvenTree/plugin/samples/integration/sample.py +++ b/InvenTree/plugin/samples/integration/sample.py @@ -44,6 +44,15 @@ class SampleIntegrationPlugin(AppMixin, SettingsMixin, UrlsMixin, NavigationMixi 'default': True, 'validator': bool, }, + 'API_KEY': { + 'name': _('API Key'), + 'description': _('Key required for accessing external API'), + }, + 'NUMERICAL_SETTING': { + 'name': _('Numerical'), + 'description': _('A numerical setting'), + 'validator': int, + }, } NAVIGATION = [ diff --git a/InvenTree/plugin/templatetags/plugin_extras.py b/InvenTree/plugin/templatetags/plugin_extras.py index 1b4b269844..b7f4f6b6c1 100644 --- a/InvenTree/plugin/templatetags/plugin_extras.py +++ b/InvenTree/plugin/templatetags/plugin_extras.py @@ -26,9 +26,9 @@ def inactive_plugin_list(*args, **kwargs): @register.simple_tag() -def plugin_globalsettings(plugin, *args, **kwargs): - """ Return a list of all global settings for a plugin """ - return plugin_reg.mixins_globalsettings.get(plugin) +def plugin_settings(plugin, *args, **kwargs): + """ Return a list of all custom settings for a plugin """ + return plugin_reg.mixins_settings.get(plugin) @register.simple_tag() diff --git a/InvenTree/plugin/test_integration.py b/InvenTree/plugin/test_integration.py index 5cf00f7c86..f88994384a 100644 --- a/InvenTree/plugin/test_integration.py +++ b/InvenTree/plugin/test_integration.py @@ -46,15 +46,15 @@ class SettingsMixinTest(BaseMixinDefinition, TestCase): # calling settings # not existing - self.assertEqual(self.mixin.get_globalsetting('ABCD'), '') - self.assertEqual(self.mixin_nothing.get_globalsetting('ABCD'), '') + self.assertEqual(self.mixin.get_setting('ABCD'), '') + self.assertEqual(self.mixin_nothing.get_setting('ABCD'), '') # right setting - self.mixin.set_globalsetting('SETTING1', '12345', self.test_user) - self.assertEqual(self.mixin.get_globalsetting('SETTING1'), '12345') + self.mixin.set_setting('SETTING1', '12345', self.test_user) + self.assertEqual(self.mixin.get_setting('SETTING1'), '12345') # no setting - self.assertEqual(self.mixin_nothing.get_globalsetting(''), '') + self.assertEqual(self.mixin_nothing.get_setting(''), '') class UrlsMixinTest(BaseMixinDefinition, TestCase): diff --git a/InvenTree/plugin/test_plugin.py b/InvenTree/plugin/test_plugin.py index 3e0a1967db..b4e2fdaf6f 100644 --- a/InvenTree/plugin/test_plugin.py +++ b/InvenTree/plugin/test_plugin.py @@ -63,11 +63,11 @@ class PluginTagTests(TestCase): """test that all inactive plugins are listed""" self.assertEqual(plugin_tags.inactive_plugin_list(), plugin_reg.plugins_inactive) - def test_tag_plugin_globalsettings(self): + def test_tag_plugin_settings(self): """check all plugins are listed""" self.assertEqual( - plugin_tags.plugin_globalsettings(self.sample), - plugin_reg.mixins_globalsettings.get(self.sample) + plugin_tags.plugin_settings(self.sample), + plugin_reg.mixins_settings.get(self.sample) ) def test_tag_mixin_enabled(self): diff --git a/InvenTree/templates/InvenTree/settings/mixins/settings.html b/InvenTree/templates/InvenTree/settings/mixins/settings.html index 910d4bbfbb..cb136b5c4f 100644 --- a/InvenTree/templates/InvenTree/settings/mixins/settings.html +++ b/InvenTree/templates/InvenTree/settings/mixins/settings.html @@ -5,7 +5,7 @@

{% trans "Settings" %}

-{% plugin_globalsettings plugin_key as plugin_settings %} +{% plugin_settings plugin_key as plugin_settings %}
diff --git a/InvenTree/templates/InvenTree/settings/setting.html b/InvenTree/templates/InvenTree/settings/setting.html index 7419b7ff34..96a8993798 100644 --- a/InvenTree/templates/InvenTree/settings/setting.html +++ b/InvenTree/templates/InvenTree/settings/setting.html @@ -13,7 +13,7 @@ {% endif %} - + diff --git a/InvenTree/templates/js/dynamic/settings.js b/InvenTree/templates/js/dynamic/settings.js index e19bba6501..133edfba20 100644 --- a/InvenTree/templates/js/dynamic/settings.js +++ b/InvenTree/templates/js/dynamic/settings.js @@ -28,9 +28,13 @@ function editSetting(pk, options={}) { // Is this a global setting or a user setting? var global = options.global || false; + var plugin = options.plugin; + var url = ''; - if (global) { + if (plugin) { + url = `/api/plugin/settings/${pk}/`; + } else if (global) { url = `/api/settings/global/${pk}/`; } else { url = `/api/settings/user/${pk}/`; From 928b90a83380ba25a6832a5cc8058feba7a8382e Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 4 Jan 2022 21:03:01 +1100 Subject: [PATCH 38/67] Edit plugin settings via the "settings" display --- InvenTree/common/models.py | 17 ++++------------- InvenTree/plugin/models.py | 6 ++++++ .../templates/InvenTree/settings/setting.html | 2 +- .../templates/InvenTree/settings/settings.html | 15 +++++++++++++-- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 048a968d1a..16d0be035a 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -371,23 +371,14 @@ class BaseInvenTreeSetting(models.Model): validator = self.__class__.get_setting_validator(self.key, **kwargs) - if self.is_bool(): - self.value = InvenTree.helpers.str2bool(self.value) - - if self.is_int(): - try: - self.value = int(self.value) - except (ValueError): - raise ValidationError(_('Must be an integer value')) + if validator is not None: + self.run_validator(validator) options = self.valid_options() if options and self.value not in options: raise ValidationError(_("Chosen value is not a valid option")) - if validator is not None: - self.run_validator(validator) - def run_validator(self, validator): """ Run a validator against the 'value' field for this InvenTreeSetting object. @@ -399,7 +390,7 @@ class BaseInvenTreeSetting(models.Model): value = self.value # Boolean validator - if self.is_bool(): + if validator is bool: # Value must "look like" a boolean value if InvenTree.helpers.is_bool(value): # Coerce into either "True" or "False" @@ -410,7 +401,7 @@ class BaseInvenTreeSetting(models.Model): }) # Integer validator - if self.is_int(): + if validator is int: try: # Coerce into an integer value diff --git a/InvenTree/plugin/models.py b/InvenTree/plugin/models.py index f477df5c27..8b81eb2062 100644 --- a/InvenTree/plugin/models.py +++ b/InvenTree/plugin/models.py @@ -113,6 +113,12 @@ class PluginSetting(common.models.BaseInvenTreeSetting): ('plugin', 'key'), ] + def clean(self, **kwargs): + + kwargs['plugin'] = self.plugin + + super().clean(**kwargs) + """ We override the following class methods, so that we can pass the plugin instance diff --git a/InvenTree/templates/InvenTree/settings/setting.html b/InvenTree/templates/InvenTree/settings/setting.html index 91d03849ce..16fc67ef86 100644 --- a/InvenTree/templates/InvenTree/settings/setting.html +++ b/InvenTree/templates/InvenTree/settings/setting.html @@ -38,7 +38,7 @@
{% trans setting.name %}{{ setting.name }} {% if setting.is_bool %}
@@ -32,7 +32,7 @@
{% endif %}
- {% trans setting.description %} + {{ setting.description }}
From 993b368d3dded4eaf494b53f12e9e96a111054b3 Mon Sep 17 00:00:00 2001 From: Matthias Mair <66015116+matmair@users.noreply.github.com> Date: Mon, 3 Jan 2022 23:59:16 +0100 Subject: [PATCH 35/67] new stale check --- .github/workflows/stale.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000000..c8b6bf3cc7 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,24 @@ +# Marks all issues that do not receive activity stale starting 2022 +name: Mark stale issues and pull requests + +on: + schedule: + - cron: '24 11 * * *' + +jobs: + stale: + + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue seems stale. Please react to show this is still important.' + stale-pr-message: 'This PR seems stale. Please react to show this is still important.' + stale-issue-label: 'no-activity' + stale-pr-label: 'no-activity' + start-date: '2022-01-01' From 9b1e9445098f86c0483daf4e59d4a94fedf8cce2 Mon Sep 17 00:00:00 2001 From: Matthias Mair <66015116+matmair@users.noreply.github.com> Date: Tue, 4 Jan 2022 00:04:05 +0100 Subject: [PATCH 36/67] ignore everything that got a milestone this helps keeping false positives lower --- .github/workflows/stale.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index c8b6bf3cc7..278e5139e5 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -22,3 +22,4 @@ jobs: stale-issue-label: 'no-activity' stale-pr-label: 'no-activity' start-date: '2022-01-01' + exempt-all-milestones: true From dc9e25ebad12ee9fe23903d4bd8ac06df033d3b1 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 2 Jan 2022 14:12:34 +1100 Subject: [PATCH 37/67] Adds API endpoints for viewing and updating plugin settings A lot of code updates / refactoring here to get this to work as expected --- InvenTree/InvenTree/version.py | 6 +- InvenTree/common/models.py | 26 ++++---- .../part/templatetags/inventree_extras.py | 13 +++- InvenTree/plugin/__init__.py | 8 ++- InvenTree/plugin/admin.py | 1 + InvenTree/plugin/api.py | 42 ++++++++++++- InvenTree/plugin/apps.py | 8 +-- .../plugin/builtin/integration/mixins.py | 17 +++-- InvenTree/plugin/helpers.py | 8 +-- InvenTree/plugin/integration.py | 1 - InvenTree/plugin/loader.py | 4 +- InvenTree/plugin/models.py | 62 +++++++++++++++++-- InvenTree/plugin/plugin.py | 30 +++++++-- InvenTree/plugin/registry.py | 23 +++---- .../plugin/samples/integration/sample.py | 12 ++++ InvenTree/plugin/serializers.py | 25 +++++++- .../plugin/templatetags/plugin_extras.py | 10 +-- InvenTree/plugin/test_api.py | 4 +- InvenTree/plugin/test_plugin.py | 10 +-- InvenTree/plugin/urls.py | 4 +- .../InvenTree/settings/mixins/settings.html | 2 +- .../templates/InvenTree/settings/setting.html | 8 ++- InvenTree/templates/js/dynamic/settings.js | 6 +- 23 files changed, 250 insertions(+), 80 deletions(-) diff --git a/InvenTree/InvenTree/version.py b/InvenTree/InvenTree/version.py index 79bc44bc0e..1f8e372d39 100644 --- a/InvenTree/InvenTree/version.py +++ b/InvenTree/InvenTree/version.py @@ -12,11 +12,15 @@ import common.models INVENTREE_SW_VERSION = "0.6.0 dev" # InvenTree API version -INVENTREE_API_VERSION = 22 +INVENTREE_API_VERSION = 23 """ Increment this API version number whenever there is a significant change to the API that any clients need to know about +v23 -> 2022-02-02 + - Adds API endpoints for managing plugin classes + - Adds API endpoints for managing plugin settings + v22 -> 2021-12-20 - Adds API endpoint to "merge" multiple stock items diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index ecddd17de8..048a968d1a 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -71,7 +71,7 @@ class BaseInvenTreeSetting(models.Model): super().save() @classmethod - def allValues(cls, user=None, plugin=None, exclude_hidden=False): + def allValues(cls, user=None, exclude_hidden=False): """ Return a dict of "all" defined global settings. @@ -86,10 +86,6 @@ class BaseInvenTreeSetting(models.Model): if user is not None: results = results.filter(user=user) - # Optionally filter by plugin - if plugin is not None: - results = results.filter(plugin=plugin) - # Query the database settings = {} @@ -238,16 +234,12 @@ class BaseInvenTreeSetting(models.Model): settings = cls.objects.all() + # Filter by user user = kwargs.get('user', None) if user is not None: settings = settings.filter(user=user) - plugin = kwargs.get('plugin', None) - - if plugin is not None: - settings = settings.filter(plugin=plugin) - try: setting = settings.filter(**cls.get_filters(key, **kwargs)).first() except (ValueError, cls.DoesNotExist): @@ -255,6 +247,16 @@ class BaseInvenTreeSetting(models.Model): except (IntegrityError, OperationalError): setting = None + plugin = kwargs.pop('plugin', None) + + if plugin: + from plugin import InvenTreePlugin + + if issubclass(plugin.__class__, InvenTreePlugin): + plugin = plugin.plugin_config() + + kwargs['plugin'] = plugin + # Setting does not exist! (Try to create it) if not setting: @@ -554,7 +556,9 @@ class BaseInvenTreeSetting(models.Model): def settings_group_options(): - """build up group tuple for settings based on gour choices""" + """ + Build up group tuple for settings based on your choices + """ return [('', _('No group')), *[(str(a.id), str(a)) for a in Group.objects.all()]] diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 9dc09535fa..9c0b0e691f 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- -""" This module provides template tags for extra functionality +""" +This module provides template tags for extra functionality, over and above the built-in Django tags. """ @@ -22,6 +23,8 @@ import InvenTree.helpers from common.models import InvenTreeSetting, ColorTheme, InvenTreeUserSetting from common.settings import currency_code_default +from plugin.models import PluginSetting + register = template.Library() @@ -223,8 +226,16 @@ def setting_object(key, *args, **kwargs): if a user-setting was requested return that """ + if 'plugin' in kwargs: + # Note, 'plugin' is an instance of an InvenTreePlugin class + + plugin = kwargs['plugin'] + + return PluginSetting.get_setting_object(key, plugin=plugin) + if 'user' in kwargs: return InvenTreeUserSetting.get_setting_object(key, user=kwargs['user']) + return InvenTreeSetting.get_setting_object(key) diff --git a/InvenTree/plugin/__init__.py b/InvenTree/plugin/__init__.py index 973d341171..b3dc3a2fd0 100644 --- a/InvenTree/plugin/__init__.py +++ b/InvenTree/plugin/__init__.py @@ -1,7 +1,11 @@ -from .registry import plugins as plugin_reg +from .registry import plugin_registry +from .plugin import InvenTreePlugin from .integration import IntegrationPluginBase from .action import ActionPlugin __all__ = [ - 'plugin_reg', 'IntegrationPluginBase', 'ActionPlugin', + 'ActionPlugin', + 'IntegrationPluginBase', + 'InvenTreePlugin', + 'plugin_registry', ] diff --git a/InvenTree/plugin/admin.py b/InvenTree/plugin/admin.py index f13444f274..e27c499479 100644 --- a/InvenTree/plugin/admin.py +++ b/InvenTree/plugin/admin.py @@ -6,6 +6,7 @@ from django.contrib import admin import plugin.models as models import plugin.registry as registry + def plugin_update(queryset, new_status: bool): """general function for bulk changing plugins""" apps_changed = False diff --git a/InvenTree/plugin/api.py b/InvenTree/plugin/api.py index 4aecd6bb24..9ab3b96724 100644 --- a/InvenTree/plugin/api.py +++ b/InvenTree/plugin/api.py @@ -11,7 +11,8 @@ from rest_framework import generics from rest_framework import status from rest_framework.response import Response -from plugin.models import PluginConfig +from common.api import GlobalSettingsPermissions +from plugin.models import PluginConfig, PluginSetting import plugin.serializers as PluginSerializers @@ -76,7 +77,46 @@ class PluginInstall(generics.CreateAPIView): return serializer.save() +class PluginSettingList(generics.ListAPIView): + """ + List endpoint for all plugin related settings. + + - read only + - only accessible by staff users + """ + + queryset = PluginSetting.objects.all() + serializer_class = PluginSerializers.PluginSettingSerializer + + permission_classes = [ + GlobalSettingsPermissions, + ] + + +class PluginSettingDetail(generics.RetrieveUpdateAPIView): + """ + Detail endpoint for a plugin-specific setting. + + Note that these cannot be created or deleted via the API + """ + + queryset = PluginSetting.objects.all() + serializer_class = PluginSerializers.PluginSettingSerializer + + # Staff permission required + permission_classes = [ + GlobalSettingsPermissions, + ] + + plugin_api_urls = [ + + # Plugin settings URLs + url(r'^settings/', include([ + url(r'^(?P\d+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'), + url(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'), + ])), + # Detail views for a single PluginConfig item url(r'^(?P\d+)/', include([ url(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'), diff --git a/InvenTree/plugin/apps.py b/InvenTree/plugin/apps.py index 8a3cd97889..cca9dee91c 100644 --- a/InvenTree/plugin/apps.py +++ b/InvenTree/plugin/apps.py @@ -4,17 +4,17 @@ from __future__ import unicode_literals from django.apps import AppConfig from maintenance_mode.core import set_maintenance_mode -from plugin.registry import plugins +from plugin import plugin_registry class PluginAppConfig(AppConfig): name = 'plugin' def ready(self): - if not plugins.is_loading: + if not plugin_registry.is_loading: # this is the first startup - plugins.collect_plugins() - plugins.load_plugins() + plugin_registry.collect_plugins() + plugin_registry.load_plugins() # drop out of maintenance # makes sure we did not have an error in reloading and maintenance is still active diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 47e9ff630d..30f3cd8551 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -36,17 +36,14 @@ class SettingsMixin: # Find the plugin configuration associated with this plugin - try: - plugin, _ = PluginConfig.objects.get_or_create(key=self.plugin_slug(), name=self.plugin_name()) - except (OperationalError, ProgrammingError) as error: - plugin = None - - if not plugin: + plugin = self.plugin_config() + + if plugin: + return PluginSetting.get_setting(key, plugin=plugin, settings=self.settings) + else: # Plugin cannot be found, return default value return PluginSetting.get_setting_default(key, settings=self.settings) - return PluginSetting.get_setting(key, plugin=plugin, settings=self.settings) - def set_setting(self, key, value, user): """ Set plugin setting value by key @@ -54,12 +51,12 @@ class SettingsMixin: try: plugin, _ = PluginConfig.objects.get_or_create(key=self.plugin_slug(), name=self.plugin_name()) - except (OperationalError, ProgrammingError) as error: + except (OperationalError, ProgrammingError): plugin = None if not plugin: # Cannot find associated plugin model, return - return + return PluginSetting.set_setting(key, value, user, plugin=plugin, settings=self.settings) diff --git a/InvenTree/plugin/helpers.py b/InvenTree/plugin/helpers.py index 003ca707b4..fb46df8927 100644 --- a/InvenTree/plugin/helpers.py +++ b/InvenTree/plugin/helpers.py @@ -10,14 +10,14 @@ from django.conf import settings # region logging / errors def log_plugin_error(error, reference: str = 'general'): - from plugin import plugin_reg + from plugin import plugin_registry # make sure the registry is set up - if reference not in plugin_reg.errors: - plugin_reg.errors[reference] = [] + if reference not in plugin_registry.errors: + plugin_registry.errors[reference] = [] # add error to stack - plugin_reg.errors[reference].append(error) + plugin_registry.errors[reference].append(error) class IntegrationPluginError(Exception): diff --git a/InvenTree/plugin/integration.py b/InvenTree/plugin/integration.py index d66ab79c26..2c593291d3 100644 --- a/InvenTree/plugin/integration.py +++ b/InvenTree/plugin/integration.py @@ -9,7 +9,6 @@ import pathlib from django.urls.base import reverse from django.conf import settings -from django.utils.text import slugify from django.utils.translation import ugettext_lazy as _ import plugin.plugin as plugin diff --git a/InvenTree/plugin/loader.py b/InvenTree/plugin/loader.py index 2491336a51..2d17f8c36f 100644 --- a/InvenTree/plugin/loader.py +++ b/InvenTree/plugin/loader.py @@ -4,7 +4,7 @@ load templates for loaded plugins from django.template.loaders.filesystem import Loader as FilesystemLoader from pathlib import Path -from plugin import plugin_reg +from plugin import plugin_registry class PluginTemplateLoader(FilesystemLoader): @@ -12,7 +12,7 @@ class PluginTemplateLoader(FilesystemLoader): def get_dirs(self): dirname = 'templates' template_dirs = [] - for plugin in plugin_reg.plugins.values(): + for plugin in plugin_registry.plugins.values(): new_path = Path(plugin.path) / dirname if Path(new_path).is_dir(): template_dirs.append(new_path) diff --git a/InvenTree/plugin/models.py b/InvenTree/plugin/models.py index b001798544..f477df5c27 100644 --- a/InvenTree/plugin/models.py +++ b/InvenTree/plugin/models.py @@ -10,7 +10,7 @@ from django.db import models import common.models -from plugin import plugin_reg +from plugin import InvenTreePlugin, plugin_registry class PluginConfig(models.Model): @@ -72,7 +72,7 @@ class PluginConfig(models.Model): self.__org_active = self.active # append settings from registry - self.plugin = plugin_reg.plugins.get(self.key, None) + self.plugin = plugin_registry.plugins.get(self.key, None) def get_plugin_meta(name): if self.plugin: @@ -95,10 +95,10 @@ class PluginConfig(models.Model): if not reload: if self.active is False and self.__org_active is True: - plugin_reg.reload_plugins() + plugin_registry.reload_plugins() elif self.active is True and self.__org_active is False: - plugin_reg.reload_plugins() + plugin_registry.reload_plugins() return ret @@ -113,6 +113,58 @@ class PluginSetting(common.models.BaseInvenTreeSetting): ('plugin', 'key'), ] + """ + We override the following class methods, + so that we can pass the plugin instance + """ + + @property + def name(self): + return self.__class__.get_setting_name(self.key, plugin=self.plugin) + + @property + def default_value(self): + return self.__class__.get_setting_default(self.key, plugin=self.plugin) + + @property + def description(self): + return self.__class__.get_setting_description(self.key, plugin=self.plugin) + + @property + def units(self): + return self.__class__.get_setting_units(self.key, plugin=self.plugin) + + def choices(self): + return self.__class__.get_setting_choices(self.key, plugin=self.plugin) + + @classmethod + def get_setting_definition(cls, key, **kwargs): + """ + In the BaseInvenTreeSetting class, we have a class attribute named 'SETTINGS', + which is a dict object that fully defines all the setting parameters. + + Here, unlike the BaseInvenTreeSetting, we do not know the definitions of all settings + 'ahead of time' (as they are defined externally in the plugins). + + Settings can be provided by the caller, as kwargs['settings']. + + If not provided, we'll look at the plugin registry to see what settings are available, + (if the plugin is specified!) + """ + + if 'settings' not in kwargs: + + plugin = kwargs.pop('plugin', None) + + if plugin: + + if issubclass(plugin.__class__, InvenTreePlugin): + plugin = plugin.plugin_config() + + kwargs['settings'] = plugin_registry.mixins_settings.get(plugin.key, {}) + + return super().get_setting_definition(key, **kwargs) + @classmethod def get_filters(cls, key, **kwargs): """ @@ -124,6 +176,8 @@ class PluginSetting(common.models.BaseInvenTreeSetting): plugin = kwargs.get('plugin', None) if plugin: + if issubclass(plugin.__class__, InvenTreePlugin): + plugin = plugin.plugin_config() filters['plugin'] = plugin return filters diff --git a/InvenTree/plugin/plugin.py b/InvenTree/plugin/plugin.py index dbafda0aea..0cf8082b7f 100644 --- a/InvenTree/plugin/plugin.py +++ b/InvenTree/plugin/plugin.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- -"""Base Class for InvenTree plugins""" - +""" +Base Class for InvenTree plugins +""" +from django.db.utils import OperationalError, ProgrammingError from django.utils.text import slugify @@ -10,6 +12,9 @@ class InvenTreePlugin(): Base class for a plugin """ + def __init__(self): + pass + # Override the plugin name for each concrete plugin instance PLUGIN_NAME = '' @@ -36,5 +41,22 @@ class InvenTreePlugin(): return self.PLUGIN_TITLE - def __init__(self): - pass + def plugin_config(self, raise_error=False): + """ + Return the PluginConfig object associated with this plugin + """ + + try: + import plugin.models + + cfg, _ = plugin.models.PluginConfig.objects.get_or_create( + key=self.plugin_slug(), + name=self.plugin_name(), + ) + except (OperationalError, ProgrammingError) as error: + cfg = None + + if raise_error: + raise error + + return cfg diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index e0b25ecc65..30dbad5f95 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -33,7 +33,7 @@ from .helpers import get_plugin_error, IntegrationPluginError logger = logging.getLogger('inventree') -class Plugins: +class PluginsRegistry: def __init__(self) -> None: # plugin registry self.plugins = {} @@ -225,7 +225,8 @@ class Plugins: self.plugins_inactive[plug_key] = plugin_db_setting def _activate_plugins(self, force_reload=False): - """run integration functions for all plugins + """ + Run integration functions for all plugins :param force_reload: force reload base apps, defaults to False :type force_reload: bool, optional @@ -238,13 +239,13 @@ class Plugins: self.activate_integration_app(plugins, force_reload=force_reload) def _deactivate_plugins(self): - """run integration deactivation functions for all plugins""" + """ + Run integration deactivation functions for all plugins + """ self.deactivate_integration_app() self.deactivate_integration_globalsettings() # endregion - # region specific integrations - # region integration_globalsettings def activate_integration_globalsettings(self, plugins): from common.models import InvenTreeSetting @@ -255,24 +256,16 @@ class Plugins: plugin_setting = plugin.settings self.mixins_settings[slug] = plugin_setting - # Add to settings dir - InvenTreeSetting.SETTINGS.update(plugin_setting) - def deactivate_integration_globalsettings(self): - from common.models import InvenTreeSetting # collect all settings plugin_settings = {} + for _, plugin_setting in self.mixins_settings.items(): plugin_settings.update(plugin_setting) - # remove settings - for setting in plugin_settings: - InvenTreeSetting.SETTINGS.pop(setting) - # clear cache self.mixins_Fsettings = {} - # endregion # region integration_app def activate_integration_app(self, plugins, force_reload=False): @@ -452,4 +445,4 @@ class Plugins: # endregion -plugins = Plugins() +plugin_registry = PluginsRegistry() diff --git a/InvenTree/plugin/samples/integration/sample.py b/InvenTree/plugin/samples/integration/sample.py index 682726718f..a05e804def 100644 --- a/InvenTree/plugin/samples/integration/sample.py +++ b/InvenTree/plugin/samples/integration/sample.py @@ -52,6 +52,18 @@ class SampleIntegrationPlugin(AppMixin, SettingsMixin, UrlsMixin, NavigationMixi 'name': _('Numerical'), 'description': _('A numerical setting'), 'validator': int, + 'default': 123, + }, + 'CHOICE_SETTING': { + 'name': _("Choice Setting"), + 'description': _('A setting with multiple choices'), + 'choices': [ + ('A', 'Anaconda'), + ('B', 'Bat'), + ('C', 'Cat'), + ('D', 'Dog'), + ], + 'default': 'A', }, } diff --git a/InvenTree/plugin/serializers.py b/InvenTree/plugin/serializers.py index e25e253498..da171a604d 100644 --- a/InvenTree/plugin/serializers.py +++ b/InvenTree/plugin/serializers.py @@ -14,7 +14,9 @@ from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers -from plugin.models import PluginConfig +from common.serializers import SettingsSerializer + +from plugin.models import PluginConfig, PluginSetting class PluginConfigSerializer(serializers.ModelSerializer): @@ -117,3 +119,24 @@ class PluginConfigInstallSerializer(serializers.Serializer): # TODO return ret + + +class PluginSettingSerializer(SettingsSerializer): + """ + Serializer for the PluginSetting model + """ + + plugin = serializers.PrimaryKeyRelatedField(read_only=True) + + class Meta: + model = PluginSetting + fields = [ + 'pk', + 'key', + 'value', + 'name', + 'description', + 'type', + 'choices', + 'plugin', + ] diff --git a/InvenTree/plugin/templatetags/plugin_extras.py b/InvenTree/plugin/templatetags/plugin_extras.py index b7f4f6b6c1..7852133ebb 100644 --- a/InvenTree/plugin/templatetags/plugin_extras.py +++ b/InvenTree/plugin/templatetags/plugin_extras.py @@ -7,7 +7,7 @@ from django import template from django.urls import reverse from common.models import InvenTreeSetting -from plugin import plugin_reg +from plugin import plugin_registry register = template.Library() @@ -16,19 +16,19 @@ register = template.Library() @register.simple_tag() def plugin_list(*args, **kwargs): """ Return a list of all installed integration plugins """ - return plugin_reg.plugins + return plugin_registry.plugins @register.simple_tag() def inactive_plugin_list(*args, **kwargs): """ Return a list of all inactive integration plugins """ - return plugin_reg.plugins_inactive + return plugin_registry.plugins_inactive @register.simple_tag() def plugin_settings(plugin, *args, **kwargs): """ Return a list of all custom settings for a plugin """ - return plugin_reg.mixins_settings.get(plugin) + return plugin_registry.mixins_settings.get(plugin) @register.simple_tag() @@ -57,4 +57,4 @@ def safe_url(view_name, *args, **kwargs): @register.simple_tag() def plugin_errors(*args, **kwargs): """Return all plugin errors""" - return plugin_reg.errors + return plugin_registry.errors diff --git a/InvenTree/plugin/test_api.py b/InvenTree/plugin/test_api.py index 0bb5f7789b..fe1e9802bf 100644 --- a/InvenTree/plugin/test_api.py +++ b/InvenTree/plugin/test_api.py @@ -64,14 +64,14 @@ class PluginDetailAPITest(InvenTreeAPITestCase): Test the PluginConfig action commands """ from plugin.models import PluginConfig - from plugin import plugin_reg + from plugin import plugin_registry url = reverse('admin:plugin_pluginconfig_changelist') fixtures = PluginConfig.objects.all() # check if plugins were registered -> in some test setups the startup has no db access if not fixtures: - plugin_reg.reload_plugins() + plugin_registry.reload_plugins() fixtures = PluginConfig.objects.all() print([str(a) for a in fixtures]) diff --git a/InvenTree/plugin/test_plugin.py b/InvenTree/plugin/test_plugin.py index b4e2fdaf6f..5724bdb0a9 100644 --- a/InvenTree/plugin/test_plugin.py +++ b/InvenTree/plugin/test_plugin.py @@ -8,7 +8,7 @@ from plugin.samples.integration.sample import SampleIntegrationPlugin from plugin.samples.integration.another_sample import WrongIntegrationPlugin, NoIntegrationPlugin # from plugin.plugins import load_action_plugins, load_barcode_plugins import plugin.templatetags.plugin_extras as plugin_tags -from plugin import plugin_reg +from plugin import plugin_registry class InvenTreePluginTests(TestCase): @@ -57,17 +57,17 @@ class PluginTagTests(TestCase): def test_tag_plugin_list(self): """test that all plugins are listed""" - self.assertEqual(plugin_tags.plugin_list(), plugin_reg.plugins) + self.assertEqual(plugin_tags.plugin_list(), plugin_registry.plugins) def test_tag_incative_plugin_list(self): """test that all inactive plugins are listed""" - self.assertEqual(plugin_tags.inactive_plugin_list(), plugin_reg.plugins_inactive) + self.assertEqual(plugin_tags.inactive_plugin_list(), plugin_registry.plugins_inactive) def test_tag_plugin_settings(self): """check all plugins are listed""" self.assertEqual( plugin_tags.plugin_settings(self.sample), - plugin_reg.mixins_settings.get(self.sample) + plugin_registry.mixins_settings.get(self.sample) ) def test_tag_mixin_enabled(self): @@ -89,4 +89,4 @@ class PluginTagTests(TestCase): def test_tag_plugin_errors(self): """test that all errors are listed""" - self.assertEqual(plugin_tags.plugin_errors(), plugin_reg.errors) + self.assertEqual(plugin_tags.plugin_errors(), plugin_registry.errors) diff --git a/InvenTree/plugin/urls.py b/InvenTree/plugin/urls.py index 419dce5a88..46cdfd8a84 100644 --- a/InvenTree/plugin/urls.py +++ b/InvenTree/plugin/urls.py @@ -3,7 +3,7 @@ URL lookup for plugin app """ from django.conf.urls import url, include -from plugin import plugin_reg +from plugin import plugin_registry PLUGIN_BASE = 'plugin' # Constant for links @@ -12,7 +12,7 @@ PLUGIN_BASE = 'plugin' # Constant for links def get_plugin_urls(): """returns a urlpattern that can be integrated into the global urls""" urls = [] - for plugin in plugin_reg.plugins.values(): + for plugin in plugin_registry.plugins.values(): if plugin.mixin_enabled('urls'): urls.append(plugin.urlpatterns) return url(f'^{PLUGIN_BASE}/', include((urls, 'plugin'))) diff --git a/InvenTree/templates/InvenTree/settings/mixins/settings.html b/InvenTree/templates/InvenTree/settings/mixins/settings.html index cb136b5c4f..57218b3699 100644 --- a/InvenTree/templates/InvenTree/settings/mixins/settings.html +++ b/InvenTree/templates/InvenTree/settings/mixins/settings.html @@ -10,7 +10,7 @@ {% for setting in plugin_settings %} - {% include "InvenTree/settings/setting.html" with key=setting%} + {% include "InvenTree/settings/setting.html" with key=setting plugin=plugin %} {% endfor %}
\ No newline at end of file diff --git a/InvenTree/templates/InvenTree/settings/setting.html b/InvenTree/templates/InvenTree/settings/setting.html index 96a8993798..91d03849ce 100644 --- a/InvenTree/templates/InvenTree/settings/setting.html +++ b/InvenTree/templates/InvenTree/settings/setting.html @@ -1,10 +1,12 @@ {% load inventree_extras %} {% load i18n %} -{% if user_setting %} - {% setting_object key user=request.user as setting %} +{% if plugin %} +{% setting_object key plugin=plugin as setting %} +{% elif user_setting %} +{% setting_object key user=request.user as setting %} {% else %} - {% setting_object key as setting %} +{% setting_object key as setting %} {% endif %}
-
diff --git a/InvenTree/templates/InvenTree/settings/settings.html b/InvenTree/templates/InvenTree/settings/settings.html index cb87c6765b..9b3d2d21de 100644 --- a/InvenTree/templates/InvenTree/settings/settings.html +++ b/InvenTree/templates/InvenTree/settings/settings.html @@ -62,16 +62,27 @@ $('table').find('.btn-edit-setting').click(function() { var setting = $(this).attr('setting'); var pk = $(this).attr('pk'); - + var plugin = $(this).attr('plugin'); var is_global = true; if ($(this).attr('user')){ is_global = false; } + var title = ''; + + if (plugin != null) { + title = '{% trans "Edit Plugin Setting" %}'; + } else if (is_global) { + title = '{% trans "Edit Global Setting" %}'; + } else { + title = '{% trans "Edit User Setting" %}'; + } + editSetting(pk, { + plugin: plugin, global: is_global, - title: is_global ? '{% trans "Edit Global Setting" %}' : '{% trans "Edit User Setting" %}', + title: title, }); }); From ac849c156664c0867072ae7ae5ee13b22571d15f Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 4 Jan 2022 21:36:27 +1100 Subject: [PATCH 39/67] Fixes for unit tests --- InvenTree/plugin/admin.py | 23 +++-- .../plugin/builtin/integration/mixins.py | 14 +-- InvenTree/plugin/integration.py | 19 +++- InvenTree/plugin/plugin.py | 11 ++- InvenTree/plugin/registry.py | 90 ++++++++++++------- InvenTree/plugin/serializers.py | 9 +- InvenTree/plugin/test_api.py | 4 +- InvenTree/plugin/test_integration.py | 2 +- InvenTree/plugin/test_plugin.py | 5 +- InvenTree/plugin/urls.py | 8 +- 10 files changed, 116 insertions(+), 69 deletions(-) diff --git a/InvenTree/plugin/admin.py b/InvenTree/plugin/admin.py index e27c499479..b20aef8057 100644 --- a/InvenTree/plugin/admin.py +++ b/InvenTree/plugin/admin.py @@ -8,30 +8,38 @@ import plugin.registry as registry def plugin_update(queryset, new_status: bool): - """general function for bulk changing plugins""" + """ + General function for bulk changing plugins + """ + apps_changed = False - # run through all plugins in the queryset as the save method needs to be overridden + # Run through all plugins in the queryset as the save method needs to be overridden for plugin in queryset: if plugin.active is not new_status: plugin.active = new_status plugin.save(no_reload=True) apps_changed = True - # reload plugins if they changed + # Reload plugins if they changed if apps_changed: registry.plugin_registry.reload_plugins() @admin.action(description='Activate plugin(s)') def plugin_activate(modeladmin, request, queryset): - """activate a set of plugins""" + """ + Activate a set of plugins + """ plugin_update(queryset, True) @admin.action(description='Deactivate plugin(s)') def plugin_deactivate(modeladmin, request, queryset): - """deactivate a set of plugins""" + """ + Deactivate a set of plugins + """ + plugin_update(queryset, False) @@ -51,7 +59,10 @@ class PluginSettingInline(admin.TabularInline): class PluginConfigAdmin(admin.ModelAdmin): - """Custom admin with restricted id fields""" + """ + Custom admin with restricted id fields + """ + readonly_fields = ["key", "name", ] list_display = ['name', 'key', '__str__', 'active', ] list_filter = ['active'] diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 30f3cd8551..c5d2411e4d 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -34,17 +34,9 @@ class SettingsMixin: Return the 'value' of the setting associated with this plugin """ - # Find the plugin configuration associated with this plugin + return PluginSetting.get_setting(key, plugin=self) - plugin = self.plugin_config() - - if plugin: - return PluginSetting.get_setting(key, plugin=plugin, settings=self.settings) - else: - # Plugin cannot be found, return default value - return PluginSetting.get_setting_default(key, settings=self.settings) - - def set_setting(self, key, value, user): + def set_setting(self, key, value, user=None): """ Set plugin setting value by key """ @@ -58,7 +50,7 @@ class SettingsMixin: # Cannot find associated plugin model, return return - PluginSetting.set_setting(key, value, user, plugin=plugin, settings=self.settings) + PluginSetting.set_setting(key, value, user, plugin=plugin) class UrlsMixin: diff --git a/InvenTree/plugin/integration.py b/InvenTree/plugin/integration.py index 2c593291d3..73223593a5 100644 --- a/InvenTree/plugin/integration.py +++ b/InvenTree/plugin/integration.py @@ -19,19 +19,27 @@ logger = logging.getLogger("inventree") class MixinBase: - """general base for mixins""" + """ + General base for mixins + """ def __init__(self) -> None: self._mixinreg = {} self._mixins = {} def add_mixin(self, key: str, fnc_enabled=True, cls=None): - """add a mixin to the plugins registry""" + """ + Add a mixin to the plugins registry + """ + self._mixins[key] = fnc_enabled self.setup_mixin(key, cls=cls) def setup_mixin(self, key, cls=None): - """define mixin details for the current mixin -> provides meta details for all active mixins""" + """ + Define mixin details for the current mixin -> provides meta details for all active mixins + """ + # get human name human_name = getattr(cls.MixinMeta, 'MIXIN_NAME', key) if cls and hasattr(cls, 'MixinMeta') else key @@ -43,7 +51,10 @@ class MixinBase: @property def registered_mixins(self, with_base: bool = False): - """get all registered mixins for the plugin""" + """ + Get all registered mixins for the plugin + """ + mixins = getattr(self, '_mixinreg', None) if mixins: # filter out base diff --git a/InvenTree/plugin/plugin.py b/InvenTree/plugin/plugin.py index 0cf8082b7f..35643b36c3 100644 --- a/InvenTree/plugin/plugin.py +++ b/InvenTree/plugin/plugin.py @@ -18,9 +18,9 @@ class InvenTreePlugin(): # Override the plugin name for each concrete plugin instance PLUGIN_NAME = '' - PLUGIN_SLUG = '' + PLUGIN_SLUG = None - PLUGIN_TITLE = '' + PLUGIN_TITLE = None def plugin_name(self): """ @@ -35,11 +35,14 @@ class InvenTreePlugin(): if slug is None: slug = self.plugin_name() - return slugify(slug) + return slugify(slug.lower()) def plugin_title(self): - return self.PLUGIN_TITLE + if self.PLUGIN_TITLE: + return self.PLUGIN_TITLE + else: + return self.plugin_name() def plugin_config(self, raise_error=False): """ diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index 30dbad5f95..fe28acfadb 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -1,7 +1,10 @@ """ -registry for plugins -holds the class and the object that contains all code to maintain plugin states +Registry for loading and managing multiple plugins at run-time + +- Holds the class and the object that contains all code to maintain plugin states +- Manages setup and teardown of plugin class instances """ + import importlib import pathlib import logging @@ -34,6 +37,10 @@ logger = logging.getLogger('inventree') class PluginsRegistry: + """ + The PluginsRegistry class + """ + def __init__(self) -> None: # plugin registry self.plugins = {} @@ -54,11 +61,15 @@ class PluginsRegistry: # region public plugin functions def load_plugins(self): - """load and activate all IntegrationPlugins""" + """ + Load and activate all IntegrationPlugins + """ + from plugin.helpers import log_plugin_error logger.info('Start loading plugins') - # set maintanace mode + + # Set maintanace mode _maintenance = bool(get_maintenance_mode()) if not _maintenance: set_maintenance_mode(True) @@ -68,7 +79,7 @@ class PluginsRegistry: retry_counter = settings.PLUGIN_RETRY while not registered_sucessfull: try: - # we are using the db so for migrations etc we need to try this block + # We are using the db so for migrations etc we need to try this block self._init_plugins(blocked_plugin) self._activate_plugins() registered_sucessfull = True @@ -81,13 +92,14 @@ class PluginsRegistry: log_plugin_error({error.path: error.message}, 'load') blocked_plugin = error.path # we will not try to load this app again - # init apps without any integration plugins + # Initialize apps without any integration plugins self._clean_registry() self._clean_installed_apps() self._activate_plugins(force_reload=True) - # we do not want to end in an endless loop + # We do not want to end in an endless loop retry_counter -= 1 + if retry_counter <= 0: if settings.PLUGIN_TESTING: print('[PLUGIN] Max retries, breaking loading') @@ -98,15 +110,20 @@ class PluginsRegistry: # now the loading will re-start up with init - # remove maintenance + # Remove maintenance mode if not _maintenance: set_maintenance_mode(False) + logger.info('Finished loading plugins') def unload_plugins(self): - """unload and deactivate all IntegrationPlugins""" + """ + Unload and deactivate all IntegrationPlugins + """ + logger.info('Start unloading plugins') - # set maintanace mode + + # Set maintanace mode _maintenance = bool(get_maintenance_mode()) if not _maintenance: set_maintenance_mode(True) @@ -123,21 +140,27 @@ class PluginsRegistry: logger.info('Finished unloading plugins') def reload_plugins(self): - """safely reload IntegrationPlugins""" - # do not reload whe currently loading + """ + Safely reload IntegrationPlugins + """ + + # Do not reload whe currently loading if self.is_loading: return logger.info('Start reloading plugins') + with maintenance_mode_on(): self.unload_plugins() self.load_plugins() - logger.info('Finished reloading plugins') - # endregion - # region general plugin managment mechanisms + logger.info('Finished reloading plugins') + def collect_plugins(self): - """collect integration plugins from all possible ways of loading""" + """ + Collect integration plugins from all possible ways of loading + """ + self.plugin_modules = [] # clear # Collect plugins from paths @@ -146,7 +169,7 @@ class PluginsRegistry: if modules: [self.plugin_modules.append(item) for item in modules] - # check if not running in testing mode and apps should be loaded from hooks + # Check if not running in testing mode and apps should be loaded from hooks if (not settings.PLUGIN_TESTING) or (settings.PLUGIN_TESTING and settings.PLUGIN_TESTING_SETUP): # Collect plugins from setup entry points for entry in metadata.entry_points().get('inventree_plugins', []): @@ -159,22 +182,25 @@ class PluginsRegistry: logger.info(", ".join([a.__module__ for a in self.plugin_modules])) def _init_plugins(self, disabled=None): - """initialise all found plugins + """ + Initialise all found plugins :param disabled: loading path of disabled app, defaults to None :type disabled: str, optional :raises error: IntegrationPluginError """ + from plugin.models import PluginConfig logger.info('Starting plugin initialisation') + # Initialize integration plugins for plugin in self.plugin_modules: - # check if package + # Check if package was_packaged = getattr(plugin, 'is_package', False) - # check if activated - # these checks only use attributes - never use plugin supplied functions -> that would lead to arbitrary code execution!! + # Check if activated + # These checks only use attributes - never use plugin supplied functions -> that would lead to arbitrary code execution!! plug_name = plugin.PLUGIN_NAME plug_key = plugin.PLUGIN_SLUG if getattr(plugin, 'PLUGIN_SLUG', None) else plug_name plug_key = slugify(plug_key) # keys are slugs! @@ -186,23 +212,23 @@ class PluginsRegistry: raise error plugin_db_setting = None - # always activate if testing + # Always activate if testing if settings.PLUGIN_TESTING or (plugin_db_setting and plugin_db_setting.active): - # check if the plugin was blocked -> threw an error + # Check if the plugin was blocked -> threw an error if disabled: # option1: package, option2: file-based if (plugin.__name__ == disabled) or (plugin.__module__ == disabled): - # errors are bad so disable the plugin in the database + # Errors are bad so disable the plugin in the database if not settings.PLUGIN_TESTING: plugin_db_setting.active = False # TODO save the error to the plugin plugin_db_setting.save(no_reload=True) - # add to inactive plugins so it shows up in the ui + # Add to inactive plugins so it shows up in the ui self.plugins_inactive[plug_key] = plugin_db_setting continue # continue -> the plugin is not loaded - # init package + # Initialize package # now we can be sure that an admin has activated the plugin # TODO check more stuff -> as of Nov 2021 there are not many checks in place # but we could enhance those to check signatures, run the plugin against a whitelist etc. @@ -235,7 +261,7 @@ class PluginsRegistry: plugins = self.plugins.items() logger.info(f'Found {len(plugins)} active plugins') - self.activate_integration_globalsettings(plugins) + self.activate_integration_settings(plugins) self.activate_integration_app(plugins, force_reload=force_reload) def _deactivate_plugins(self): @@ -243,10 +269,9 @@ class PluginsRegistry: Run integration deactivation functions for all plugins """ self.deactivate_integration_app() - self.deactivate_integration_globalsettings() - # endregion + self.deactivate_integration_settings() - def activate_integration_globalsettings(self, plugins): + def activate_integration_settings(self, plugins): from common.models import InvenTreeSetting if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_GLOBALSETTING'): @@ -256,7 +281,7 @@ class PluginsRegistry: plugin_setting = plugin.settings self.mixins_settings[slug] = plugin_setting - def deactivate_integration_globalsettings(self): + def deactivate_integration_settings(self): # collect all settings plugin_settings = {} @@ -267,7 +292,6 @@ class PluginsRegistry: # clear cache self.mixins_Fsettings = {} - # region integration_app def activate_integration_app(self, plugins, force_reload=False): """activate AppMixin plugins - add custom apps and reload @@ -441,8 +465,6 @@ class PluginsRegistry: return True, [] except Exception as error: get_plugin_error(error, do_raise=True) - # endregion - # endregion plugin_registry = PluginsRegistry() diff --git a/InvenTree/plugin/serializers.py b/InvenTree/plugin/serializers.py index da171a604d..cc999a5a4f 100644 --- a/InvenTree/plugin/serializers.py +++ b/InvenTree/plugin/serializers.py @@ -1,5 +1,5 @@ """ -JSON serializers for Stock app +JSON serializers for plugin app """ # -*- coding: utf-8 -*- @@ -20,7 +20,8 @@ from plugin.models import PluginConfig, PluginSetting class PluginConfigSerializer(serializers.ModelSerializer): - """ Serializer for a PluginConfig: + """ + Serializer for a PluginConfig: """ meta = serializers.DictField(read_only=True) @@ -73,7 +74,7 @@ class PluginConfigInstallSerializer(serializers.Serializer): if not data.get('confirm'): raise ValidationError({'confirm': _('Installation not confirmed')}) if (not data.get('url')) and (not data.get('packagename')): - msg = _('Either packagenmae of url must be provided') + msg = _('Either packagename of URL must be provided') raise ValidationError({'url': msg, 'packagename': msg}) return data @@ -115,7 +116,7 @@ class PluginConfigInstallSerializer(serializers.Serializer): ret['result'] = str(error.output, 'utf-8') ret['error'] = True - # register plugins + # Register plugins # TODO return ret diff --git a/InvenTree/plugin/test_api.py b/InvenTree/plugin/test_api.py index fe1e9802bf..fdc97e407b 100644 --- a/InvenTree/plugin/test_api.py +++ b/InvenTree/plugin/test_api.py @@ -8,7 +8,7 @@ from InvenTree.api_tester import InvenTreeAPITestCase class PluginDetailAPITest(InvenTreeAPITestCase): """ - Tests the plugin AP I endpoints + Tests the plugin API endpoints """ roles = [ @@ -19,7 +19,7 @@ class PluginDetailAPITest(InvenTreeAPITestCase): ] def setUp(self): - self.MSG_NO_PKG = 'Either packagenmae of url must be provided' + self.MSG_NO_PKG = 'Either packagename of URL must be provided' self.PKG_NAME = 'minimal' super().setUp() diff --git a/InvenTree/plugin/test_integration.py b/InvenTree/plugin/test_integration.py index f88994384a..3d88fed4dd 100644 --- a/InvenTree/plugin/test_integration.py +++ b/InvenTree/plugin/test_integration.py @@ -42,7 +42,7 @@ class SettingsMixinTest(BaseMixinDefinition, TestCase): def test_function(self): # settings variable - self.assertEqual(self.mixin.globalsettings, self.TEST_SETTINGS) + self.assertEqual(self.mixin.settings, self.TEST_SETTINGS) # calling settings # not existing diff --git a/InvenTree/plugin/test_plugin.py b/InvenTree/plugin/test_plugin.py index 5724bdb0a9..2013ad43c8 100644 --- a/InvenTree/plugin/test_plugin.py +++ b/InvenTree/plugin/test_plugin.py @@ -1,4 +1,6 @@ -""" Unit tests for plugins """ +""" +Unit tests for plugins +""" from django.test import TestCase @@ -6,7 +8,6 @@ import plugin.plugin import plugin.integration from plugin.samples.integration.sample import SampleIntegrationPlugin from plugin.samples.integration.another_sample import WrongIntegrationPlugin, NoIntegrationPlugin -# from plugin.plugins import load_action_plugins, load_barcode_plugins import plugin.templatetags.plugin_extras as plugin_tags from plugin import plugin_registry diff --git a/InvenTree/plugin/urls.py b/InvenTree/plugin/urls.py index 46cdfd8a84..1457aaf6f1 100644 --- a/InvenTree/plugin/urls.py +++ b/InvenTree/plugin/urls.py @@ -1,6 +1,7 @@ """ URL lookup for plugin app """ + from django.conf.urls import url, include from plugin import plugin_registry @@ -10,9 +11,14 @@ PLUGIN_BASE = 'plugin' # Constant for links def get_plugin_urls(): - """returns a urlpattern that can be integrated into the global urls""" + """ + Returns a urlpattern that can be integrated into the global urls + """ + urls = [] + for plugin in plugin_registry.plugins.values(): if plugin.mixin_enabled('urls'): urls.append(plugin.urlpatterns) + return url(f'^{PLUGIN_BASE}/', include((urls, 'plugin'))) From 963ac35a5b17cddee6bb27b48291eb5c6474e288 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 4 Jan 2022 21:57:09 +1100 Subject: [PATCH 40/67] Tweaks for settings pages --- .../templates/InvenTree/settings/login.html | 18 +++++++++--------- .../templates/InvenTree/settings/plugin.html | 9 ++++----- .../templates/InvenTree/settings/report.html | 8 ++++---- .../templates/InvenTree/settings/sidebar.html | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/InvenTree/templates/InvenTree/settings/login.html b/InvenTree/templates/InvenTree/settings/login.html index b7f32465c6..a52e35fb12 100644 --- a/InvenTree/templates/InvenTree/settings/login.html +++ b/InvenTree/templates/InvenTree/settings/login.html @@ -13,19 +13,19 @@ - {% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_SSO" icon="fa-info-circle" %} - {% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_PWD_FORGOT" icon="fa-info-circle" %} - {% include "InvenTree/settings/setting.html" with key="LOGIN_MAIL_REQUIRED" icon="fa-info-circle" %} - {% include "InvenTree/settings/setting.html" with key="LOGIN_ENFORCE_MFA" %} + {% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_SSO" icon="fa-user-shield" %} + {% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_PWD_FORGOT" icon="fa-user-lock" %} + {% include "InvenTree/settings/setting.html" with key="LOGIN_MAIL_REQUIRED" icon="fa-at" %} + {% include "InvenTree/settings/setting.html" with key="LOGIN_ENFORCE_MFA" icon='fa-key' %} - {% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_REG" icon="fa-info-circle" %} - {% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_MAIL_TWICE" icon="fa-info-circle" %} - {% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_PWD_TWICE" icon="fa-info-circle" %} - {% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_SSO_AUTO" icon="fa-info-circle" %} - {% include "InvenTree/settings/setting.html" with key="SIGNUP_GROUP" %} + {% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_REG" icon="fa-user-plus" %} + {% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_MAIL_TWICE" icon="fa-at" %} + {% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_PWD_TWICE" icon="fa-user-lock" %} + {% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_SSO_AUTO" icon="fa-key" %} + {% include "InvenTree/settings/setting.html" with key="SIGNUP_GROUP" icon="fa-users" %}
{% trans 'Signup' %}
diff --git a/InvenTree/templates/InvenTree/settings/plugin.html b/InvenTree/templates/InvenTree/settings/plugin.html index ac3129eddc..960ec852b8 100644 --- a/InvenTree/templates/InvenTree/settings/plugin.html +++ b/InvenTree/templates/InvenTree/settings/plugin.html @@ -19,10 +19,9 @@
- {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_URL" %} - {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_NAVIGATION" %} - {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_GLOBALSETTING"%} - {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_APP"%} + {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_URL" icon="fa-link" %} + {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_NAVIGATION" icon="fa-sitemap" %} + {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_APP" icon="fa-rocket" %}
@@ -70,7 +69,7 @@ {% if mixin_list %} {% for mixin in mixin_list %} - {{ mixin.human_name }} + {{ mixin.human_name }} {% endfor %} {% endif %} diff --git a/InvenTree/templates/InvenTree/settings/report.html b/InvenTree/templates/InvenTree/settings/report.html index 89d26feba6..54c7175508 100644 --- a/InvenTree/templates/InvenTree/settings/report.html +++ b/InvenTree/templates/InvenTree/settings/report.html @@ -12,10 +12,10 @@ - {% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE" %} - {% include "InvenTree/settings/setting.html" with key="REPORT_DEFAULT_PAGE_SIZE" %} - {% include "InvenTree/settings/setting.html" with key="REPORT_DEBUG_MODE" %} - {% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE_TEST_REPORT" %} + {% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE" icon="file-pdf" %} + {% include "InvenTree/settings/setting.html" with key="REPORT_DEFAULT_PAGE_SIZE" icon="fa-print" %} + {% include "InvenTree/settings/setting.html" with key="REPORT_DEBUG_MODE" icon="fa-laptop-code" %} + {% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE_TEST_REPORT" icon="fa-vial" %}
diff --git a/InvenTree/templates/InvenTree/settings/sidebar.html b/InvenTree/templates/InvenTree/settings/sidebar.html index 13c370ac16..24f62f1e1c 100644 --- a/InvenTree/templates/InvenTree/settings/sidebar.html +++ b/InvenTree/templates/InvenTree/settings/sidebar.html @@ -49,7 +49,7 @@ {% include "sidebar_header.html" with text="Plugin Settings" %} -{% include "sidebar_item.html" with label='plugin' text="Plugin" icon="fa-plug" %} +{% include "sidebar_item.html" with label='plugin' text="Plugins" icon="fa-plug" %} {% plugin_list as pl_list %} {% for plugin_key, plugin in pl_list.items %} From ff80fe4dbf2d2fbb84554273246115c054e7182b Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 5 Jan 2022 15:14:03 +1100 Subject: [PATCH 41/67] Translation merge (#2499) * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin * Fix: New translations django.po from Crowdin --- InvenTree/locale/de/LC_MESSAGES/django.po | 961 +++++++++-------- InvenTree/locale/el/LC_MESSAGES/django.po | 959 ++++++++-------- InvenTree/locale/es/LC_MESSAGES/django.po | 1199 +++++++++++---------- InvenTree/locale/fr/LC_MESSAGES/django.po | 961 +++++++++-------- InvenTree/locale/he/LC_MESSAGES/django.po | 959 ++++++++-------- InvenTree/locale/id/LC_MESSAGES/django.po | 959 ++++++++-------- InvenTree/locale/it/LC_MESSAGES/django.po | 975 ++++++++--------- InvenTree/locale/ja/LC_MESSAGES/django.po | 961 +++++++++-------- InvenTree/locale/ko/LC_MESSAGES/django.po | 959 ++++++++-------- InvenTree/locale/nl/LC_MESSAGES/django.po | 969 +++++++++-------- InvenTree/locale/no/LC_MESSAGES/django.po | 961 +++++++++-------- InvenTree/locale/pl/LC_MESSAGES/django.po | 1005 ++++++++--------- InvenTree/locale/pt/LC_MESSAGES/django.po | 959 ++++++++-------- InvenTree/locale/ru/LC_MESSAGES/django.po | 983 ++++++++--------- InvenTree/locale/sv/LC_MESSAGES/django.po | 959 ++++++++-------- InvenTree/locale/th/LC_MESSAGES/django.po | 959 ++++++++-------- InvenTree/locale/tr/LC_MESSAGES/django.po | 961 +++++++++-------- InvenTree/locale/vi/LC_MESSAGES/django.po | 959 ++++++++-------- InvenTree/locale/zh/LC_MESSAGES/django.po | 961 +++++++++-------- 19 files changed, 9427 insertions(+), 9142 deletions(-) diff --git a/InvenTree/locale/de/LC_MESSAGES/django.po b/InvenTree/locale/de/LC_MESSAGES/django.po index 50aecd55eb..6e42d13b5d 100644 --- a/InvenTree/locale/de/LC_MESSAGES/django.po +++ b/InvenTree/locale/de/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:28\n" "Last-Translator: \n" "Language-Team: German\n" "Language: de_DE\n" @@ -36,8 +36,7 @@ msgstr "Datum eingeben" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Bestätigen" @@ -81,36 +80,41 @@ msgstr "Bestätigung der E-Mail Adresse" msgid "You must type the same email each time." msgstr "E-Mail Adressen müssen übereinstimmen." -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Doppelte Seriennummer: {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "Keine gültige Menge" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Keine Seriennummer angegeben" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Ungültige Gruppe: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "Doppelte Seriennummer: {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "Keine Seriennummern gefunden" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Anzahl der eindeutigen Seriennummern ({s}) muss mit der Anzahl ({q}) übereinstimmen" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "Fehlender externer Link" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Anhang" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Datei zum Anhängen auswählen" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "Link" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "Link zu einer externen URL" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Kommentar" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Datei-Kommentar" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Ungültige Auswahl" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Name" @@ -212,7 +216,7 @@ msgstr "Name" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Name" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Beschreibung (optional)" msgid "parent" msgstr "Eltern" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Muss eine gültige Nummer sein" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "Bauauftragsreferenz" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "Bauauftrag, zu dem dieser Bauauftrag zugwiesen ist" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "Bauauftrag, zu dem dieser Bauauftrag zugwiesen ist" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "Losnummer" msgid "Batch code for this build output" msgstr "Losnummer für dieses Endprodukt" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "Erstelldatum" @@ -822,7 +826,7 @@ msgstr "Nutzer der diesen Bauauftrag erstellt hat" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "Externer Link" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "Bauauftrag starten um Teile zuzuweisen" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "Dieses Endprodukt ist nicht vollständig zugewiesen" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "Status" msgid "A list of build outputs must be provided" msgstr "Eine Liste von Endprodukten muss angegeben werden" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "Stücklisten-Position" @@ -1010,7 +1014,7 @@ msgstr "Endprodukt muss auf den gleichen Bauauftrag verweisen" msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part muss auf dasselbe Teil verweisen wie der Bauauftrag" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "Teil muss auf Lager sein" @@ -1336,7 +1340,7 @@ msgstr "Fertiggestellte Endprodukte" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "Zuordnung abgeschlossen" msgid "All untracked stock items have been allocated" msgstr "Alle nicht verfolgten Lagerartikel wurden zugewiesen" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "Neuer Bauauftrag" @@ -1647,9 +1651,9 @@ msgstr "Kategorie-Parametervorlage kopieren" msgid "Copy category parameter templates when creating a part" msgstr "Kategorie-Parameter Vorlagen kopieren wenn ein Teil angelegt wird" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "Vorlage" @@ -1657,9 +1661,9 @@ msgstr "Vorlage" msgid "Parts are templates by default" msgstr "Teile sind standardmäßig Vorlagen" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "Baugruppe" @@ -1667,8 +1671,8 @@ msgstr "Baugruppe" msgid "Parts can be assembled from other components by default" msgstr "Teile können standardmäßig aus anderen Teilen angefertigt werden" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "Komponente" @@ -1676,7 +1680,7 @@ msgstr "Komponente" msgid "Parts can be used as sub-components by default" msgstr "Teile können standardmäßig in Baugruppen benutzt werden" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "Kaufbar" @@ -1684,8 +1688,8 @@ msgstr "Kaufbar" msgid "Parts are purchaseable by default" msgstr "Artikel sind grundsätzlich kaufbar" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "Verkäuflich" @@ -1693,10 +1697,10 @@ msgstr "Verkäuflich" msgid "Parts are salable by default" msgstr "Artikel sind grundsätzlich verkaufbar" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "Nachverfolgbar" @@ -1704,7 +1708,7 @@ msgstr "Nachverfolgbar" msgid "Parts are trackable by default" msgstr "Artikel sind grundsätzlich verfolgbar" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "Preisstaffelungs Anzahl" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "Preis" @@ -2224,7 +2228,7 @@ msgstr "Stückpreis für die angegebene Anzahl" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "Datei hochgeladen" @@ -2232,7 +2236,7 @@ msgstr "Datei hochgeladen" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "Übereinstimmende Felder" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "Vorheriger Schritt" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "URL" @@ -2324,7 +2328,7 @@ msgstr "Anlaufstelle" msgid "Link to external company information" msgstr "Link auf externe Firmeninformation" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "Bild" @@ -2375,24 +2379,25 @@ msgstr "Teil auswählen" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "Hersteller" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "Hersteller auswählen" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "MPN" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "Hersteller-Teilenummer" @@ -2417,8 +2422,8 @@ msgstr "Parametername" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "Wert" @@ -2426,10 +2431,10 @@ msgstr "Wert" msgid "Parameter value" msgstr "Parameterwert" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "Einheiten" @@ -2447,22 +2452,23 @@ msgstr "Verlinktes Herstellerteil muss dasselbe Basisteil referenzieren" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "Zulieferer" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "Zulieferer auswählen" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "SKU (Lagerbestandseinheit)" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "Lagerbestandseinheit (SKU) des Zulieferers" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "Zuliefererbeschreibung des Teils" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "Notiz" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "Basiskosten" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "Mindestpreis" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "Verpackungen" @@ -2502,7 +2508,7 @@ msgstr "Verpackungen" msgid "Part packaging" msgstr "Teile-Verpackungen" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "Vielfache" @@ -2563,10 +2569,11 @@ msgstr "Bild von URL herunterladen" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "Kunde" @@ -2596,7 +2603,7 @@ msgstr "Neues Zuliefererteil anlegen" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "Neues Zuliefererteil" @@ -2604,8 +2611,8 @@ msgstr "Neues Zuliefererteil" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "Optionen" @@ -2633,7 +2640,7 @@ msgstr "Herstellerteile" msgid "Create new manufacturer part" msgstr "Neues Herstellerteil anlegen" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "Neues Herstellerteil" @@ -2695,15 +2702,15 @@ msgstr "Zugeordneter Bestand" msgid "Company Notes" msgstr "Firmenbemerkungen" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "Zuliefererteil entfernen?" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "Alle ausgewählten Zulieferteile werden gelöscht" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "Teil bestellen" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "Herstellerteil bearbeiten" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "Herstellerteil löschen" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "Zulieferer" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "Zuliefererteil entfernen" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "Löschen" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "Parameter löschen" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "Parameter hinzufügen" @@ -2810,17 +2817,17 @@ msgstr "Zugewiesene Lagerartikel" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "Zuliefererteil" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "Zuliefererteil bearbeiten" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "Zuliefererteil entfernen" @@ -2857,7 +2864,7 @@ msgstr "Preisinformationen ansehen" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "Preisstaffel hinzufügen" @@ -2865,11 +2872,11 @@ msgstr "Preisstaffel hinzufügen" msgid "No price break information found" msgstr "Keine Informationen zur Preisstaffel gefunden" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "Preisstaffel löschen" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "Preisstaffel bearbeiten" @@ -2887,9 +2894,9 @@ msgstr "Preisstaffel löschen" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "Bestand" @@ -3181,7 +3188,7 @@ msgstr "Bestellung" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "Bestellung" @@ -3192,7 +3199,7 @@ msgstr "Zuliefererteil" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "Empfangen" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "Auftrag bearbeiten" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "Warnung" @@ -3811,23 +3817,35 @@ msgstr "Stückpreis für {part} auf {price} aktualisiert" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "{part} Stückpreis auf {price} und Menge auf {qty} aktualisiert" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "Muss größer als 0 sein" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "Muss eine gültige Nummer sein" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "Standort für anfänglichen Bestand angeben" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "Dieses Feld ist erforderlich" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "Standard-Lagerort" @@ -3836,43 +3854,19 @@ msgstr "Standard-Lagerort" msgid "Available Stock" msgstr "Verfügbarer Bestand" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "Ausgangsteil" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "Teil für Stücklisten-Kopie auswählen" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "Stücklisten-Position(en) löschen" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "Kopie von Stückliste bestätigen" - -#: part/forms.py:97 -msgid "validate" -msgstr "kontrollieren" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "Bestätigen, dass die Stückliste korrekt ist" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "Teil-Kategorie wählen" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "Parameter-Vorlage zu Kategorien dieser Ebene hinzufügen" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "Parameter-Vorlage zu allen Kategorien hinzufügen" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "Menge für die Preisberechnung" @@ -3888,7 +3882,7 @@ msgstr "Standard Stichwörter" msgid "Default keywords for parts in this category" msgstr "Standard-Stichworte für Teile dieser Kategorie" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "Teil-Kategorie" @@ -3905,7 +3899,7 @@ msgstr "Teil-Kategorien" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "Teile" @@ -3914,384 +3908,415 @@ msgstr "Teile" msgid "Invalid choice for parent part" msgstr "Ungültige Auswahl für übergeordnetes Teil" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "Teil '{p1}' wird in Stückliste für Teil '{p2}' benutzt (rekursiv)" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "Nächste verfügbare Seriennummern wären" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "Nächste verfügbare Seriennummer ist" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "Die neuste Seriennummer ist" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "Doppelte IPN in den Teil-Einstellungen nicht erlaubt" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "Name des Teils" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "Ist eine Vorlage" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "Ist dieses Teil eine Vorlage?" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "Ist dieses Teil eine Variante eines anderen Teils?" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "Variante von" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "Beschreibung des Teils" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "Schlüsselwörter" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "Schlüsselworte um die Sichtbarkeit in Suchergebnissen zu verbessern" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "Kategorie" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "Teile-Kategorie" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "IPN (Interne Produktnummer)" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "Interne Teilenummer" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "Revisions- oder Versionsnummer" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "Revision" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "Standard Zulieferer" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "Standard Zuliefererteil" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "Standard Ablaufzeit" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "Ablauf-Zeit (in Tagen) für Bestand dieses Teils" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "Minimaler Bestand" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "Minimal zulässiger Bestand" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "Stock Keeping Units (SKU) für dieses Teil" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "Kann dieses Teil aus anderen Teilen angefertigt werden?" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "Kann dieses Teil zum Bauauftrag von anderen genutzt werden?" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "Hat dieses Teil Tracking für einzelne Objekte?" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "Kann dieses Teil von externen Zulieferern gekauft werden?" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "Kann dieses Teil an Kunden verkauft werden?" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "Aktiv" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "Ist dieses Teil aktiv?" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "Ist dieses Teil virtuell, wie zum Beispiel eine Software oder Lizenz?" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "Bemerkungen - unterstüzt Markdown-Formatierung" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "Prüfsumme der Stückliste gespeichert" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "Stückliste kontrolliert von" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "BOM Kontrolldatum" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "Erstellungs-Nutzer" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "Mehrere verkaufen" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "Test-Vorlagen können nur für verfolgbare Teile angelegt werden" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "Ein Test mit diesem Namen besteht bereits für dieses Teil" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "Test-Name" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "Namen für diesen Test eingeben" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "Test-Beschreibung" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "Beschreibung für diesen Test eingeben" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "Benötigt" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "Muss dieser Test erfolgreich sein?" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "Erfordert Wert" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "Muss für diesen Test ein Wert für das Test-Ergebnis eingetragen werden?" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "Anhang muss eingegeben werden" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "Muss für diesen Test ein Anhang für das Test-Ergebnis hinzugefügt werden?" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "Ungültiges Zeichen im Vorlagename ({c})" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "Vorlagen-Name des Parameters muss eindeutig sein" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "Name des Parameters" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "Einheit des Parameters" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "Ausgangsteil" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "Parameter Vorlage" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "Wert" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "Parameter Wert" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "Standard-Wert" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "Standard Parameter Wert" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "Ausgangsteil auswählen" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "Untergeordnetes Teil" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "Teil für die Nutzung in der Stückliste auswählen" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "Stücklisten-Anzahl für dieses Stücklisten-Teil" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "Optional" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "Diese Stücklisten-Position ist optional" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "Überschuss" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "Geschätzter Ausschuss (absolut oder prozentual)" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "Referenz der Postion auf der Stückliste" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "Notizen zur Stücklisten-Position" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "Prüfsumme" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "Geerbt" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Diese Stücklisten-Position wird in die Stücklisten von Teil-Varianten vererbt" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "Varianten zulassen" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Bestand von Varianten kann für diese Stücklisten-Position verwendet werden" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "Menge muss eine Ganzzahl sein" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "Zuliefererteil muss festgelegt sein" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "Stücklisten Ersatzteile" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "Ersatzteil kann nicht identisch mit dem Hauptteil sein" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "Übergeordnete Stücklisten Position" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "Ersatzteil" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "Teil 1" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "Teil 2" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "verknüpftes Teil auswählen" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "Fehler bei Verwandschaft: Ist das Teil mit sich selbst verwandt oder ist das die Verwandtschaft nicht eindeutig?" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "Benachrichtigungen über geringen Bestand" @@ -4315,7 +4340,7 @@ msgstr "Die Stückliste für %(part)s wurde zuletzt von %(checker)s am msgid "The BOM for %(part)s has not been validated." msgstr "Die Stückliste für %(part)s wurde noch nicht kontrolliert." -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "Stücklisten-Aktionen" @@ -4323,10 +4348,6 @@ msgstr "Stücklisten-Aktionen" msgid "Delete Items" msgstr "Einträge löschen" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "Dieses Teil hat bereits eine Stückliste" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "Teil auswählen" @@ -4355,15 +4376,6 @@ msgstr "Vorlage für Stückliste" msgid "Each part must already exist in the database" msgstr "Jedes Teil muss bereits in der Datenbank bestehen" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "Bestätigen Sie das die Stückliste für
%(part)s korrekt ist" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "Damit wird jede Zeile der Stückliste kontrolliert" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "Sie haben Benachrichtigungen für diese Kategorie abonniert" @@ -4500,7 +4512,7 @@ msgstr "Wenn diese Kat. gelöscht wird, werden diese Teile in die oberste Kat. v msgid "Import Parts" msgstr "Teile importieren" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "Teil duplizieren" @@ -4561,118 +4573,118 @@ msgstr "neue Variante anlegen" msgid "Add new parameter" msgstr "Parameter hinzufügen" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "Verknüpfte Teile" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "Verknüpftes Teil hinzufügen" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "Stückliste" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "Export-Aktionen" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "Stückliste exportieren" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "Stücklisten-Bericht drucken" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "Stückliste hochladen" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "Stückliste kopieren" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "Stückliste überprüfen" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "Neue Stücklisten-Position" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "Stücklisten-Position hinzufügen" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "Baugruppen" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "Gefertigte Teile" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "Bauauftragszuweisungen" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "Zulieferer" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "Teil-Hersteller" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "Herstellerteile löschen" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "Ausgewählte Stücklistenpositionen löschen?" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "Alle ausgewählte Stücklistenpositionen werden gelöscht" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "Stücklisten-Position anlegen" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "verknüpftes Teil" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "verknüpftes Teil hinzufügen" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "Testergebnis-Vorlage hinzufügen" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "Teilenotizen bearbeiten" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "Stückpreis Einkauf - %(currency)s" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "Stückpreis Differenz - %(currency)s" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "Stückpreis Zulieferer - %(currency)s" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "Stückpreis - %(currency)s" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "Teil ist virtuell (kein physisches Teil)" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "Inaktiv" @@ -4806,7 +4818,7 @@ msgstr "Dieses Teil ist eine Variante von %(link)s" msgid "In Stock" msgstr "Auf Lager" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "Bestellt" @@ -4826,8 +4838,8 @@ msgstr "Zu Bauaufträgen zugeordnet" msgid "Can Build" msgstr "Herstellbar" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "Im Bau" @@ -5018,7 +5030,7 @@ msgstr "Für dieses Teil sind keine Bestandspreise verfügbar." msgid "Internal Cost" msgstr "Interne Kosten" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "Interne Preisspanne hinzufügen" @@ -5039,8 +5051,8 @@ msgid "Set category for the following parts" msgstr "Kategorie für Teile setzen" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "Kein Bestand" @@ -5094,87 +5106,71 @@ msgstr "Teilbild aktualisiert" msgid "Part image not found" msgstr "Teilbild nicht gefunden" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "Stückliste duplizieren" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "bestätige Duplizierung Stückliste von übergeordneter Stückliste" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "Bestätigen, dass Stückliste korrekt ist" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "überprüfte Stückliste" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "Teile zuordnen" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "Stückliste exportieren" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "Löschen des Teils bestätigen" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "Teil wurde gelöscht" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "Teilbepreisung" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "Teilparametervorlage anlegen" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "Teilparametervorlage bearbeiten" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "Teilparametervorlage löschen" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "Teil-Kategorie bearbeiten" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "Teil-Kategorie löschen" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "Teil-Kategorie wurde gelöscht" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "Kategorieparametervorlage anlegen" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "Kategorieparametervorlage bearbeiten" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "Kategorieparametervorlage löschen" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "neue Preisstaffel hinzufügt" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "Interne Preisspanne bearbeiten" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "Interne Preisspanne löschen" @@ -5210,11 +5206,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5624,7 +5620,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5697,7 +5693,7 @@ msgstr "Anzahl darf nicht die verfügbare Menge überschreiten ({q})" msgid "Enter serial numbers for new items" msgstr "Seriennummern für neue Teile eingeben" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "Ziel-Bestand" @@ -5709,63 +5705,63 @@ msgstr "Optionales Notizfeld" msgid "Serial numbers cannot be assigned to this part" msgstr "Seriennummern können diesem Teil nicht zugewiesen werden" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "Eine Liste der Lagerbestände muss angegeben werden" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "Primärschlüssel Lagerelement" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "Bestandsbewegungsnotizen" @@ -6380,22 +6376,22 @@ msgstr "Anmeldeeinstellungen" msgid "Signup" msgstr "Anmelden" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "Einstellungen" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6446,11 +6442,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6484,53 +6475,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "Commit-Datum" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "Commit-Hash" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7264,47 +7255,55 @@ msgstr "Fehler 404: Ressource nicht gefunden" msgid "The requested resource could not be located on the server" msgstr "Die angefragte Ressource kann auf diesem Server nicht gefunden werden" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "Fehler 408: Zeitüberschreitung" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "Verbindungszeitüberschreitung bei der Datenanforderung" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "Unbehandelter Fehler-Code" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "Fehler-Code" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "Keine Anhänge gefunden" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "Anhang bearbeiten" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "Löschen bestätigen" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "Anhang löschen" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "Hochladedatum" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "Anhang bearbeiten" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "Anhang löschen" @@ -7697,8 +7696,8 @@ msgstr "Keine passenden Lagerbestände" msgid "No builds matching query" msgstr "Keine Bauaufträge passen zur Anfrage" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "Auswählen" @@ -7763,55 +7762,55 @@ msgstr "Teile geliefert" msgid "Parts Manufactured" msgstr "Hersteller-Teile" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "Keine Firmeninformation gefunden" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "Die folgenden Herstellerteile werden gelöscht" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "Herstellerteile löschen" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "Keine Herstellerteile gefunden" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "Vorlagenteil" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "Baugruppe" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "Keine Parameter gefunden" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "Parameter bearbeiten" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "Parameter löschen" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "Parameter bearbeiten" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "Parameter löschen" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "Keine Zuliefererteile gefunden" @@ -8112,7 +8111,7 @@ msgstr "Empfang der Teile bestätigen" msgid "Receive Purchase Order Items" msgstr "Bestellpositionen erhalten" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "Keine Bestellungen gefunden" @@ -8137,7 +8136,7 @@ msgid "Total" msgstr "Summe" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "Stück-Preis" @@ -8153,7 +8152,7 @@ msgstr "Position bearbeiten" msgid "Delete line item" msgstr "Position löschen" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "Position empfangen" @@ -8262,216 +8261,232 @@ msgstr "Stückpreis aktualisieren" msgid "No matching line items" msgstr "Keine passenden Positionen gefunden" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "Teileigenschaften" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "Erstellungsoptionen für Teile" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "Einstellungen für Teilkopien" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "Zuliefereroptionen" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "Teil-Kategorie hinzufügen" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "Anfänglichen Bestand erstellen" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "Anfänglichen Bestand für dieses Teil erstellen" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "Start-Bestandsmenge" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "Menge des anfänglichen Bestands für dieses Teil angeben" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "Zielstandort auswählen" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "Kategorieparameter kopieren" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "Parametervorlagen aus der ausgewählten Bauteilkategorie kopieren" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "Zuliefererdaten hinzufügen" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "Erstelle ersten Lieferanten für dieses Teil" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "Bild kopieren" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "Bild vom Originalteil kopieren" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "Stückliste vom Originalteil kopieren" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "Parameter kopieren" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "Parameterdaten vom Originalteil kopieren" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "Übergeordnete Teilkategorie" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "Teil bearbeiten" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "Teil bearbeitet" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "Sie haben Benachrichtigungen für dieses Teil abonniert" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "Sie haben Benachrichtigungen für dieses Teil abonniert" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "Benachrichtigungen für dieses Teil abonnieren" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "Sie haben Benachrichtigungen für dieses Teil abgemeldet" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "überprüfte Stückliste" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "Nachverfolgbares Teil" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "virtuelles Teil" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "Abonnierter Teil" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "Verkäufliches Teil" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "Keine Varianten gefunden" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "Teile-Beziehung löschen" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "Teile-Beziehung löschen" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "Keine Teile gefunden" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "Keine Kategorie" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "Bestand niedrig" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "Listenansicht" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "Rasteransicht" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "Baumansicht" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "Abonnierte Kategorie" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "Pfad" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "Keine zur Anfrage passenden Testvorlagen" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "Testergebnis bearbeiten" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "Testergebnis löschen" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "Dieses Testergebnis ist für ein Hauptteil" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "Testergebnis-Vorlage bearbeiten" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "Testergebnis-Vorlage löschen" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "Keine ${human_name} Informationen gefunden" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "${human_name} bearbeiten" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "${human_name} löschen" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "Einzelpreis" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "Einzelpreisdifferenz" @@ -8909,12 +8924,12 @@ msgstr "Lagerorte einschließen" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "Unterkategorien einschließen" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "Abonniert" @@ -9061,27 +9076,27 @@ msgstr "Bestellstatus" msgid "Outstanding" msgstr "ausstehend" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "Teile in Unterkategorien einschließen" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "Hat IPN" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "Teil hat Interne Teilenummer" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "Aktive Teile anzeigen" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "verfügbarer Bestand" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "Käuflich" diff --git a/InvenTree/locale/el/LC_MESSAGES/django.po b/InvenTree/locale/el/LC_MESSAGES/django.po index 0cc31b6263..4cbc3642ce 100644 --- a/InvenTree/locale/el/LC_MESSAGES/django.po +++ b/InvenTree/locale/el/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Greek\n" "Language: el_GR\n" @@ -36,8 +36,7 @@ msgstr "" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" +msgid "Invalid group {group}" msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "" @@ -212,7 +216,7 @@ msgstr "" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/es/LC_MESSAGES/django.po b/InvenTree/locale/es/LC_MESSAGES/django.po index 879766a7a9..586f846e4b 100644 --- a/InvenTree/locale/es/LC_MESSAGES/django.po +++ b/InvenTree/locale/es/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:28\n" "Last-Translator: \n" "Language-Team: Spanish, Mexico\n" "Language: es_MX\n" @@ -36,8 +36,7 @@ msgstr "Ingrese fecha" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Confirmar" @@ -81,36 +80,41 @@ msgstr "Confirmación de email" msgid "You must type the same email each time." msgstr "Debe escribir el mismo correo electrónico cada vez." -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Duplicar serie: {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "Cantidad proporcionada no válida" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Cadena de número de serie vacía" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Grupo inválido: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "Serie duplicada: {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "No se encontraron números de serie" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Número único de número de serie ({s}) debe coincidir con la cantidad ({q})" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "Falta enlace externo" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Adjunto" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Seleccionar archivo a adjuntar" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "Enlace" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "Enlace a URL externa" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Comentario" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Comentario de archivo" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Elección no válida" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Nombre" @@ -212,7 +216,7 @@ msgstr "Nombre" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Nombre" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Descripción (opcional)" msgid "parent" msgstr "principal" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Debe ser un número válido" @@ -270,63 +274,63 @@ msgstr "Español (México)" #: InvenTree/settings.py:703 msgid "French" -msgstr "" +msgstr "Francés" #: InvenTree/settings.py:704 msgid "Hebrew" -msgstr "" +msgstr "Hebreo" #: InvenTree/settings.py:705 msgid "Italian" -msgstr "" +msgstr "Italiano" #: InvenTree/settings.py:706 msgid "Japanese" -msgstr "" +msgstr "Japonés" #: InvenTree/settings.py:707 msgid "Korean" -msgstr "" +msgstr "Coreano" #: InvenTree/settings.py:708 msgid "Dutch" -msgstr "" +msgstr "Holandés" #: InvenTree/settings.py:709 msgid "Norwegian" -msgstr "" +msgstr "Noruego" #: InvenTree/settings.py:710 msgid "Polish" -msgstr "" +msgstr "Polaco" #: InvenTree/settings.py:711 msgid "Portugese" -msgstr "" +msgstr "Portugués" #: InvenTree/settings.py:712 msgid "Russian" -msgstr "" +msgstr "Ruso" #: InvenTree/settings.py:713 msgid "Swedish" -msgstr "" +msgstr "Sueco" #: InvenTree/settings.py:714 msgid "Thai" -msgstr "" +msgstr "Tailandés" #: InvenTree/settings.py:715 msgid "Turkish" -msgstr "" +msgstr "Turco" #: InvenTree/settings.py:716 msgid "Vietnamese" -msgstr "" +msgstr "Vietnamita" #: InvenTree/settings.py:717 msgid "Chinese" -msgstr "" +msgstr "Chino" #: InvenTree/status.py:94 msgid "Background worker check failed" @@ -334,114 +338,114 @@ msgstr "" #: InvenTree/status.py:98 msgid "Email backend not configured" -msgstr "" +msgstr "No se ha configurado el backend de correo" #: InvenTree/status.py:101 msgid "InvenTree system health checks failed" -msgstr "" +msgstr "Las comprobaciones de estado del sistema InvenTree fallaron" #: InvenTree/status_codes.py:101 InvenTree/status_codes.py:142 #: InvenTree/status_codes.py:316 templates/js/translated/table_filters.js:313 msgid "Pending" -msgstr "" +msgstr "Pendiente" #: InvenTree/status_codes.py:102 msgid "Placed" -msgstr "" +msgstr "Colocado" #: InvenTree/status_codes.py:103 InvenTree/status_codes.py:319 #: order/templates/order/order_base.html:128 #: order/templates/order/sales_order_base.html:132 msgid "Complete" -msgstr "" +msgstr "Terminado" #: InvenTree/status_codes.py:104 InvenTree/status_codes.py:144 #: InvenTree/status_codes.py:318 msgid "Cancelled" -msgstr "" +msgstr "Cancelado" #: InvenTree/status_codes.py:105 InvenTree/status_codes.py:145 #: InvenTree/status_codes.py:187 msgid "Lost" -msgstr "" +msgstr "Perdido" #: InvenTree/status_codes.py:106 InvenTree/status_codes.py:146 #: InvenTree/status_codes.py:189 msgid "Returned" -msgstr "" +msgstr "Devuelto" #: InvenTree/status_codes.py:143 order/models.py:941 #: templates/js/translated/order.js:1980 templates/js/translated/order.js:2255 msgid "Shipped" -msgstr "" +msgstr "Enviado" #: InvenTree/status_codes.py:183 msgid "OK" -msgstr "" +msgstr "OK" #: InvenTree/status_codes.py:184 msgid "Attention needed" -msgstr "" +msgstr "Atención necesaria" #: InvenTree/status_codes.py:185 msgid "Damaged" -msgstr "" +msgstr "Dañado" #: InvenTree/status_codes.py:186 msgid "Destroyed" -msgstr "" +msgstr "Destruido" #: InvenTree/status_codes.py:188 msgid "Rejected" -msgstr "" +msgstr "Rechazado" #: InvenTree/status_codes.py:272 msgid "Legacy stock tracking entry" -msgstr "" +msgstr "Entrada antigua de rastreo de stock" #: InvenTree/status_codes.py:274 msgid "Stock item created" -msgstr "" +msgstr "Artículo de stock creado" #: InvenTree/status_codes.py:276 msgid "Edited stock item" -msgstr "" +msgstr "Elemento de stock editado" #: InvenTree/status_codes.py:277 msgid "Assigned serial number" -msgstr "" +msgstr "Número de serie asignado" #: InvenTree/status_codes.py:279 msgid "Stock counted" -msgstr "" +msgstr "Stock contado" #: InvenTree/status_codes.py:280 msgid "Stock manually added" -msgstr "" +msgstr "Stock añadido manualmente" #: InvenTree/status_codes.py:281 msgid "Stock manually removed" -msgstr "" +msgstr "Stock eliminado manualmente" #: InvenTree/status_codes.py:283 msgid "Location changed" -msgstr "" +msgstr "Ubicación cambiada" #: InvenTree/status_codes.py:285 msgid "Installed into assembly" -msgstr "" +msgstr "Instalado en el ensamblaje" #: InvenTree/status_codes.py:286 msgid "Removed from assembly" -msgstr "" +msgstr "Retirado del ensamblaje" #: InvenTree/status_codes.py:288 msgid "Installed component item" -msgstr "" +msgstr "Artículo del componente instalado" #: InvenTree/status_codes.py:289 msgid "Removed component item" -msgstr "" +msgstr "Elemento de componente eliminado" #: InvenTree/status_codes.py:291 msgid "Split from parent item" @@ -453,19 +457,19 @@ msgstr "" #: InvenTree/status_codes.py:294 templates/js/translated/stock.js:2064 msgid "Merged stock items" -msgstr "" +msgstr "Artículos de stock combinados" #: InvenTree/status_codes.py:296 templates/js/translated/table_filters.js:213 msgid "Sent to customer" -msgstr "" +msgstr "Enviado al cliente" #: InvenTree/status_codes.py:297 msgid "Returned from customer" -msgstr "" +msgstr "Devuelto por el cliente" #: InvenTree/status_codes.py:299 msgid "Build order output created" -msgstr "" +msgstr "Orden de ensamble Trabajo de ensamblaje creado" #: InvenTree/status_codes.py:300 msgid "Build order output completed" @@ -473,7 +477,7 @@ msgstr "" #: InvenTree/status_codes.py:302 msgid "Received against purchase order" -msgstr "" +msgstr "Recibido contra la orden de compra" #: InvenTree/status_codes.py:317 msgid "Production" @@ -481,103 +485,103 @@ msgstr "" #: InvenTree/validators.py:23 msgid "Not a valid currency code" -msgstr "" +msgstr "No es un código de moneda válido" #: InvenTree/validators.py:51 msgid "Invalid character in part name" -msgstr "" +msgstr "Carácter inválido en el nombre del artículo" #: InvenTree/validators.py:64 #, python-brace-format msgid "IPN must match regex pattern {pat}" -msgstr "" +msgstr "El IPN debe coincidir con la expresión regular {pat}" #: InvenTree/validators.py:78 InvenTree/validators.py:92 #: InvenTree/validators.py:106 #, python-brace-format msgid "Reference must match pattern {pattern}" -msgstr "" +msgstr "La referencia debe coincidir con la expresión regular {pattern}" #: InvenTree/validators.py:114 #, python-brace-format msgid "Illegal character in name ({x})" -msgstr "" +msgstr "Carácter ilegal en el nombre ({x})" #: InvenTree/validators.py:133 InvenTree/validators.py:149 msgid "Overage value must not be negative" -msgstr "" +msgstr "El valor excedente no debe ser negativo" #: InvenTree/validators.py:151 msgid "Overage must not exceed 100%" -msgstr "" +msgstr "El excedente no debe superar el 100%" #: InvenTree/validators.py:158 msgid "Overage must be an integer value or a percentage" -msgstr "" +msgstr "El excedente debe ser un valor entero o un porcentaje" #: InvenTree/views.py:538 msgid "Delete Item" -msgstr "" +msgstr "Eliminar elemento" #: InvenTree/views.py:587 msgid "Check box to confirm item deletion" -msgstr "" +msgstr "Marque la casilla para confirmar la eliminación del artículo" #: InvenTree/views.py:602 templates/InvenTree/settings/user.html:21 msgid "Edit User Information" -msgstr "" +msgstr "Editar datos del usuario" #: InvenTree/views.py:613 templates/InvenTree/settings/user.html:19 msgid "Set Password" -msgstr "" +msgstr "Configurar Contraseña" #: InvenTree/views.py:632 msgid "Password fields must match" -msgstr "" +msgstr "Los campos de contraseña deben coincidir" #: InvenTree/views.py:883 templates/navbar.html:126 msgid "System Information" -msgstr "" +msgstr "Información del sistema" #: barcodes/api.py:54 barcodes/api.py:151 msgid "Must provide barcode_data parameter" -msgstr "" +msgstr "Debe proporcionar el parámetro barcode_data" #: barcodes/api.py:127 msgid "No match found for barcode data" -msgstr "" +msgstr "No se encontró ninguna coincidencia para los datos del código de barras" #: barcodes/api.py:129 msgid "Match found for barcode data" -msgstr "" +msgstr "Coincidencia encontrada para datos de códigos de barras" #: barcodes/api.py:154 msgid "Must provide stockitem parameter" -msgstr "" +msgstr "Debe proporcionar el parámetro stockitem" #: barcodes/api.py:161 msgid "No matching stock item found" -msgstr "" +msgstr "No se ha encontrado ningún artículo de stock que coincida" #: barcodes/api.py:191 msgid "Barcode already matches Stock Item" -msgstr "" +msgstr "El código de barras ya corresponde a un Elemento del Stock" #: barcodes/api.py:195 msgid "Barcode already matches Stock Location" -msgstr "" +msgstr "El código de barras ya corresponde a una Ubicación de Stock" #: barcodes/api.py:199 msgid "Barcode already matches Part" -msgstr "" +msgstr "El código de barras ya corresponde a una parte" #: barcodes/api.py:205 barcodes/api.py:217 msgid "Barcode hash already matches Stock Item" -msgstr "" +msgstr "La comprobación (hash) del código de barras ya corresponde a un Elemento del Stock" #: barcodes/api.py:223 msgid "Barcode associated with Stock Item" -msgstr "" +msgstr "Código de barras asignado al Elemento del Stock" #: build/forms.py:36 build/models.py:1286 #: build/templates/build/build_base.html:82 @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,13 +611,13 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" -msgstr "" +msgstr "Cantidad" #: build/forms.py:37 msgid "Enter quantity for build output" @@ -623,7 +627,7 @@ msgstr "" #: stock/serializers.py:314 templates/js/translated/stock.js:230 #: templates/js/translated/stock.js:384 msgid "Serial Numbers" -msgstr "" +msgstr "Números de serie" #: build/forms.py:43 msgid "Enter serial numbers for build outputs" @@ -639,11 +643,11 @@ msgstr "" #: build/forms.py:94 msgid "Mark build as complete" -msgstr "" +msgstr "Marcar construcción como completa" #: build/forms.py:107 msgid "Confirm cancel" -msgstr "" +msgstr "¿Deseas cancelar?" #: build/forms.py:107 build/views.py:65 msgid "Confirm build cancellation" @@ -658,7 +662,7 @@ msgstr "Opción no válida para el armado principal" #: report/templates/report/inventree_build_order_base.html:106 #: templates/js/translated/build.js:402 msgid "Build Order" -msgstr "" +msgstr "Orden de Producción" #: build/models.py:138 build/templates/build/build_base.html:13 #: build/templates/build/index.html:8 build/templates/build/index.html:12 @@ -668,25 +672,25 @@ msgstr "" #: templates/InvenTree/search.html:139 #: templates/InvenTree/settings/sidebar.html:43 users/models.py:44 msgid "Build Orders" -msgstr "" +msgstr "Ordenes de Producción" #: build/models.py:198 msgid "Build Order Reference" -msgstr "" +msgstr "Referencia de Orden de Producción" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 #: templates/js/translated/bom.js:547 templates/js/translated/build.js:1124 #: templates/js/translated/order.js:1050 templates/js/translated/order.js:2144 msgid "Reference" -msgstr "" +msgstr "Referencia" #: build/models.py:210 msgid "Brief description of the build" -msgstr "" +msgstr "Breve descripción de la producción" #: build/models.py:219 build/templates/build/build_base.html:164 #: build/templates/build/detail.html:88 @@ -695,15 +699,15 @@ msgstr "Armado Principal" #: build/models.py:220 msgid "BuildOrder to which this build is allocated" -msgstr "" +msgstr "Orden de Producción a la cual esta producción pertenece" #: build/models.py:225 build/templates/build/build_base.html:77 #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,34 +720,34 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 msgid "Part" -msgstr "" +msgstr "Parte" #: build/models.py:233 msgid "Select part to build" -msgstr "" +msgstr "Seleccionar parte a producir" #: build/models.py:238 msgid "Sales Order Reference" -msgstr "" +msgstr "Referencia de Orden de Venta" #: build/models.py:242 msgid "SalesOrder to which this build is allocated" -msgstr "" +msgstr "Ordenes de Venta a la cual esta producción pertenece" #: build/models.py:247 templates/js/translated/build.js:1352 #: templates/js/translated/order.js:1564 msgid "Source Location" -msgstr "" +msgstr "Ubicación de origen" #: build/models.py:251 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" @@ -751,7 +755,7 @@ msgstr "" #: build/models.py:256 msgid "Destination Location" -msgstr "" +msgstr "Ubicación de destino" #: build/models.py:260 msgid "Select location where the completed items will be stored" @@ -759,7 +763,7 @@ msgstr "Seleccione la ubicación donde se almacenarán los elementos completados #: build/models.py:264 msgid "Build Quantity" -msgstr "" +msgstr "Cantidad a crear" #: build/models.py:267 msgid "Number of stock items to build" @@ -783,20 +787,20 @@ msgstr "" #: build/models.py:285 stock/models.py:531 msgid "Batch Code" -msgstr "" +msgstr "Numero de lote" #: build/models.py:289 msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" -msgstr "" +msgstr "Fecha de Creación" #: build/models.py:296 order/models.py:558 msgid "Target completion date" -msgstr "" +msgstr "Fecha de finalización objetivo" #: build/models.py:297 msgid "Target date for build completion. Build will be overdue after this date." @@ -805,28 +809,28 @@ msgstr "" #: build/models.py:300 order/models.py:252 #: templates/js/translated/build.js:1703 msgid "Completion Date" -msgstr "" +msgstr "Fecha de finalización" #: build/models.py:306 msgid "completed by" -msgstr "" +msgstr "terminado por" #: build/models.py:314 templates/js/translated/build.js:1674 msgid "Issued by" -msgstr "" +msgstr "Emitido por" #: build/models.py:315 msgid "User who issued this build order" -msgstr "" +msgstr "El usuario que emitió esta orden" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" -msgstr "" +msgstr "Responsable" #: build/models.py:324 msgid "User responsible for this build order" @@ -838,26 +842,26 @@ msgstr "" #: part/templates/part/part_base.html:354 stock/models.py:525 #: stock/templates/stock/item_base.html:372 msgid "External Link" -msgstr "" +msgstr "Link externo" #: build/models.py:334 build/serializers.py:201 #: build/templates/build/sidebar.html:21 company/models.py:142 #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" -msgstr "" +msgstr "Notas" #: build/models.py:335 msgid "Extra build notes" @@ -886,19 +890,19 @@ msgstr "" #: build/models.py:1127 msgid "Stock item is over-allocated" -msgstr "" +msgstr "Artículo de stock sobreasignado" #: build/models.py:1133 order/models.py:1167 msgid "Allocation quantity must be greater than zero" -msgstr "" +msgstr "Cantidad asignada debe ser mayor que cero" #: build/models.py:1139 msgid "Quantity must be 1 for serialized stock" -msgstr "" +msgstr "La cantidad debe ser 1 para el stock serializado" #: build/models.py:1196 msgid "Selected stock item not found in BOM" -msgstr "" +msgstr "Artículo de stock seleccionado no encontrado en BOM" #: build/models.py:1256 stock/templates/stock/item_base.html:344 #: templates/InvenTree/search.html:137 templates/js/translated/build.js:1605 @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -923,11 +927,11 @@ msgstr "" #: templates/js/translated/stock.js:555 templates/js/translated/stock.js:720 #: templates/js/translated/stock.js:2470 msgid "Stock Item" -msgstr "" +msgstr "Artículo de stock" #: build/models.py:1274 msgid "Source stock item" -msgstr "" +msgstr "Producto original de stock" #: build/models.py:1287 msgid "Stock quantity to allocate to build" @@ -935,11 +939,11 @@ msgstr "" #: build/models.py:1295 msgid "Install into" -msgstr "" +msgstr "Instalar en" #: build/models.py:1296 msgid "Destination stock item" -msgstr "" +msgstr "Artículo de stock de destino" #: build/serializers.py:137 build/serializers.py:363 msgid "Build Output" @@ -962,18 +966,18 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" -msgstr "" +msgstr "Ubicación" #: build/serializers.py:191 msgid "Location for completed build outputs" @@ -987,14 +991,14 @@ msgstr "" #: templates/js/translated/order.js:1263 templates/js/translated/stock.js:1651 #: templates/js/translated/stock.js:2488 templates/js/translated/stock.js:2637 msgid "Status" -msgstr "" +msgstr "Estado" #: build/serializers.py:213 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1126,7 +1130,7 @@ msgstr "" #: templates/js/translated/table_filters.js:340 #: templates/js/translated/table_filters.js:361 msgid "Overdue" -msgstr "" +msgstr "Vencido" #: build/templates/build/build_base.html:158 #: build/templates/build/detail.html:68 build/templates/build/detail.html:143 @@ -1134,7 +1138,7 @@ msgstr "" #: templates/js/translated/build.js:1647 #: templates/js/translated/table_filters.js:370 msgid "Completed" -msgstr "" +msgstr "Completado" #: build/templates/build/build_base.html:171 #: build/templates/build/detail.html:95 order/models.py:927 @@ -1145,17 +1149,17 @@ msgstr "" #: stock/templates/stock/item_base.html:306 #: templates/js/translated/order.js:1218 msgid "Sales Order" -msgstr "" +msgstr "Orden de Venta" #: build/templates/build/build_base.html:178 #: build/templates/build/detail.html:109 #: report/templates/report/inventree_build_order_base.html:153 msgid "Issued By" -msgstr "" +msgstr "Emitido por" #: build/templates/build/build_base.html:223 msgid "Incomplete Outputs" -msgstr "" +msgstr "Salidas incompletas" #: build/templates/build/build_base.html:224 msgid "Build Order cannot be completed as incomplete build outputs remain" @@ -1220,7 +1224,7 @@ msgstr "" #: build/templates/build/detail.html:50 order/models.py:878 stock/forms.py:136 #: templates/js/translated/order.js:592 templates/js/translated/order.js:1138 msgid "Destination" -msgstr "" +msgstr "Destinación" #: build/templates/build/detail.html:57 msgid "Destination location not specified" @@ -1228,7 +1232,7 @@ msgstr "" #: build/templates/build/detail.html:74 templates/js/translated/build.js:652 msgid "Allocated Parts" -msgstr "" +msgstr "Partes asignadas" #: build/templates/build/detail.html:81 #: stock/templates/stock/item_base.html:330 @@ -1236,7 +1240,7 @@ msgstr "" #: templates/js/translated/table_filters.js:151 #: templates/js/translated/table_filters.js:238 msgid "Batch" -msgstr "" +msgstr "Lote" #: build/templates/build/detail.html:127 #: order/templates/order/order_base.html:143 @@ -1263,11 +1267,11 @@ msgstr "" #: build/templates/build/detail.html:177 templates/js/translated/build.js:1207 msgid "Unallocate stock" -msgstr "" +msgstr "Desasignar stock" #: build/templates/build/detail.html:178 msgid "Unallocate Stock" -msgstr "" +msgstr "Desasignar stock" #: build/templates/build/detail.html:180 msgid "Allocate stock to build" @@ -1275,7 +1279,7 @@ msgstr "" #: build/templates/build/detail.html:181 build/templates/build/sidebar.html:8 msgid "Allocate Stock" -msgstr "" +msgstr "Asignar stock" #: build/templates/build/detail.html:184 msgid "Order required parts" @@ -1336,11 +1340,11 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" -msgstr "" +msgstr "Adjuntos" #: build/templates/build/detail.html:294 msgid "Build Notes" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "Todos los artículos de stock no rastreados han sido asignados" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "Artículos de Stock Asignados" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "Parte principal" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "Seleccionar parte principal de la que copiar BOM" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "Borrar elementos BOM existentes" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "Parte inválida para parte principal" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "Tiempo de expiración (en días) para los artículos de stock de esta parte" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "Parte principal" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "Seleccionar parte principal" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "Artículo BOM principal" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "Confirmar duplicación de BOM desde principal" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "Categoría principal de parte" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "Esta prueba está definida para una parte principal" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/fr/LC_MESSAGES/django.po b/InvenTree/locale/fr/LC_MESSAGES/django.po index a11f3877e0..77f5ed0cab 100644 --- a/InvenTree/locale/fr/LC_MESSAGES/django.po +++ b/InvenTree/locale/fr/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -36,8 +36,7 @@ msgstr "Entrer la date" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Confirmer" @@ -81,36 +80,41 @@ msgstr "Confirmation de l'adresse email" msgid "You must type the same email each time." msgstr "Vous devez taper le même e-mail à chaque fois." -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Dupliquer le numéro de série: {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "Quantité fournie invalide" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Chaîne de numéro de série vide" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Groupe invalide : {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "Numéro de série dupliqué: {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "Aucun numéro de série trouvé" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Le nombre de numéros de série uniques ({s}) doit correspondre à la quantité ({q})" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "Lien externe manquant" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Pièce jointe" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Sélectionnez un fichier à joindre" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "Lien" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "Lien vers une url externe" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Commentaire" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Commentaire du fichier" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Choix invalide" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Nom" @@ -212,7 +216,7 @@ msgstr "Nom" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Nom" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Description (facultative)" msgid "parent" msgstr "parent" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Doit être un nombre valide" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "Référence de l' Ordre de Fabrication" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "BuildOrder associé a cette fabrication" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "BuildOrder associé a cette fabrication" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "Date de création" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "Lien Externe" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "État" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "L'article doit être en stock" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "Composant" @@ -1676,7 +1680,7 @@ msgstr "Composant" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "Achetable" @@ -1684,8 +1688,8 @@ msgstr "Achetable" msgid "Parts are purchaseable by default" msgstr "Les pièces sont achetables par défaut" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "URL" @@ -2324,7 +2328,7 @@ msgstr "Point de contact" msgid "Link to external company information" msgstr "Lien externe vers les informations de l'entreprise" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "Image" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "Fabricant" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "Sélectionner un fabricant" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "Valeur" @@ -2426,10 +2431,10 @@ msgstr "Valeur" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "Fournisseur" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "coût de base" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "Télécharger l'image depuis l'URL" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "Stock affecté" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "Fournisseurs" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "Supprimer les pièces du fournisseur" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "Supprimer" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "Stock" @@ -3181,7 +3188,7 @@ msgstr "Commande" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "Commande d’achat" @@ -3192,7 +3199,7 @@ msgstr "Pièce fournisseur" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "Reçu" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN dupliqué non autorisé dans les paramètres de la pièce" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "Catégorie" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "Catégorie de la pièce" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "IPN" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "Révision" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "Actif" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "Ventes multiples" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "Nom de test" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "Requis" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "Données" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "Supprimer l'élément" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "Sélectionner une pièce" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "Modifier la pièce jointe" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "A un IPN" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/he/LC_MESSAGES/django.po b/InvenTree/locale/he/LC_MESSAGES/django.po index bdd7f77c53..7386d27feb 100644 --- a/InvenTree/locale/he/LC_MESSAGES/django.po +++ b/InvenTree/locale/he/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Hebrew\n" "Language: he_IL\n" @@ -36,8 +36,7 @@ msgstr "" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" +msgid "Invalid group {group}" msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "" @@ -212,7 +216,7 @@ msgstr "" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/id/LC_MESSAGES/django.po b/InvenTree/locale/id/LC_MESSAGES/django.po index db65ee73cc..7dd1b774e0 100644 --- a/InvenTree/locale/id/LC_MESSAGES/django.po +++ b/InvenTree/locale/id/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Indonesian\n" "Language: id_ID\n" @@ -36,8 +36,7 @@ msgstr "Masukkan tanggal" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Konfirmasi" @@ -81,36 +80,41 @@ msgstr "Konfirmasi alamat email" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" +msgid "Invalid group {group}" msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "" @@ -212,7 +216,7 @@ msgstr "" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/it/LC_MESSAGES/django.po b/InvenTree/locale/it/LC_MESSAGES/django.po index 4447f6daa7..bc9564c36d 100644 --- a/InvenTree/locale/it/LC_MESSAGES/django.po +++ b/InvenTree/locale/it/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:28\n" "Last-Translator: \n" "Language-Team: Italian\n" "Language: it_IT\n" @@ -36,8 +36,7 @@ msgstr "Inserisci la data" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Conferma" @@ -81,36 +80,41 @@ msgstr "Conferma indirizzo email" msgid "You must type the same email each time." msgstr "È necessario digitare la stessa e-mail ogni volta." -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Seriale Duplicato: {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "Quantità inserita non valida" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Numero seriale vuoto" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Gruppo non valido: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "Seriale duplicato: {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "Nessun numero di serie trovato" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Il numero dei numeri seriali univoci ({s}) deve essere uguale alla quantità ({q})" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "Link esterno mancante" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Allegato" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Seleziona file da allegare" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "Link" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "Link a URL esterno" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Commento" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Commento del file" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Scelta non valida" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Nome" @@ -212,7 +216,7 @@ msgstr "Nome" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Nome" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Descrizione (opzionale)" msgid "parent" msgstr "genitore" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Deve essere un numero valido" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "Data di creazione" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "Collegamento esterno" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "Stato" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "Distinta base (Bom)" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "L'articolo deve essere disponibile" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "Assegnazione Completa" msgid "All untracked stock items have been allocated" msgstr "Tutte le giacenze non tracciate sono state assegnate" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "Copia Template Parametri Categoria" msgid "Copy category parameter templates when creating a part" msgstr "Copia i modelli dei parametri categoria quando si crea un articolo" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "Template" @@ -1657,9 +1661,9 @@ msgstr "Template" msgid "Parts are templates by default" msgstr "Gli articoli sono modelli per impostazione predefinita" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "Assemblaggio" @@ -1667,8 +1671,8 @@ msgstr "Assemblaggio" msgid "Parts can be assembled from other components by default" msgstr "Gli articoli possono essere assemblate da altri componenti per impostazione predefinita" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "Componente" @@ -1676,7 +1680,7 @@ msgstr "Componente" msgid "Parts can be used as sub-components by default" msgstr "Gli articoli possono essere assemblati da altri componenti per impostazione predefinita" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "Acquistabile" @@ -1684,8 +1688,8 @@ msgstr "Acquistabile" msgid "Parts are purchaseable by default" msgstr "Gli articoli sono acquistabili per impostazione predefinita" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "Vendibile" @@ -1693,10 +1697,10 @@ msgstr "Vendibile" msgid "Parts are salable by default" msgstr "Gli articoli sono acquistabili per impostazione predefinita" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "Tracciabile" @@ -1704,7 +1708,7 @@ msgstr "Tracciabile" msgid "Parts are trackable by default" msgstr "Gli articoli sono tracciabili per impostazione predefinita" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "Prezzo" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "Carica file" @@ -2232,7 +2236,7 @@ msgstr "Carica file" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "Abbina Campi" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "Passaggio Precedente" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "URL" @@ -2324,7 +2328,7 @@ msgstr "Punto di contatto" msgid "Link to external company information" msgstr "Collegamento alle informazioni aziendali esterne" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "Immagine" @@ -2375,24 +2379,25 @@ msgstr "Seleziona articolo" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "Produttore" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "Seleziona Produttore" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "Codice articolo produttore (MPN)" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "Codice articolo produttore" @@ -2417,8 +2422,8 @@ msgstr "Nome parametro" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "Valore" @@ -2426,10 +2431,10 @@ msgstr "Valore" msgid "Parameter value" msgstr "Valore del parametro" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "Unità" @@ -2447,22 +2452,23 @@ msgstr "L'articolo del costruttore collegato deve riferirsi alla stesso articolo #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "Fornitore" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "Seleziona fornitore" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "SKU" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "Descrizione articolo fornitore" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "Nota" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "costo base" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "Onere minimo (ad esempio tassa di stoccaggio)" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "Confezionamento" @@ -2502,7 +2508,7 @@ msgstr "Confezionamento" msgid "Part packaging" msgstr "Imballaggio del pezzo" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "multiplo" @@ -2563,10 +2569,11 @@ msgstr "Scarica immagine dall'URL" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "Cliente" @@ -2596,7 +2603,7 @@ msgstr "Crea nuovo fornitore" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "Nuovo fornitore articolo" @@ -2604,8 +2611,8 @@ msgstr "Nuovo fornitore articolo" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "Opzioni" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "Elimina articoli fornitore?" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "Tutte gli articoli del fornitore selezionati saranno eliminati" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "Articoli ordinati" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "Fornitori" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "Elimina articolo fornitore" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "Elimina" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "Elimina il parametro" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "Aggiungi parametro" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "Articolo Fornitore" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "Modifica articolo fornitore" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "Elimina articolo fornitore" @@ -2857,7 +2864,7 @@ msgstr "Informazioni Prezzi" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "Aggiungi riduzione prezzo" @@ -2865,11 +2872,11 @@ msgstr "Aggiungi riduzione prezzo" msgid "No price break information found" msgstr "Nessuna informazione di riduzione di prezzo trovata" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "Elimina riduzione di prezzo" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "Cancella riduzione di prezzo" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "Magazzino" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "Articolo Fornitore" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "Specifica la posizione per lo stock iniziale" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "Posizione Predefinita" @@ -3836,43 +3854,19 @@ msgstr "Posizione Predefinita" msgid "Available Stock" msgstr "Disponibilità in magazzino" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "convalida" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "Conferma che la Distinta Base (BOM) è corretta" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "Seleziona categoria articolo" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "Digita la quantità per il calcolo del prezzo" @@ -3888,7 +3882,7 @@ msgstr "Keywords predefinite" msgid "Default keywords for parts in this category" msgstr "Parole chiave predefinite per gli articoli in questa categoria" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "Categoria Articoli" @@ -3905,7 +3899,7 @@ msgstr "Categorie Articolo" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "Articoli" @@ -3914,384 +3908,415 @@ msgstr "Articoli" msgid "Invalid choice for parent part" msgstr "Scelta non valida per l'articolo principale" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "I successivi numeri di serie disponibili sono" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "Il prossimo numero di serie disponibile è" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "Il numero di serie più recente è" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "Non è consentito duplicare IPN nelle impostazioni dell'articolo" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "Nome articolo" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "È Template" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "Quest'articolo è un articolo di template?" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "Questa parte è una variante di un altro articolo?" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "Variante Di" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "Descrizione articolo" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "Parole Chiave" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "Parole chiave per migliorare la visibilità nei risultati di ricerca" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "Categoria" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "Categoria articolo" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "IPN - Numero di riferimento interno" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "Numero Dell'articolo Interno" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "Numero di revisione o di versione" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "Revisione" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "Dove viene normalmente immagazzinato questo articolo?" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "Fornitore predefinito" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "Articolo fornitore predefinito" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "Scadenza Predefinita" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "Scadenza (in giorni) per gli articoli in giacenza di questo pezzo" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "Scorta Minima" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "Livello minimo di giacenza consentito" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "Unità di conservazione delle scorte per quest'articolo" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "Quest'articolo può essere acquistato da fornitori esterni?" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "Questo pezzo può essere venduto ai clienti?" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "Attivo" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "Quest'articolo è attivo?" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "È una parte virtuale, come un prodotto software o una licenza?" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "Note dell'articolo - supporta la formattazione Markdown" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "BOM checksum" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "Descrizione Di Prova" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "Consenti Le Varianti" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "Notifica di magazzino bassa" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "Elimina Elementi" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "Seleziona Articolo" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "Sei iscritto alle notifiche di questa categoria" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "Articoli correlati" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "Distinta base" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "Fornitori articoli" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "Componenti Produttori" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "Articoli correlati" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "Inattivo" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "In magazzino" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "Ordinato" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "Imposta categoria per i seguenti articoli" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "Nessuna giacenza" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "Esporta Distinta base" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "Modifica Categoria Articoli" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "Elimina categoria" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "La Categoria articoli è stata eliminata" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "Crea Template Parametro Categoria" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "Modifica Modello Parametro Categoria" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "Elimina Modello Parametro Categoria" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "Posizione magazzino di destinazione" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "Impostazioni di accesso" msgid "Signup" msgstr "Registrati" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7263,47 +7254,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "Modifica allegato" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "Elimina allegato" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7696,8 +7695,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7762,55 +7761,55 @@ msgstr "Fornitori articoli" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "Modifica parametro" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "Elimina il parametro" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "Modifica parametro" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "Elimina Parametri" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "Nessun fornitore trovato" @@ -8111,7 +8110,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8136,7 +8135,7 @@ msgid "Total" msgstr "Totale" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "Prezzo Unitario" @@ -8152,7 +8151,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8261,222 +8260,238 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "Attributi Articolo" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "Opzioni Fornitore" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "Aggiungi Categoria Articolo" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "Crea giacenza iniziale" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "Crea una giacenza iniziale per quest'articolo" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "Quantità iniziale" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "Selezione la posizione di destinazione della giacenza" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "Copia Parametri Categoria" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "Aggiungi Dati Fornitore" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "Copia immagine" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "Copia immagine dall'articolo originale" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "Copia parametri" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "Categoria articolo principale" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "Modifica l'articolo" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "Articolo modificato" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 -msgid "Trackable part" +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "Convalida la distinta dei materiali" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 +msgid "Trackable part" +msgstr "Parte tracciabile" + +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "Parte virtuale" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "Parte sottoscritta" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "Parte vendibile" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "Nessuna variante trovata" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" -msgstr "" +msgstr "Elimina relazione tra i componenti" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "Nessun articolo trovato" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "Nessuna categoria" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "In esaurimento" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "Visualizza come elenco" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "Visualizza come griglia" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "Visualizza come struttura ad albero" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "Categoria sottoscritta" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "Percorso" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" -msgstr "" +msgstr "Nessun modello di test corrispondente" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" -msgstr "" +msgstr "Modificare il risultato del test" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" -msgstr "" +msgstr "Cancellare il risultato del test" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "Modifica ${human_name}" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "Elimina ${human_name}" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "Prezzo Singolo" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" #: templates/js/translated/plugin.js:22 msgid "The Plugin was installed" -msgstr "" +msgstr "Il Plugin è stato installato" #: templates/js/translated/report.js:67 msgid "items selected" @@ -8498,7 +8513,7 @@ msgstr "" #: templates/js/translated/report.js:243 templates/js/translated/report.js:297 #: templates/js/translated/report.js:351 msgid "No Reports Found" -msgstr "" +msgstr "Nessun Report Trovato" #: templates/js/translated/report.js:137 msgid "No report templates found which match selected stock item(s)" @@ -8908,12 +8923,12 @@ msgstr "Includi posizioni" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "Includi sottocategorie" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "Sottoscritto" @@ -9060,27 +9075,27 @@ msgstr "Stato dell'ordine" msgid "Outstanding" msgstr "In Sospeso" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "Includi articoli nelle sottocategorie" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "Ha IPN" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "L'articolo possiede un part number interno" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "Visualizza articoli attivi" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "Disponibilità" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "Acquistabile" diff --git a/InvenTree/locale/ja/LC_MESSAGES/django.po b/InvenTree/locale/ja/LC_MESSAGES/django.po index 2452dd64d8..6134a9efff 100644 --- a/InvenTree/locale/ja/LC_MESSAGES/django.po +++ b/InvenTree/locale/ja/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Japanese\n" "Language: ja_JP\n" @@ -36,8 +36,7 @@ msgstr "日付を入力する" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "確認" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "数量コードが無効です" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "シリアル番号は空です" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "無効なグループ: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "重複シリアル: {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "シリアル番号が見つかりません" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "添付ファイル" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "添付ファイルを選択" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "コメント:" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "ファイルコメント" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "無効な選択です" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "お名前" @@ -212,7 +216,7 @@ msgstr "お名前" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "お名前" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "説明 (オプション)" msgid "parent" msgstr "親" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "有効な数字でなければなりません" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "パーツを割り当てるためにビルドする" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "テンプレート" @@ -1657,9 +1661,9 @@ msgstr "テンプレート" msgid "Parts are templates by default" msgstr "パーツはデフォルトのテンプレートです" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "アセンブリ" @@ -1667,8 +1671,8 @@ msgstr "アセンブリ" msgid "Parts can be assembled from other components by default" msgstr "パーツはデフォルトで他のコンポーネントから組み立てることができます" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "コンポーネント" @@ -1676,7 +1680,7 @@ msgstr "コンポーネント" msgid "Parts can be used as sub-components by default" msgstr "パーツはデフォルトでサブコンポーネントとして使用できます" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "購入可能" @@ -1684,8 +1688,8 @@ msgstr "購入可能" msgid "Parts are purchaseable by default" msgstr "パーツはデフォルトで購入可能です" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "パーツはデフォルトで販売可能です" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "追跡可能" @@ -1704,7 +1708,7 @@ msgstr "追跡可能" msgid "Parts are trackable by default" msgstr "パーツはデフォルトで追跡可能です" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "新しいサプライヤー・パーツを作成" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "新しいサプライヤー・パーツ" @@ -2604,8 +2611,8 @@ msgstr "新しいサプライヤー・パーツ" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "メーカー・パーツ" msgid "Create new manufacturer part" msgstr "新しいメーカー・パーツを作成" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "新しいメーカ―・パーツ" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "パーツの注文" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "メーカー・パーツの編集" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "メーカー・パーツを削除" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "パーツ" @@ -3914,384 +3908,415 @@ msgstr "パーツ" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/ko/LC_MESSAGES/django.po b/InvenTree/locale/ko/LC_MESSAGES/django.po index 762ba0d084..19ec20c6a9 100644 --- a/InvenTree/locale/ko/LC_MESSAGES/django.po +++ b/InvenTree/locale/ko/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Korean\n" "Language: ko_KR\n" @@ -36,8 +36,7 @@ msgstr "" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" +msgid "Invalid group {group}" msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "" @@ -212,7 +216,7 @@ msgstr "" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/nl/LC_MESSAGES/django.po b/InvenTree/locale/nl/LC_MESSAGES/django.po index 9c93c0018d..ee5aec7e36 100644 --- a/InvenTree/locale/nl/LC_MESSAGES/django.po +++ b/InvenTree/locale/nl/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2022-01-03 09:49\n" "Last-Translator: \n" "Language-Team: Dutch\n" "Language: nl_NL\n" @@ -36,8 +36,7 @@ msgstr "Voer datum in" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Bevestigen" @@ -81,36 +80,41 @@ msgstr "E-mailadres bevestiging" msgid "You must type the same email each time." msgstr "Er moet hetzelfde e-mailadres ingevoerd worden." -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Dubbel serienummer: {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "Ongeldige hoeveeldheid ingevoerd" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Leeg serienummer" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Ongeldige groep: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "Dubbel serienummer: {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "Geen serienummers gevonden" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Aantal unieke serienummer ({s}) moet overeenkomen met de hoeveelheid ({q})" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "Externe link ontbreekt" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Bijlage" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Bestand als bijlage selecteren" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "Link" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "Link naar externe URL" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Opmerking" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Bijlage opmerking" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Ongeldige keuze" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Naam" @@ -212,7 +216,7 @@ msgstr "Naam" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Naam" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Omschrijving (optioneel)" msgid "parent" msgstr "overkoepelend" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Moet een geldig nummer zijn" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "Productie-opdracht referentie" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "Productie-opdracht waar dit product aan is toegewezen" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "Productie-opdracht waar dit product aan is toegewezen" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "Aanmaakdatum" @@ -822,7 +826,7 @@ msgstr "Gebruiker die de productie-opdracht heeft gegeven" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "Externe Link" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "Bouw om onderdelen toe te wijzen" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "Status" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1134,7 +1138,7 @@ msgstr "Achterstallig" #: templates/js/translated/build.js:1647 #: templates/js/translated/table_filters.js:370 msgid "Completed" -msgstr "" +msgstr "Voltooid" #: build/templates/build/build_base.html:171 #: build/templates/build/detail.html:95 order/models.py:927 @@ -1220,15 +1224,15 @@ msgstr "" #: build/templates/build/detail.html:50 order/models.py:878 stock/forms.py:136 #: templates/js/translated/order.js:592 templates/js/translated/order.js:1138 msgid "Destination" -msgstr "" +msgstr "Bestemming" #: build/templates/build/detail.html:57 msgid "Destination location not specified" -msgstr "" +msgstr "Bestemmingslocatie niet opgegeven" #: build/templates/build/detail.html:74 templates/js/translated/build.js:652 msgid "Allocated Parts" -msgstr "" +msgstr "Toegewezen onderdelen" #: build/templates/build/detail.html:81 #: stock/templates/stock/item_base.html:330 @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "Samenstelling" @@ -1667,8 +1671,8 @@ msgstr "Samenstelling" msgid "Parts can be assembled from other components by default" msgstr "Onderdelen kunnen standaard vanuit andere delen worden samengesteld" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "Fabrikant" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "Fabrikant selecteren" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "MPN" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "Fabrikant artikel nummer (MPN)" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "Gekoppeld fabrikant onderdeel moet verwijzen naar hetzelfde basis onderd #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "Fabrikant onderdelen" msgid "Create new manufacturer part" msgstr "Maak nieuw fabrikant onderdeel" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "Nieuw fabrikant onderdeel" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "Fabrikant onderdeel bewerken" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "Fabrikant onderdeel verwijderen" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "Standaard locatie" @@ -3836,43 +3854,19 @@ msgstr "Standaard locatie" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "Selecteer bovenliggend onderdeel om stuklijst van te kopiëren" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "Nieuw stuklijstitem" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "Samenstellingen" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "Productie-opdracht toewijzingen" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "Fabrikanten" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "Fabrikant onderdeel verwijderen" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "Gefabriceerde onderdelen" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "De volgende fabricage onderdelen worden verwijderd" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "Verwijder fabricage onderdelen" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "Geen fabricage onderdelen gevonden" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "Samengesteld onderdeel" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/no/LC_MESSAGES/django.po b/InvenTree/locale/no/LC_MESSAGES/django.po index b327f4a617..b625da1576 100644 --- a/InvenTree/locale/no/LC_MESSAGES/django.po +++ b/InvenTree/locale/no/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Norwegian\n" "Language: no_NO\n" @@ -36,8 +36,7 @@ msgstr "Oppgi dato" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Bekreft" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Dupliser serie: {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "Ugyldig mengde oppgitt" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Tom serienummerstreng" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Ugyldig gruppe: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "Dupliser serie: {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "Ingen serienummer funnet" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Antall unike serienummer ({s}) må samsvare mengde ({q})" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Vedlegg" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Velg fil å legge ved" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Kommenter" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Kommentar til fil" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Ugyldig valg" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Navn" @@ -212,7 +216,7 @@ msgstr "Navn" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Navn" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Beskrivelse (valgfritt)" msgid "parent" msgstr "" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Nummer må være gyldig" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/pl/LC_MESSAGES/django.po b/InvenTree/locale/pl/LC_MESSAGES/django.po index 2b467b4de9..7d650776d2 100644 --- a/InvenTree/locale/pl/LC_MESSAGES/django.po +++ b/InvenTree/locale/pl/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 16:26\n" "Last-Translator: \n" "Language-Team: Polish\n" "Language: pl_PL\n" @@ -36,8 +36,7 @@ msgstr "Wprowadź dane" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Potwierdź" @@ -71,7 +70,7 @@ msgstr "Wybierz kategorię" #: InvenTree/forms.py:236 msgid "Email (again)" -msgstr "" +msgstr "Adres email (ponownie)" #: InvenTree/forms.py:240 msgid "Email address confirmation" @@ -79,52 +78,57 @@ msgstr "Potwierdzenie adresu email" #: InvenTree/forms.py:260 msgid "You must type the same email each time." -msgstr "" +msgstr "Należy ponownie wpisać ten sam adres e-mail." -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Powtórzony numer seryjny: {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "Podano nieprawidłową ilość" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Pusty ciąg numeru seryjnego" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Nieprawidłowa grupa: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "Powtórzony numer seryjny: {g}" +msgid "Invalid group {group}" +msgstr "Nieprawidłowa grupa {group}" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "Nieprawidłowa/Brak grupy {group}" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "Nie znaleziono numerów seryjnych" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Ilość numerów seryjnych ({s}) musi odpowiadać ilości ({q})" #: InvenTree/models.py:120 msgid "Missing file" -msgstr "" +msgstr "Brak pliku" #: InvenTree/models.py:121 msgid "Missing external link" -msgstr "" +msgstr "Brak zewnętrznego odnośnika" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Załącznik" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Wybierz plik do załączenia" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "Łącze" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "Link do zewnętrznego adresu URL" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Komentarz" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Komentarz pliku" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -166,24 +170,24 @@ msgstr "data przesłania" #: InvenTree/models.py:176 msgid "Filename must not be empty" -msgstr "" +msgstr "Nazwa pliku nie może być pusta" #: InvenTree/models.py:199 msgid "Invalid attachment directory" -msgstr "" +msgstr "Nieprawidłowy katalog załącznika" #: InvenTree/models.py:209 #, python-brace-format msgid "Filename contains illegal character '{c}'" -msgstr "" +msgstr "Nazwa pliku zawiera niedozwolony znak '{c}'" #: InvenTree/models.py:212 msgid "Filename missing extension" -msgstr "" +msgstr "Brak rozszerzenia w nazwie pliku" #: InvenTree/models.py:219 msgid "Attachment with this filename already exists" -msgstr "" +msgstr "Załącznik o tej nazwie już istnieje" #: InvenTree/models.py:226 msgid "Error renaming file" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Błędny wybór" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Nazwa" @@ -212,7 +216,7 @@ msgstr "Nazwa" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Nazwa" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Opis (opcjonalny)" msgid "parent" msgstr "nadrzędny" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Numer musi być prawidłowy" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "Odwołanie do zamówienia wykonania" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "Zamówienie budowy, do którego budowa jest przypisana" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "Zamówienie budowy, do którego budowa jest przypisana" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "Kod partii" msgid "Batch code for this build output" msgstr "Kod partii dla wyjścia budowy" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "Data utworzenia" @@ -822,7 +826,7 @@ msgstr "Użytkownik, który wydał to zamówienie" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "Link Zewnętrzny" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "Status" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,9 +1014,9 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" -msgstr "" +msgstr "Towar musi znajdować się w magazynie" #: build/serializers.py:354 order/models.py:277 order/serializers.py:240 #: stock/models.py:365 stock/models.py:1077 stock/serializers.py:305 @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "Nowe zlecenie budowy" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "Szablon" @@ -1657,9 +1661,9 @@ msgstr "Szablon" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "Złożenie" @@ -1667,8 +1671,8 @@ msgstr "Złożenie" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "Komponent" @@ -1676,7 +1680,7 @@ msgstr "Komponent" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "Możliwość zakupu" @@ -1684,8 +1688,8 @@ msgstr "Możliwość zakupu" msgid "Parts are purchaseable by default" msgstr "Części są domyślnie z możliwością zakupu" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "Możliwość sprzedaży" @@ -1693,10 +1697,10 @@ msgstr "Możliwość sprzedaży" msgid "Parts are salable by default" msgstr "Części są domyślnie z możliwością sprzedaży" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "Możliwość śledzenia" @@ -1704,7 +1708,7 @@ msgstr "Możliwość śledzenia" msgid "Parts are trackable by default" msgstr "Części są domyślnie z możliwością śledzenia" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "Cena" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "Wyślij plik" @@ -2232,7 +2236,7 @@ msgstr "Wyślij plik" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "URL" @@ -2324,7 +2328,7 @@ msgstr "Punkt kontaktowy" msgid "Link to external company information" msgstr "Link do informacji o zewnętrznym przedsiębiorstwie" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "Obraz" @@ -2375,24 +2379,25 @@ msgstr "Wybierz część" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "Producent" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "Wybierz producenta" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "MPN" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "Numer producenta" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "Jednostki" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "Dostawca" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "Wybierz dostawcę" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "SKU" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "Uwaga" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "koszt podstawowy" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "Opakowanie" @@ -2502,7 +2508,7 @@ msgstr "Opakowanie" msgid "Part packaging" msgstr "Opakowanie części" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "wielokrotność" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "Klient" @@ -2596,7 +2603,7 @@ msgstr "Utwórz nowego dostawcę części" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "Nowy dostawca części" @@ -2604,8 +2611,8 @@ msgstr "Nowy dostawca części" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "Opcje" @@ -2633,7 +2640,7 @@ msgstr "Części producenta" msgid "Create new manufacturer part" msgstr "Utwórz nową część producenta" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "Nowa część producenta" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "Zamów część" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "Edytuj część producenta" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "Usuń cześć producenta" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "Dostawcy" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "Usuń" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "Dodaj parametr" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2832,13 +2839,13 @@ msgstr "" #: company/templates/company/supplier_part.html:141 #: part/templates/part/detail.html:24 stock/templates/stock/location.html:166 msgid "Create new stock item" -msgstr "" +msgstr "Utwórz nowy towar" #: company/templates/company/supplier_part.html:142 #: part/templates/part/detail.html:25 stock/templates/stock/location.html:167 #: templates/js/translated/stock.js:360 msgid "New Stock Item" -msgstr "" +msgstr "Nowy towar" #: company/templates/company/supplier_part.html:155 #: company/templates/company/supplier_part_navbar.html:19 @@ -2857,7 +2864,7 @@ msgstr "Informacja cenowa" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "Edytuj przedział cenowy" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "Stan" @@ -2916,7 +2923,7 @@ msgstr "Cennik" #: templates/InvenTree/search.html:152 templates/js/translated/stock.js:2351 #: templates/stats.html:93 templates/stats.html:102 users/models.py:43 msgid "Stock Items" -msgstr "" +msgstr "Towary" #: company/views.py:50 msgid "New Supplier" @@ -3181,7 +3188,7 @@ msgstr "Zamówienie" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "Zlecenie zakupu" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "Odebrane" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "Ostrzeżenie" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "Domyślna lokalizacja" @@ -3836,43 +3854,19 @@ msgstr "Domyślna lokalizacja" msgid "Available Stock" msgstr "Dostępna ilość" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "Część nadrzędna" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "potwierdź" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "Wybierz kategorię części" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "Domyślne słowa kluczowe" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "Części" @@ -3914,384 +3908,415 @@ msgstr "Części" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "Nazwa części" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "Wariant" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "Opis części" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "Słowa kluczowe" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "Kategoria" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "IPN" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "Wersja" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "Minimalny stan magazynowy" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "Czy ta część może być zbudowana z innych części?" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "Czy ta część może być użyta do budowy innych części?" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "Aktywny" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "Czy ta część jest aktywna?" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "Sprzedaj wiele" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "Nazwa testu" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "Wymagane" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "Część nadrzędna" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "Dane" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "Wartość domyślna" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" -msgstr "" +msgstr "Wybierz część nadrzędną" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "Podczęść" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "Suma kontrolna" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "Część 1" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "Część 2" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "Wybierz powiązaną część" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "Duplikuj część" @@ -4561,118 +4573,118 @@ msgstr "Nowy wariant" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "Dodaj powiązane" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "Zestawienie materiałowe" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "Kopiuj BOM" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "Powiązane części" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "Dodaj powiązaną część" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "Część jest wirtualna (nie fizyczna)" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "Nieaktywny" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,14 +5049,14 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" -msgstr "" +msgstr "Brak w magazynie" #: part/templates/part/stock_count.html:9 templates/InvenTree/index.html:158 msgid "Low Stock" -msgstr "" +msgstr "Mała ilość w magazynie" #: part/templates/part/variant_part.html:9 msgid "Create new part variant" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "Edytuj kategorię części" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5407,7 +5403,7 @@ msgstr "Data ważności" #: stock/forms.py:78 stock/forms.py:252 msgid "Expiration date for this stock item" -msgstr "" +msgstr "Data ważności tego zasobu" #: stock/forms.py:81 msgid "Enter unique serial numbers (or leave blank)" @@ -5489,7 +5485,7 @@ msgstr "" #: stock/models.py:461 msgid "Parent Stock Item" -msgstr "" +msgstr "Nadrzędny towar" #: stock/models.py:470 msgid "Base part" @@ -5497,7 +5493,7 @@ msgstr "Część podstawowa" #: stock/models.py:478 msgid "Select a matching supplier part for this stock item" -msgstr "" +msgstr "Wybierz pasującą część dostawcy dla tego towaru" #: stock/models.py:484 stock/templates/stock/location.html:16 #: stock/templates/stock/stock_app_base.html:8 @@ -5583,7 +5579,7 @@ msgstr "Ilość musi być liczbą całkowitą" #: stock/models.py:1080 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" -msgstr "" +msgstr "Ilość nie może przekraczać dostępnej ilości towaru ({n})" #: stock/models.py:1083 msgid "Serial numbers must be a list of integers" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5676,11 +5672,11 @@ msgstr "" #: stock/serializers.py:173 msgid "Purchase price of this stock item" -msgstr "" +msgstr "Cena zakupu tego towaru" #: stock/serializers.py:180 msgid "Purchase currency of this stock item" -msgstr "" +msgstr "Waluta zakupu tego towaru" #: stock/serializers.py:294 msgid "Enter number of stock items to serialize" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "Edytuj załącznik" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "Usuń załącznik" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "Cena jednostkowa" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "Zaktualizuj cenę jednostkową" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "Cena jednostkowa" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/pt/LC_MESSAGES/django.po b/InvenTree/locale/pt/LC_MESSAGES/django.po index 900d7cf186..34654d95ee 100644 --- a/InvenTree/locale/pt/LC_MESSAGES/django.po +++ b/InvenTree/locale/pt/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Portuguese\n" "Language: pt_PT\n" @@ -36,8 +36,7 @@ msgstr "" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" +msgid "Invalid group {group}" msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "" @@ -212,7 +216,7 @@ msgstr "" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/ru/LC_MESSAGES/django.po b/InvenTree/locale/ru/LC_MESSAGES/django.po index 34c9d0d725..63739f4e60 100644 --- a/InvenTree/locale/ru/LC_MESSAGES/django.po +++ b/InvenTree/locale/ru/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Russian\n" "Language: ru_RU\n" @@ -36,8 +36,7 @@ msgstr "Введите дату" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Подтвердить" @@ -81,36 +80,41 @@ msgstr "Подтверждение адреса электронной почт msgid "You must type the same email each time." msgstr "Вы должны вводить один и тот же адрес электронной почты." -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Дублировать серийный номер: {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "недопустимое количество" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Пустая строка серийного номера" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Некорректный идентификатор группы {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "Повторяющийся серийный {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "Серийных номеров не найдено" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Число уникальных серийных номеров ({s}) должно соответствовать количеству ({q})" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "Отсутствует внешняя ссылка" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Вложения" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Выберите файл для вложения" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "Ссылка" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "Ссылка на внешний URL" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Комментарий" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Комментарий к файлу" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Неверный выбор" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Название" @@ -212,7 +216,7 @@ msgstr "Название" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Название" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Описание (необязательно)" msgid "parent" msgstr "родитель" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Должно быть действительным номером" @@ -453,7 +457,7 @@ msgstr "Разбить дочерний элемент" #: InvenTree/status_codes.py:294 templates/js/translated/stock.js:2064 msgid "Merged stock items" -msgstr "" +msgstr "Объединенные позиции на складе" #: InvenTree/status_codes.py:296 templates/js/translated/table_filters.js:213 msgid "Sent to customer" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "Ссылка на заказ" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "Штрих код" msgid "Batch code for this build output" msgstr "Штрих код для этого вывода сборки" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "Дата создания" @@ -822,7 +826,7 @@ msgstr "Пользователь, выпустивший этот заказ н #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "Внешняя ссылка" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,10 +997,10 @@ msgstr "Статус" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" -msgstr "" +msgstr "BOM Компонент" #: build/serializers.py:269 msgid "Build output" @@ -1010,19 +1014,19 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" -msgstr "" +msgstr "Компонент должен быть в наличии" #: build/serializers.py:354 order/models.py:277 order/serializers.py:240 #: stock/models.py:365 stock/models.py:1077 stock/serializers.py:305 msgid "Quantity must be greater than zero" -msgstr "" +msgstr "Количество должно быть больше нуля" #: build/serializers.py:396 order/serializers.py:741 #, python-brace-format msgid "Available quantity ({q}) exceeded" -msgstr "" +msgstr "Превышено доступное количество ({q})" #: build/serializers.py:402 msgid "Build output must be specified for allocation of tracked parts" @@ -1038,7 +1042,7 @@ msgstr "" #: build/tasks.py:92 msgid "Stock required for build order" -msgstr "" +msgstr "Для заказа сборки необходим остаток" #: build/templates/build/build_base.html:39 #: order/templates/order/order_base.html:28 @@ -1048,7 +1052,7 @@ msgstr "" #: build/templates/build/build_base.html:43 msgid "Print build order report" -msgstr "" +msgstr "Печать отчета о заказе сборки" #: build/templates/build/build_base.html:50 msgid "Build actions" @@ -1056,16 +1060,16 @@ msgstr "" #: build/templates/build/build_base.html:54 msgid "Edit Build" -msgstr "" +msgstr "Редактировать сборку" #: build/templates/build/build_base.html:56 #: build/templates/build/build_base.html:215 build/views.py:56 msgid "Cancel Build" -msgstr "" +msgstr "Отменить сборку" #: build/templates/build/build_base.html:59 msgid "Delete Build" -msgstr "" +msgstr "Удалить сборку" #: build/templates/build/build_base.html:64 #: build/templates/build/build_base.html:65 @@ -1155,7 +1159,7 @@ msgstr "Выдано" #: build/templates/build/build_base.html:223 msgid "Incomplete Outputs" -msgstr "" +msgstr "Незавершенные выходные данные" #: build/templates/build/build_base.html:224 msgid "Build Order cannot be completed as incomplete build outputs remain" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/sv/LC_MESSAGES/django.po b/InvenTree/locale/sv/LC_MESSAGES/django.po index 8f0b0f1fbd..f4015e78ec 100644 --- a/InvenTree/locale/sv/LC_MESSAGES/django.po +++ b/InvenTree/locale/sv/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Swedish\n" "Language: sv_SE\n" @@ -36,8 +36,7 @@ msgstr "Ange datum" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Bekräfta" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "Ogiltigt antal angivet" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Tom serienummersträng" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Ogiltig grupp: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" +msgid "Invalid group {group}" msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "Inga serienummer hittades" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Bilaga" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Välj fil att bifoga" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Kommentar" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Fil kommentar" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Ogiltigt val" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Namn" @@ -212,7 +216,7 @@ msgstr "Namn" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Namn" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Beskrivning (valfritt)" msgid "parent" msgstr "överordnad" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Måste vara ett giltigt nummer" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/th/LC_MESSAGES/django.po b/InvenTree/locale/th/LC_MESSAGES/django.po index 862aeeae7a..c7ff4190b2 100644 --- a/InvenTree/locale/th/LC_MESSAGES/django.po +++ b/InvenTree/locale/th/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Thai\n" "Language: th_TH\n" @@ -36,8 +36,7 @@ msgstr "" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" +msgid "Invalid group {group}" msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "" @@ -212,7 +216,7 @@ msgstr "" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "" @@ -3914,384 +3908,415 @@ msgstr "" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/tr/LC_MESSAGES/django.po b/InvenTree/locale/tr/LC_MESSAGES/django.po index 23999feeb4..3ae94e8bc1 100644 --- a/InvenTree/locale/tr/LC_MESSAGES/django.po +++ b/InvenTree/locale/tr/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -36,8 +36,7 @@ msgstr "Tarih giriniz" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "Onay" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Tekrarlanan seri {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "Geçersiz veri sağlandı" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "Boş seri numarası dizesi" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "Geçersiz grup: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "Tekrarlanan seri {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "Seri numarası bulunamadı" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Benzersiz seri numaralarının sayısı ({s}) girilen miktarla eşleşmeli ({q})" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "Ek" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "Eklenecek dosyayı seç" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "Bağlantı" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "Harici URL'ye bağlantı" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Yorum" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "Dosya yorumu" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "Geçersiz seçim" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "Adı" @@ -212,7 +216,7 @@ msgstr "Adı" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "Adı" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Açıklama (isteğe bağlı)" msgid "parent" msgstr "üst" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "Geçerli bir numara olmalı" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "Yapım İşi Emri Referansı" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "Bu yapım işinin tahsis edildiği yapım işi emri" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "Bu yapım işinin tahsis edildiği yapım işi emri" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "Sıra numarası" msgid "Batch code for this build output" msgstr "Yapım işi çıktısı için sıra numarası" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "Oluşturulma tarihi" @@ -822,7 +826,7 @@ msgstr "Bu yapım işi emrini veren kullanıcı" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "Harici Bağlantı" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "Yapım işi için tahsis edilen parçalar" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "Durum" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "Tamamlanmış Yapım İşi Çıktıları" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "Yeni Yapım İşi Emri" @@ -1647,9 +1651,9 @@ msgstr "Kategori Paremetre Sablonu Kopyala" msgid "Copy category parameter templates when creating a part" msgstr "Parça oluştururken kategori parametre şablonlarını kopyala" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "Şablon" @@ -1657,9 +1661,9 @@ msgstr "Şablon" msgid "Parts are templates by default" msgstr "Parçaları varsayılan olan şablondur" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "Montaj" @@ -1667,8 +1671,8 @@ msgstr "Montaj" msgid "Parts can be assembled from other components by default" msgstr "Parçalar varsayılan olarak başka bileşenlerden monte edilebilir" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "Bileşen" @@ -1676,7 +1680,7 @@ msgstr "Bileşen" msgid "Parts can be used as sub-components by default" msgstr "Parçalar varsayılan olarak alt bileşen olarak kullanılabilir" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "Satın Alınabilir" @@ -1684,8 +1688,8 @@ msgstr "Satın Alınabilir" msgid "Parts are purchaseable by default" msgstr "Parçalar varsayılan olarak satın alınabilir" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "Satılabilir" @@ -1693,10 +1697,10 @@ msgstr "Satılabilir" msgid "Parts are salable by default" msgstr "Parçalar varsayılan olarak satılabilir" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "Takip Edilebilir" @@ -1704,7 +1708,7 @@ msgstr "Takip Edilebilir" msgid "Parts are trackable by default" msgstr "Parçalar varsayılan olarak takip edilebilir" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "Fiyat" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "Dosya Yükle" @@ -2232,7 +2236,7 @@ msgstr "Dosya Yükle" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "Alanları Eşleştir" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "Resim" @@ -2375,24 +2379,25 @@ msgstr "Parça seçin" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "Üretici" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "Üretici seçin" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "ÜPN" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "Üretici Parça Numarası" @@ -2417,8 +2422,8 @@ msgstr "Parametre adı" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "Değer" @@ -2426,10 +2431,10 @@ msgstr "Değer" msgid "Parameter value" msgstr "Parametre değeri" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "Tedarikçi" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "Tedarikçi seçin" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "SKU" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "Not" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "temel maliyet" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "Paketleme" @@ -2502,7 +2508,7 @@ msgstr "Paketleme" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "çoklu" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "Müşteri" @@ -2596,7 +2603,7 @@ msgstr "Yeni tedarikçi parçası oluştur" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "Yeni Tedarikçi Parçası" @@ -2604,8 +2611,8 @@ msgstr "Yeni Tedarikçi Parçası" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "Atanan Stok" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "Parça siparişi" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "Tedarikçi parçalarını sil" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "Tedarikçi Parçası" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "Tedarikçi parçasını düzenle" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "Tedarikçi parçasını sil" @@ -2857,7 +2864,7 @@ msgstr "Fiyat Bilgisi" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "Stok" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "Uyarı" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "Varsayılan Konum" @@ -3836,43 +3854,19 @@ msgstr "Varsayılan Konum" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "Parametre şablonunu aynı seviyedeki kategorilere ekle" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "Parametre şablonunu tüm kategorilere ekle" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "Parça Kategorileri" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "Parçalar" @@ -3914,384 +3908,415 @@ msgstr "Parçalar" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "Sonraki kullanılabilir seri numaraları" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "Sonraki müsait seri numarası" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "En son seri numarası" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "Yinelenen DPN'ye parça ayarlarında izin verilmiyor" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "Parça adı" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "Şablon Mu" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "Bu parça bir şablon parçası mı?" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "Bu parça başka bir parçanın çeşidi mi?" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "Çeşidi" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "Parça açıklaması" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "Anahtar kelimeler" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "DPN" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "Parça revizyon veya versiyon numarası" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "Revizyon" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "Varsayılan Tedarikçi" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "Varsayılan tedarikçi parçası" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "Minimum Stok" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "Bu parça diğer parçalardan yapılabilir mi?" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "Bu parça diğer parçaların yapımında kullanılabilir mi?" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "Bu parça dış tedarikçilerden satın alınabilir mi?" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "Bu parça müşterilere satılabilir mi?" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "Aktif" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "Bu parça aktif mi?" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "Oluşturan Kullanıcı" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "Test şablonları sadece takip edilebilir paçalar için oluşturulabilir" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "Test Adı" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "Test Açıklaması" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "Gerekli" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "Testi geçmesi için bu gerekli mi?" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "Parametre şablon adı benzersiz olmalıdır" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "Parametre Şablonu" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Bu malzeme listesi, çeşit parçalar listesini kalıtsalıdır" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "Çeşide İzin Ver" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Çeşit parçaların stok kalemleri bu malzeme listesinde kullanılabilir" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "Malzeme Listesi Şablonu Yükle" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "Yeni Çeşit" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "Parça Tedarikçileri" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "Pasif" @@ -4806,7 +4818,7 @@ msgstr "Bu parça %(link)s parçasının bir çeşididir" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "Aşağıdaki parçalara kategori ayarla" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "Stok Yok" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "Parça Parametre Şablonu Oluştur" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "Parça Parametre Şablonu Düzenle" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "Parça Parametre Şablonu Sil" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "Kategori Parametre Şablonu Oluştur" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "Kategori Parametre Şablonu Düzenle" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "Kategori Parametre Şablonu Sil" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "Commit Tarihi" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "Commit Hash Değeri" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "Ek Düzenle" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "Eki Sil" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "Şablon Parça" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "Çeşit bulunamadı" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "Sorgu ile eşleşen test şablonu bulunamadı" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "Konumları dahil et" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "Alt kategorilerdeki parçaları dahil et" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "DPN Var" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/vi/LC_MESSAGES/django.po b/InvenTree/locale/vi/LC_MESSAGES/django.po index 372bddf936..b2a86bbe7f 100644 --- a/InvenTree/locale/vi/LC_MESSAGES/django.po +++ b/InvenTree/locale/vi/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Vietnamese\n" "Language: vi_VN\n" @@ -36,8 +36,7 @@ msgstr "" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "" @@ -81,36 +80,41 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" +msgid "Invalid group {group}" msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "Bình luận" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "" @@ -212,7 +216,7 @@ msgstr "" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "Mô tả (tùy chọn)" msgid "parent" msgstr "" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "" @@ -822,7 +826,7 @@ msgstr "" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "Trạng thái" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "" @@ -1657,9 +1661,9 @@ msgstr "" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "" @@ -1667,8 +1671,8 @@ msgstr "" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "" @@ -1676,7 +1680,7 @@ msgstr "" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "" @@ -1684,8 +1688,8 @@ msgstr "" msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "" @@ -1693,10 +1697,10 @@ msgstr "" msgid "Parts are salable by default" msgstr "" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "" @@ -1704,7 +1708,7 @@ msgstr "" msgid "Parts are trackable by default" msgstr "" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "" @@ -2232,7 +2236,7 @@ msgstr "" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "" @@ -2375,24 +2379,25 @@ msgstr "" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "Nhà sản xuất" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "" @@ -2417,8 +2422,8 @@ msgstr "" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "" @@ -2426,10 +2431,10 @@ msgstr "" msgid "Parameter value" msgstr "" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "Nhà cung cấp" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "" @@ -2502,7 +2508,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "" @@ -2596,7 +2603,7 @@ msgstr "" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "" @@ -2604,8 +2611,8 @@ msgstr "" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "" @@ -2633,7 +2640,7 @@ msgstr "" msgid "Create new manufacturer part" msgstr "" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "" @@ -2857,7 +2864,7 @@ msgstr "" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "Kiện hàng" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "Đơn hàng" @@ -3192,7 +3199,7 @@ msgstr "" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "" @@ -3836,43 +3854,19 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "" @@ -3905,7 +3899,7 @@ msgstr "" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "Nguyên liệu" @@ -3914,384 +3908,415 @@ msgstr "Nguyên liệu" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "" msgid "Part image not found" msgstr "" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "Cài đặt" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/zh/LC_MESSAGES/django.po b/InvenTree/locale/zh/LC_MESSAGES/django.po index a3b8d4255c..5966a4fe21 100644 --- a/InvenTree/locale/zh/LC_MESSAGES/django.po +++ b/InvenTree/locale/zh/LC_MESSAGES/django.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 02:57+0000\n" -"PO-Revision-Date: 2021-12-21 03:01\n" +"POT-Creation-Date: 2021-12-31 06:22+0000\n" +"PO-Revision-Date: 2021-12-31 06:27\n" "Last-Translator: \n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" @@ -36,8 +36,7 @@ msgstr "输入日期" #: InvenTree/forms.py:126 build/forms.py:48 build/forms.py:69 build/forms.py:93 #: order/forms.py:24 order/forms.py:35 order/forms.py:46 order/forms.py:57 -#: part/forms.py:78 templates/account/email_confirm.html:20 -#: templates/js/translated/forms.js:595 +#: templates/account/email_confirm.html:20 templates/js/translated/forms.js:595 msgid "Confirm" msgstr "确认" @@ -81,36 +80,41 @@ msgstr "Email 地址确认" msgid "You must type the same email each time." msgstr "您必须输入相同的 Email 。" -#: InvenTree/helpers.py:430 +#: InvenTree/helpers.py:437 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "重复的序列号: {n}" -#: InvenTree/helpers.py:437 order/models.py:279 order/models.py:420 +#: InvenTree/helpers.py:444 order/models.py:279 order/models.py:420 #: stock/views.py:1231 msgid "Invalid quantity provided" msgstr "提供的数量无效" -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:447 msgid "Empty serial number string" msgstr "空序列号字符串" -#: InvenTree/helpers.py:462 InvenTree/helpers.py:465 InvenTree/helpers.py:468 -#: InvenTree/helpers.py:493 +#: InvenTree/helpers.py:469 InvenTree/helpers.py:472 InvenTree/helpers.py:475 +#: InvenTree/helpers.py:500 #, python-brace-format msgid "Invalid group: {g}" msgstr "无效的群组: {g}" -#: InvenTree/helpers.py:498 +#: InvenTree/helpers.py:510 #, python-brace-format -msgid "Duplicate serial: {g}" -msgstr "重复的序列号: {g}" +msgid "Invalid group {group}" +msgstr "" -#: InvenTree/helpers.py:506 +#: InvenTree/helpers.py:516 +#, python-brace-format +msgid "Invalid/no group {group}" +msgstr "" + +#: InvenTree/helpers.py:522 msgid "No serial numbers found" msgstr "未找到序列号" -#: InvenTree/helpers.py:510 +#: InvenTree/helpers.py:526 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "唯一序列号 ({s}) 必须匹配数量 ({q})" @@ -124,7 +128,7 @@ msgid "Missing external link" msgstr "" #: InvenTree/models.py:132 stock/models.py:1967 -#: templates/js/translated/attachment.js:117 +#: templates/js/translated/attachment.js:119 msgid "Attachment" msgstr "附件" @@ -133,19 +137,19 @@ msgid "Select file to attach" msgstr "选择附件" #: InvenTree/models.py:139 company/models.py:131 company/models.py:348 -#: company/models.py:564 order/models.py:124 part/models.py:797 +#: company/models.py:564 order/models.py:124 part/models.py:828 #: report/templates/report/inventree_build_order_base.html:165 -#: templates/js/translated/company.js:537 -#: templates/js/translated/company.js:826 templates/js/translated/part.js:1260 +#: templates/js/translated/company.js:540 +#: templates/js/translated/company.js:829 templates/js/translated/part.js:1317 msgid "Link" msgstr "链接" -#: InvenTree/models.py:140 build/models.py:330 part/models.py:798 +#: InvenTree/models.py:140 build/models.py:330 part/models.py:829 #: stock/models.py:527 msgid "Link to external URL" msgstr "链接到外部 URL" -#: InvenTree/models.py:143 templates/js/translated/attachment.js:161 +#: InvenTree/models.py:143 templates/js/translated/attachment.js:163 msgid "Comment" msgstr "注释" @@ -154,7 +158,7 @@ msgid "File comment" msgstr "文件注释" #: InvenTree/models.py:149 InvenTree/models.py:150 common/models.py:1219 -#: common/models.py:1220 part/models.py:2205 part/models.py:2225 +#: common/models.py:1220 part/models.py:2258 part/models.py:2278 #: report/templates/report/inventree_test_report_base.html:96 #: templates/js/translated/stock.js:2534 msgid "User" @@ -194,15 +198,15 @@ msgid "Invalid choice" msgstr "选择无效" #: InvenTree/models.py:277 InvenTree/models.py:278 company/models.py:415 -#: label/models.py:112 part/models.py:741 part/models.py:2389 +#: label/models.py:112 part/models.py:772 part/models.py:2442 #: plugin/models.py:39 report/models.py:181 -#: templates/InvenTree/settings/mixins/urls.html:11 +#: templates/InvenTree/settings/mixins/urls.html:13 #: templates/InvenTree/settings/plugin.html:47 #: templates/InvenTree/settings/plugin.html:124 #: templates/InvenTree/settings/plugin_settings.html:23 #: templates/InvenTree/settings/settings.html:268 -#: templates/js/translated/company.js:638 templates/js/translated/part.js:506 -#: templates/js/translated/part.js:643 templates/js/translated/part.js:1567 +#: templates/js/translated/company.js:641 templates/js/translated/part.js:561 +#: templates/js/translated/part.js:700 templates/js/translated/part.js:1624 #: templates/js/translated/stock.js:2327 msgid "Name" msgstr "名称" @@ -212,7 +216,7 @@ msgstr "名称" #: company/models.py:570 company/templates/company/company_base.html:68 #: company/templates/company/manufacturer_part.html:76 #: company/templates/company/supplier_part.html:73 label/models.py:119 -#: order/models.py:122 part/models.py:764 part/templates/part/category.html:74 +#: order/models.py:122 part/models.py:795 part/templates/part/category.html:74 #: part/templates/part/part_base.html:163 #: part/templates/part/set_category.html:14 report/models.py:194 #: report/models.py:553 report/models.py:592 @@ -221,12 +225,12 @@ msgstr "名称" #: templates/InvenTree/settings/plugin_settings.html:33 #: templates/js/translated/bom.js:327 templates/js/translated/bom.js:540 #: templates/js/translated/build.js:1627 templates/js/translated/company.js:345 -#: templates/js/translated/company.js:548 -#: templates/js/translated/company.js:837 templates/js/translated/order.js:836 +#: templates/js/translated/company.js:551 +#: templates/js/translated/company.js:840 templates/js/translated/order.js:836 #: templates/js/translated/order.js:1019 templates/js/translated/order.js:1258 -#: templates/js/translated/part.js:565 templates/js/translated/part.js:935 -#: templates/js/translated/part.js:1020 templates/js/translated/part.js:1190 -#: templates/js/translated/part.js:1586 templates/js/translated/part.js:1655 +#: templates/js/translated/part.js:620 templates/js/translated/part.js:992 +#: templates/js/translated/part.js:1077 templates/js/translated/part.js:1247 +#: templates/js/translated/part.js:1643 templates/js/translated/part.js:1712 #: templates/js/translated/stock.js:1569 templates/js/translated/stock.js:2339 #: templates/js/translated/stock.js:2384 msgid "Description" @@ -240,7 +244,7 @@ msgstr "描述 (可选)" msgid "parent" msgstr "上级项" -#: InvenTree/serializers.py:65 part/models.py:2674 +#: InvenTree/serializers.py:65 part/models.py:2727 msgid "Must be a valid number" msgstr "必须是有效数字" @@ -585,10 +589,10 @@ msgstr "" #: company/forms.py:42 company/templates/company/supplier_part.html:251 #: order/models.py:796 order/models.py:1207 order/serializers.py:810 #: order/templates/order/order_wizard/match_parts.html:30 -#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:193 -#: part/forms.py:209 part/forms.py:225 part/models.py:2576 +#: order/templates/order/order_wizard/select_parts.html:34 part/forms.py:145 +#: part/forms.py:161 part/forms.py:177 part/models.py:2629 #: part/templates/part/bom_upload/match_parts.html:31 -#: part/templates/part/detail.html:961 part/templates/part/detail.html:1047 +#: part/templates/part/detail.html:962 part/templates/part/detail.html:1048 #: part/templates/part/part_pricing.html:16 #: report/templates/report/inventree_build_order_base.html:114 #: report/templates/report/inventree_po_report.html:91 @@ -607,9 +611,9 @@ msgstr "" #: templates/js/translated/order.js:101 templates/js/translated/order.js:1056 #: templates/js/translated/order.js:1578 templates/js/translated/order.js:1859 #: templates/js/translated/order.js:1947 templates/js/translated/order.js:2036 -#: templates/js/translated/order.js:2150 templates/js/translated/part.js:843 -#: templates/js/translated/part.js:1798 templates/js/translated/part.js:1921 -#: templates/js/translated/part.js:1999 templates/js/translated/stock.js:383 +#: templates/js/translated/order.js:2150 templates/js/translated/part.js:900 +#: templates/js/translated/part.js:1855 templates/js/translated/part.js:1978 +#: templates/js/translated/part.js:2056 templates/js/translated/stock.js:383 #: templates/js/translated/stock.js:580 templates/js/translated/stock.js:750 #: templates/js/translated/stock.js:2519 templates/js/translated/stock.js:2621 msgid "Quantity" @@ -675,7 +679,7 @@ msgid "Build Order Reference" msgstr "相关生产订单" #: build/models.py:199 order/models.py:210 order/models.py:536 -#: order/models.py:803 part/models.py:2585 +#: order/models.py:803 part/models.py:2638 #: part/templates/part/bom_upload/match_parts.html:30 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 @@ -701,9 +705,9 @@ msgstr "此次生产匹配的订单" #: build/templates/build/detail.html:30 company/models.py:705 #: order/models.py:856 order/models.py:930 #: order/templates/order/order_wizard/select_parts.html:32 part/models.py:357 -#: part/models.py:2151 part/models.py:2167 part/models.py:2186 -#: part/models.py:2203 part/models.py:2305 part/models.py:2427 -#: part/models.py:2560 part/models.py:2867 +#: part/models.py:2204 part/models.py:2220 part/models.py:2239 +#: part/models.py:2256 part/models.py:2358 part/models.py:2480 +#: part/models.py:2613 part/models.py:2920 part/serializers.py:658 #: part/templates/part/part_app_base.html:8 #: part/templates/part/part_pricing.html:12 #: part/templates/part/set_category.html:13 @@ -716,12 +720,12 @@ msgstr "此次生产匹配的订单" #: templates/js/translated/barcode.js:383 templates/js/translated/bom.js:326 #: templates/js/translated/bom.js:505 templates/js/translated/build.js:625 #: templates/js/translated/build.js:993 templates/js/translated/build.js:1364 -#: templates/js/translated/build.js:1632 templates/js/translated/company.js:489 -#: templates/js/translated/company.js:746 templates/js/translated/order.js:84 +#: templates/js/translated/build.js:1632 templates/js/translated/company.js:492 +#: templates/js/translated/company.js:749 templates/js/translated/order.js:84 #: templates/js/translated/order.js:586 templates/js/translated/order.js:1004 #: templates/js/translated/order.js:1576 templates/js/translated/order.js:1933 -#: templates/js/translated/order.js:2128 templates/js/translated/part.js:920 -#: templates/js/translated/part.js:1001 templates/js/translated/part.js:1168 +#: templates/js/translated/order.js:2128 templates/js/translated/part.js:977 +#: templates/js/translated/part.js:1058 templates/js/translated/part.js:1225 #: templates/js/translated/stock.js:554 templates/js/translated/stock.js:719 #: templates/js/translated/stock.js:926 templates/js/translated/stock.js:1526 #: templates/js/translated/stock.js:2609 @@ -789,7 +793,7 @@ msgstr "批量代码" msgid "Batch code for this build output" msgstr "此生产产出的批量代码" -#: build/models.py:292 order/models.py:126 part/models.py:936 +#: build/models.py:292 order/models.py:126 part/models.py:967 #: part/templates/part/part_base.html:313 templates/js/translated/order.js:1271 msgid "Creation Date" msgstr "创建日期" @@ -822,7 +826,7 @@ msgstr "发布此生产订单的用户" #: build/models.py:323 build/templates/build/build_base.html:185 #: build/templates/build/detail.html:116 order/models.py:140 #: order/templates/order/order_base.html:170 -#: order/templates/order/sales_order_base.html:182 part/models.py:940 +#: order/templates/order/sales_order_base.html:182 part/models.py:971 #: report/templates/report/inventree_build_order_base.html:159 #: templates/js/translated/build.js:1686 templates/js/translated/order.js:864 msgid "Responsible" @@ -845,15 +849,15 @@ msgstr "外部链接" #: company/models.py:577 company/templates/company/sidebar.html:25 #: order/models.py:144 order/models.py:805 order/models.py:1051 #: order/templates/order/po_sidebar.html:11 -#: order/templates/order/so_sidebar.html:17 part/models.py:925 +#: order/templates/order/so_sidebar.html:17 part/models.py:956 #: part/templates/part/detail.html:120 part/templates/part/part_sidebar.html:50 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:140 stock/forms.py:190 stock/forms.py:224 stock/models.py:597 #: stock/models.py:1867 stock/models.py:1973 stock/serializers.py:332 -#: stock/serializers.py:638 stock/serializers.py:736 stock/serializers.py:868 +#: stock/serializers.py:639 stock/serializers.py:737 stock/serializers.py:869 #: stock/templates/stock/stock_sidebar.html:21 #: templates/js/translated/barcode.js:58 templates/js/translated/bom.js:711 -#: templates/js/translated/company.js:842 templates/js/translated/order.js:1149 +#: templates/js/translated/company.js:845 templates/js/translated/order.js:1149 #: templates/js/translated/order.js:1445 templates/js/translated/order.js:2280 #: templates/js/translated/stock.js:1309 templates/js/translated/stock.js:1795 msgid "Notes" @@ -911,7 +915,7 @@ msgid "Build to allocate parts" msgstr "" #: build/models.py:1273 build/serializers.py:334 order/serializers.py:690 -#: order/serializers.py:708 stock/serializers.py:576 stock/serializers.py:694 +#: order/serializers.py:708 stock/serializers.py:577 stock/serializers.py:695 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:22 #: stock/templates/stock/item_base.html:366 @@ -962,14 +966,14 @@ msgid "This build output is not fully allocated" msgstr "" #: build/serializers.py:190 order/serializers.py:226 order/serializers.py:294 -#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:729 -#: stock/serializers.py:970 stock/templates/stock/item_base.html:312 +#: stock/forms.py:222 stock/serializers.py:325 stock/serializers.py:730 +#: stock/serializers.py:971 stock/templates/stock/item_base.html:312 #: templates/js/translated/barcode.js:384 #: templates/js/translated/barcode.js:557 templates/js/translated/build.js:425 #: templates/js/translated/build.js:1032 templates/js/translated/order.js:508 #: templates/js/translated/order.js:1844 templates/js/translated/order.js:1955 #: templates/js/translated/order.js:1963 templates/js/translated/order.js:2044 -#: templates/js/translated/part.js:177 templates/js/translated/stock.js:556 +#: templates/js/translated/part.js:179 templates/js/translated/stock.js:556 #: templates/js/translated/stock.js:721 templates/js/translated/stock.js:928 #: templates/js/translated/stock.js:1676 templates/js/translated/stock.js:2411 msgid "Location" @@ -993,8 +997,8 @@ msgstr "状态" msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:259 build/serializers.py:308 part/models.py:2700 -#: part/models.py:2859 +#: build/serializers.py:259 build/serializers.py:308 part/models.py:2753 +#: part/models.py:2912 msgid "BOM Item" msgstr "" @@ -1010,7 +1014,7 @@ msgstr "" msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:340 stock/serializers.py:583 +#: build/serializers.py:340 stock/serializers.py:584 msgid "Item must be in stock" msgstr "" @@ -1336,7 +1340,7 @@ msgstr "" #: order/templates/order/po_sidebar.html:9 #: order/templates/order/purchase_order_detail.html:60 #: order/templates/order/sales_order_detail.html:107 -#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:193 +#: order/templates/order/so_sidebar.html:15 part/templates/part/detail.html:196 #: part/templates/part/part_sidebar.html:48 stock/templates/stock/item.html:95 #: stock/templates/stock/stock_sidebar.html:19 msgid "Attachments" @@ -1366,7 +1370,7 @@ msgstr "" msgid "All untracked stock items have been allocated" msgstr "" -#: build/templates/build/index.html:18 part/templates/part/detail.html:300 +#: build/templates/build/index.html:18 part/templates/part/detail.html:303 msgid "New Build Order" msgstr "新建生产订单" @@ -1647,9 +1651,9 @@ msgstr "" msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:703 part/models.py:2429 report/models.py:187 +#: common/models.py:703 part/models.py:2482 report/models.py:187 #: templates/js/translated/table_filters.js:38 -#: templates/js/translated/table_filters.js:404 +#: templates/js/translated/table_filters.js:422 msgid "Template" msgstr "模板" @@ -1657,9 +1661,9 @@ msgstr "模板" msgid "Parts are templates by default" msgstr "" -#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:1068 +#: common/models.py:710 part/models.py:919 templates/js/translated/bom.js:1068 #: templates/js/translated/table_filters.js:168 -#: templates/js/translated/table_filters.js:416 +#: templates/js/translated/table_filters.js:434 msgid "Assembly" msgstr "组装" @@ -1667,8 +1671,8 @@ msgstr "组装" msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:717 part/models.py:894 -#: templates/js/translated/table_filters.js:420 +#: common/models.py:717 part/models.py:925 +#: templates/js/translated/table_filters.js:438 msgid "Component" msgstr "组件" @@ -1676,7 +1680,7 @@ msgstr "组件" msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:724 part/models.py:905 +#: common/models.py:724 part/models.py:936 msgid "Purchaseable" msgstr "可购买" @@ -1684,8 +1688,8 @@ msgstr "可购买" msgid "Parts are purchaseable by default" msgstr "商品默认可购买" -#: common/models.py:731 part/models.py:910 -#: templates/js/translated/table_filters.js:428 +#: common/models.py:731 part/models.py:941 +#: templates/js/translated/table_filters.js:446 msgid "Salable" msgstr "可销售" @@ -1693,10 +1697,10 @@ msgstr "可销售" msgid "Parts are salable by default" msgstr "商品默认可销售" -#: common/models.py:738 part/models.py:900 +#: common/models.py:738 part/models.py:931 #: templates/js/translated/table_filters.js:46 #: templates/js/translated/table_filters.js:100 -#: templates/js/translated/table_filters.js:432 +#: templates/js/translated/table_filters.js:450 msgid "Trackable" msgstr "可追踪" @@ -1704,7 +1708,7 @@ msgstr "可追踪" msgid "Parts are trackable by default" msgstr "商品默认可跟踪" -#: common/models.py:745 part/models.py:920 +#: common/models.py:745 part/models.py:951 #: part/templates/part/part_base.html:147 #: templates/js/translated/table_filters.js:42 msgid "Virtual" @@ -2212,7 +2216,7 @@ msgstr "" #: common/models.py:1267 company/serializers.py:264 #: company/templates/company/supplier_part.html:256 -#: templates/js/translated/part.js:852 templates/js/translated/part.js:1803 +#: templates/js/translated/part.js:909 templates/js/translated/part.js:1860 msgid "Price" msgstr "价格" @@ -2224,7 +2228,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:24 order/views.py:243 #: part/templates/part/bom_upload/upload_file.html:52 #: part/templates/part/import_wizard/part_upload.html:47 part/views.py:212 -#: part/views.py:858 +#: part/views.py:764 msgid "Upload File" msgstr "上传文件" @@ -2232,7 +2236,7 @@ msgstr "上传文件" #: order/views.py:244 part/templates/part/bom_upload/match_fields.html:52 #: part/templates/part/import_wizard/ajax_match_fields.html:45 #: part/templates/part/import_wizard/match_fields.html:52 part/views.py:213 -#: part/views.py:859 +#: part/views.py:765 msgid "Match Fields" msgstr "匹配字段" @@ -2261,7 +2265,7 @@ msgid "Previous Step" msgstr "" #: company/forms.py:24 part/forms.py:46 -#: templates/InvenTree/settings/mixins/urls.html:12 +#: templates/InvenTree/settings/mixins/urls.html:14 msgid "URL" msgstr "URL" @@ -2324,7 +2328,7 @@ msgstr "" msgid "Link to external company information" msgstr "链接到外部公司信息" -#: company/models.py:139 part/models.py:807 +#: company/models.py:139 part/models.py:838 msgid "Image" msgstr "图片" @@ -2375,24 +2379,25 @@ msgstr "选择商品" #: company/templates/company/supplier_part.html:97 #: stock/templates/stock/item_base.html:379 #: templates/js/translated/company.js:333 -#: templates/js/translated/company.js:514 -#: templates/js/translated/company.js:797 templates/js/translated/part.js:232 +#: templates/js/translated/company.js:517 +#: templates/js/translated/company.js:800 templates/js/translated/part.js:234 +#: templates/js/translated/table_filters.js:389 msgid "Manufacturer" msgstr "制造商" -#: company/models.py:336 templates/js/translated/part.js:233 +#: company/models.py:336 templates/js/translated/part.js:235 msgid "Select manufacturer" msgstr "选择制造商" #: company/models.py:342 company/templates/company/manufacturer_part.html:96 #: company/templates/company/supplier_part.html:105 -#: templates/js/translated/company.js:530 -#: templates/js/translated/company.js:815 templates/js/translated/order.js:1038 -#: templates/js/translated/part.js:243 templates/js/translated/part.js:832 +#: templates/js/translated/company.js:533 +#: templates/js/translated/company.js:818 templates/js/translated/order.js:1038 +#: templates/js/translated/part.js:245 templates/js/translated/part.js:889 msgid "MPN" msgstr "MPN" -#: company/models.py:343 templates/js/translated/part.js:244 +#: company/models.py:343 templates/js/translated/part.js:246 msgid "Manufacturer Part Number" msgstr "制造商商品编号" @@ -2417,8 +2422,8 @@ msgstr "参数名称" #: company/models.py:422 #: report/templates/report/inventree_test_report_base.html:95 -#: stock/models.py:1960 templates/js/translated/company.js:644 -#: templates/js/translated/part.js:652 templates/js/translated/stock.js:1296 +#: stock/models.py:1960 templates/js/translated/company.js:647 +#: templates/js/translated/part.js:709 templates/js/translated/stock.js:1296 msgid "Value" msgstr "数值" @@ -2426,10 +2431,10 @@ msgstr "数值" msgid "Parameter value" msgstr "参数值" -#: company/models.py:429 part/models.py:882 part/models.py:2397 +#: company/models.py:429 part/models.py:913 part/models.py:2450 #: part/templates/part/part_base.html:288 #: templates/InvenTree/settings/settings.html:273 -#: templates/js/translated/company.js:650 templates/js/translated/part.js:658 +#: templates/js/translated/company.js:653 templates/js/translated/part.js:715 msgid "Units" msgstr "单位" @@ -2447,22 +2452,23 @@ msgstr "" #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:219 #: part/bom.py:247 stock/templates/stock/item_base.html:396 #: templates/js/translated/company.js:337 -#: templates/js/translated/company.js:771 templates/js/translated/order.js:823 -#: templates/js/translated/part.js:213 templates/js/translated/part.js:800 +#: templates/js/translated/company.js:774 templates/js/translated/order.js:823 +#: templates/js/translated/part.js:215 templates/js/translated/part.js:857 +#: templates/js/translated/table_filters.js:393 msgid "Supplier" msgstr "供应商" -#: company/models.py:546 templates/js/translated/part.js:214 +#: company/models.py:546 templates/js/translated/part.js:216 msgid "Select supplier" msgstr "选择供应商" #: company/models.py:551 company/templates/company/supplier_part.html:91 #: part/bom.py:220 part/bom.py:248 templates/js/translated/order.js:1025 -#: templates/js/translated/part.js:224 templates/js/translated/part.js:818 +#: templates/js/translated/part.js:226 templates/js/translated/part.js:875 msgid "SKU" msgstr "SKU" -#: company/models.py:552 templates/js/translated/part.js:225 +#: company/models.py:552 templates/js/translated/part.js:227 msgid "Supplier stock keeping unit" msgstr "" @@ -2479,22 +2485,22 @@ msgid "Supplier part description" msgstr "供应商商品描述" #: company/models.py:576 company/templates/company/supplier_part.html:119 -#: part/models.py:2588 report/templates/report/inventree_po_report.html:93 +#: part/models.py:2641 report/templates/report/inventree_po_report.html:93 #: report/templates/report/inventree_so_report.html:93 msgid "Note" msgstr "备注" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "base cost" msgstr "" -#: company/models.py:580 part/models.py:1748 +#: company/models.py:580 part/models.py:1779 msgid "Minimum charge (e.g. stocking fee)" msgstr "最低收费(例如库存费)" #: company/models.py:582 company/templates/company/supplier_part.html:112 #: stock/models.py:493 stock/templates/stock/item_base.html:337 -#: templates/js/translated/company.js:847 templates/js/translated/stock.js:1791 +#: templates/js/translated/company.js:850 templates/js/translated/stock.js:1791 msgid "Packaging" msgstr "打包" @@ -2502,7 +2508,7 @@ msgstr "打包" msgid "Part packaging" msgstr "商品打包" -#: company/models.py:584 part/models.py:1750 +#: company/models.py:584 part/models.py:1781 msgid "multiple" msgstr "" @@ -2563,10 +2569,11 @@ msgstr "从 URL 下载图片" #: company/templates/company/company_base.html:83 order/models.py:547 #: order/templates/order/sales_order_base.html:115 stock/models.py:512 -#: stock/models.py:513 stock/serializers.py:624 +#: stock/models.py:513 stock/serializers.py:625 #: stock/templates/stock/item_base.html:289 #: templates/js/translated/company.js:329 templates/js/translated/order.js:1240 #: templates/js/translated/stock.js:2452 +#: templates/js/translated/table_filters.js:397 msgid "Customer" msgstr "客户" @@ -2596,7 +2603,7 @@ msgstr "创建新的供应商商品" #: company/templates/company/detail.html:20 #: company/templates/company/manufacturer_part.html:118 -#: part/templates/part/detail.html:333 +#: part/templates/part/detail.html:336 msgid "New Supplier Part" msgstr "新建供应商商品" @@ -2604,8 +2611,8 @@ msgstr "新建供应商商品" #: company/templates/company/detail.html:79 #: company/templates/company/manufacturer_part.html:127 #: company/templates/company/manufacturer_part.html:156 -#: part/templates/part/category.html:171 part/templates/part/detail.html:342 -#: part/templates/part/detail.html:370 +#: part/templates/part/category.html:171 part/templates/part/detail.html:345 +#: part/templates/part/detail.html:374 msgid "Options" msgstr "选项" @@ -2633,7 +2640,7 @@ msgstr "制造商商品" msgid "Create new manufacturer part" msgstr "新建制造商商品" -#: company/templates/company/detail.html:67 part/templates/part/detail.html:360 +#: company/templates/company/detail.html:67 part/templates/part/detail.html:364 msgid "New Manufacturer Part" msgstr "新建制造商商品" @@ -2695,15 +2702,15 @@ msgstr "" msgid "Company Notes" msgstr "公司备注" -#: company/templates/company/detail.html:383 +#: company/templates/company/detail.html:384 #: company/templates/company/manufacturer_part.html:215 -#: part/templates/part/detail.html:413 +#: part/templates/part/detail.html:418 msgid "Delete Supplier Parts?" msgstr "删除供应商商品?" -#: company/templates/company/detail.html:384 +#: company/templates/company/detail.html:385 #: company/templates/company/manufacturer_part.html:216 -#: part/templates/part/detail.html:414 +#: part/templates/part/detail.html:419 msgid "All selected supplier parts will be deleted" msgstr "删除所有选定的供应商商品" @@ -2725,12 +2732,12 @@ msgid "Order part" msgstr "订购商品" #: company/templates/company/manufacturer_part.html:40 -#: templates/js/translated/company.js:562 +#: templates/js/translated/company.js:565 msgid "Edit manufacturer part" msgstr "编辑制造商商品" #: company/templates/company/manufacturer_part.html:44 -#: templates/js/translated/company.js:563 +#: templates/js/translated/company.js:566 msgid "Delete manufacturer part" msgstr "删除生产商商品" @@ -2747,15 +2754,15 @@ msgid "Suppliers" msgstr "供应商" #: company/templates/company/manufacturer_part.html:129 -#: part/templates/part/detail.html:344 +#: part/templates/part/detail.html:347 msgid "Delete supplier parts" msgstr "删除供应商商品" #: company/templates/company/manufacturer_part.html:129 #: company/templates/company/manufacturer_part.html:158 #: company/templates/company/manufacturer_part.html:254 -#: part/templates/part/detail.html:344 part/templates/part/detail.html:372 -#: templates/js/translated/company.js:425 templates/js/translated/helpers.js:31 +#: part/templates/part/detail.html:347 part/templates/part/detail.html:376 +#: templates/js/translated/company.js:426 templates/js/translated/helpers.js:31 #: users/models.py:209 msgid "Delete" msgstr "删除" @@ -2779,7 +2786,7 @@ msgid "Delete parameters" msgstr "删除参数" #: company/templates/company/manufacturer_part.html:191 -#: part/templates/part/detail.html:861 +#: part/templates/part/detail.html:862 msgid "Add Parameter" msgstr "添加参数" @@ -2810,17 +2817,17 @@ msgstr "" #: company/templates/company/supplier_part.html:7 #: company/templates/company/supplier_part.html:24 stock/models.py:477 #: stock/templates/stock/item_base.html:401 -#: templates/js/translated/company.js:787 templates/js/translated/stock.js:1748 +#: templates/js/translated/company.js:790 templates/js/translated/stock.js:1748 msgid "Supplier Part" msgstr "供应商商品" #: company/templates/company/supplier_part.html:38 -#: templates/js/translated/company.js:860 +#: templates/js/translated/company.js:863 msgid "Edit supplier part" msgstr "编辑供应商商品" #: company/templates/company/supplier_part.html:42 -#: templates/js/translated/company.js:861 +#: templates/js/translated/company.js:864 msgid "Delete supplier part" msgstr "删除供应商商品" @@ -2857,7 +2864,7 @@ msgstr "价格信息" #: company/templates/company/supplier_part.html:184 #: company/templates/company/supplier_part.html:290 -#: part/templates/part/prices.html:271 part/views.py:1713 +#: part/templates/part/prices.html:271 part/views.py:1619 msgid "Add Price Break" msgstr "" @@ -2865,11 +2872,11 @@ msgstr "" msgid "No price break information found" msgstr "" -#: company/templates/company/supplier_part.html:224 part/views.py:1775 +#: company/templates/company/supplier_part.html:224 part/views.py:1681 msgid "Delete Price Break" msgstr "" -#: company/templates/company/supplier_part.html:238 part/views.py:1761 +#: company/templates/company/supplier_part.html:238 part/views.py:1667 msgid "Edit Price Break" msgstr "" @@ -2887,9 +2894,9 @@ msgstr "" #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/search.html:150 #: templates/InvenTree/settings/sidebar.html:41 -#: templates/js/translated/bom.js:328 templates/js/translated/part.js:434 -#: templates/js/translated/part.js:569 templates/js/translated/part.js:1061 -#: templates/js/translated/part.js:1222 templates/js/translated/stock.js:927 +#: templates/js/translated/bom.js:328 templates/js/translated/part.js:489 +#: templates/js/translated/part.js:624 templates/js/translated/part.js:1118 +#: templates/js/translated/part.js:1279 templates/js/translated/stock.js:927 #: templates/js/translated/stock.js:1580 templates/navbar.html:28 msgid "Stock" msgstr "库存" @@ -3181,7 +3188,7 @@ msgstr "" #: order/templates/order/order_base.html:18 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:351 -#: templates/js/translated/order.js:801 templates/js/translated/part.js:775 +#: templates/js/translated/order.js:801 templates/js/translated/part.js:832 #: templates/js/translated/stock.js:1725 templates/js/translated/stock.js:2433 msgid "Purchase Order" msgstr "" @@ -3192,7 +3199,7 @@ msgstr "供应商商品" #: order/models.py:864 order/templates/order/order_base.html:163 #: templates/js/translated/order.js:589 templates/js/translated/order.js:1118 -#: templates/js/translated/part.js:847 templates/js/translated/part.js:873 +#: templates/js/translated/part.js:904 templates/js/translated/part.js:930 #: templates/js/translated/table_filters.js:317 msgid "Received" msgstr "" @@ -3717,7 +3724,6 @@ msgid "Edit Sales Order" msgstr "" #: order/templates/order/sales_order_cancel.html:8 -#: part/templates/part/bom_duplicate.html:12 #: stock/templates/stock/stockitem_convert.html:13 msgid "Warning" msgstr "警告" @@ -3811,23 +3817,35 @@ msgstr "" msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" -#: part/api.py:777 +#: part/api.py:499 +msgid "Valid" +msgstr "" + +#: part/api.py:500 +msgid "Validate entire Bill of Materials" +msgstr "" + +#: part/api.py:505 +msgid "This option must be selected" +msgstr "" + +#: part/api.py:847 msgid "Must be greater than zero" msgstr "必须大于0" -#: part/api.py:781 +#: part/api.py:851 msgid "Must be a valid quantity" msgstr "必须是有效的数量" -#: part/api.py:796 +#: part/api.py:866 msgid "Specify location for initial part stock" msgstr "指定初始初始商品仓储地点" -#: part/api.py:827 part/api.py:831 part/api.py:846 part/api.py:850 +#: part/api.py:897 part/api.py:901 part/api.py:916 part/api.py:920 msgid "This field is required" msgstr "此字段为必填" -#: part/bom.py:125 part/models.py:81 part/models.py:816 +#: part/bom.py:125 part/models.py:81 part/models.py:847 #: part/templates/part/category.html:108 part/templates/part/part_base.html:338 msgid "Default Location" msgstr "默认仓储地点" @@ -3836,43 +3854,19 @@ msgstr "默认仓储地点" msgid "Available Stock" msgstr "可用库存" -#: part/forms.py:66 part/models.py:2427 -msgid "Parent Part" -msgstr "" - -#: part/forms.py:67 part/templates/part/bom_duplicate.html:7 -msgid "Select parent part to copy BOM from" -msgstr "" - -#: part/forms.py:73 -msgid "Clear existing BOM items" -msgstr "" - -#: part/forms.py:79 -msgid "Confirm BOM duplication" -msgstr "" - -#: part/forms.py:97 -msgid "validate" -msgstr "" - -#: part/forms.py:97 -msgid "Confirm that the BOM is correct" -msgstr "确认BOM 正确" - -#: part/forms.py:133 +#: part/forms.py:85 msgid "Select part category" msgstr "选择类别" -#: part/forms.py:170 +#: part/forms.py:122 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:174 +#: part/forms.py:126 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:194 +#: part/forms.py:146 msgid "Input quantity for price calculation" msgstr "" @@ -3888,7 +3882,7 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "此类别商品的默认关键字" -#: part/models.py:95 part/models.py:2473 part/templates/part/category.html:15 +#: part/models.py:95 part/models.py:2526 part/templates/part/category.html:15 #: part/templates/part/part_app_base.html:10 msgid "Part Category" msgstr "商品类别" @@ -3905,7 +3899,7 @@ msgstr "商品类别" #: part/templates/part/category_sidebar.html:9 #: templates/InvenTree/index.html:85 templates/InvenTree/search.html:82 #: templates/InvenTree/settings/sidebar.html:37 -#: templates/js/translated/part.js:1599 templates/navbar.html:21 +#: templates/js/translated/part.js:1656 templates/navbar.html:21 #: templates/stats.html:80 templates/stats.html:89 users/models.py:41 msgid "Parts" msgstr "商品" @@ -3914,384 +3908,415 @@ msgstr "商品" msgid "Invalid choice for parent part" msgstr "" -#: part/models.py:502 part/models.py:514 +#: part/models.py:500 part/models.py:512 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" -#: part/models.py:611 +#: part/models.py:642 msgid "Next available serial numbers are" msgstr "" -#: part/models.py:615 +#: part/models.py:646 msgid "Next available serial number is" msgstr "" -#: part/models.py:620 +#: part/models.py:651 msgid "Most recent serial number is" msgstr "" -#: part/models.py:715 +#: part/models.py:746 msgid "Duplicate IPN not allowed in part settings" msgstr "在商品设置中不允许重复的IPN" -#: part/models.py:740 +#: part/models.py:771 msgid "Part name" msgstr "商品名称" -#: part/models.py:747 +#: part/models.py:778 msgid "Is Template" msgstr "" -#: part/models.py:748 +#: part/models.py:779 msgid "Is this part a template part?" msgstr "" -#: part/models.py:758 +#: part/models.py:789 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:759 +#: part/models.py:790 msgid "Variant Of" msgstr "" -#: part/models.py:765 +#: part/models.py:796 msgid "Part description" msgstr "商品描述" -#: part/models.py:770 part/templates/part/category.html:86 +#: part/models.py:801 part/templates/part/category.html:86 #: part/templates/part/part_base.html:302 msgid "Keywords" msgstr "关键词" -#: part/models.py:771 +#: part/models.py:802 msgid "Part keywords to improve visibility in search results" msgstr "提高搜索结果可见性的关键字" -#: part/models.py:778 part/models.py:2223 part/models.py:2472 +#: part/models.py:809 part/models.py:2276 part/models.py:2525 #: part/templates/part/part_base.html:265 #: part/templates/part/set_category.html:15 #: templates/InvenTree/settings/settings.html:172 -#: templates/js/translated/part.js:1204 +#: templates/js/translated/part.js:1261 msgid "Category" msgstr "类别" -#: part/models.py:779 +#: part/models.py:810 msgid "Part category" msgstr "商品类别" -#: part/models.py:784 part/templates/part/part_base.html:274 -#: templates/js/translated/part.js:557 templates/js/translated/part.js:1157 +#: part/models.py:815 part/templates/part/part_base.html:274 +#: templates/js/translated/part.js:612 templates/js/translated/part.js:1214 #: templates/js/translated/stock.js:1552 msgid "IPN" msgstr "" -#: part/models.py:785 +#: part/models.py:816 msgid "Internal Part Number" msgstr "内部商品编号" -#: part/models.py:791 +#: part/models.py:822 msgid "Part revision or version number" msgstr "商品版本号" -#: part/models.py:792 part/templates/part/part_base.html:281 -#: report/models.py:200 templates/js/translated/part.js:561 +#: part/models.py:823 part/templates/part/part_base.html:281 +#: report/models.py:200 templates/js/translated/part.js:616 msgid "Revision" msgstr "" -#: part/models.py:814 +#: part/models.py:845 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:861 part/templates/part/part_base.html:347 +#: part/models.py:892 part/templates/part/part_base.html:347 msgid "Default Supplier" msgstr "" -#: part/models.py:862 +#: part/models.py:893 msgid "Default supplier part" msgstr "默认供应商商品" -#: part/models.py:869 +#: part/models.py:900 msgid "Default Expiry" msgstr "" -#: part/models.py:870 +#: part/models.py:901 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:875 part/templates/part/part_base.html:196 +#: part/models.py:906 part/templates/part/part_base.html:196 msgid "Minimum Stock" msgstr "最低库存" -#: part/models.py:876 +#: part/models.py:907 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:883 +#: part/models.py:914 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:889 +#: part/models.py:920 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:895 +#: part/models.py:926 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:901 +#: part/models.py:932 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:906 +#: part/models.py:937 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:911 +#: part/models.py:942 msgid "Can this part be sold to customers?" msgstr "此商品可以销售给客户吗?" -#: part/models.py:915 plugin/models.py:45 +#: part/models.py:946 plugin/models.py:45 #: templates/js/translated/table_filters.js:34 #: templates/js/translated/table_filters.js:96 #: templates/js/translated/table_filters.js:295 -#: templates/js/translated/table_filters.js:399 +#: templates/js/translated/table_filters.js:417 msgid "Active" msgstr "" -#: part/models.py:916 +#: part/models.py:947 msgid "Is this part active?" msgstr "" -#: part/models.py:921 +#: part/models.py:952 msgid "Is this a virtual part, such as a software product or license?" msgstr "这是一个虚拟商品,如软件产品或许可证吗?" -#: part/models.py:926 +#: part/models.py:957 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "BOM checksum" msgstr "" -#: part/models.py:929 +#: part/models.py:960 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:932 +#: part/models.py:963 msgid "BOM checked by" msgstr "" -#: part/models.py:934 +#: part/models.py:965 msgid "BOM checked date" msgstr "" -#: part/models.py:938 +#: part/models.py:969 msgid "Creation User" msgstr "新建用户" -#: part/models.py:1750 +#: part/models.py:1781 msgid "Sell multiple" msgstr "" -#: part/models.py:2273 +#: part/models.py:2326 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:2290 +#: part/models.py:2343 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:2310 templates/js/translated/part.js:1650 +#: part/models.py:2363 templates/js/translated/part.js:1707 #: templates/js/translated/stock.js:1276 msgid "Test Name" msgstr "" -#: part/models.py:2311 +#: part/models.py:2364 msgid "Enter a name for the test" msgstr "" -#: part/models.py:2316 +#: part/models.py:2369 msgid "Test Description" msgstr "" -#: part/models.py:2317 +#: part/models.py:2370 msgid "Enter description for this test" msgstr "" -#: part/models.py:2322 templates/js/translated/part.js:1659 +#: part/models.py:2375 templates/js/translated/part.js:1716 #: templates/js/translated/table_filters.js:281 msgid "Required" msgstr "" -#: part/models.py:2323 +#: part/models.py:2376 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:2328 templates/js/translated/part.js:1667 +#: part/models.py:2381 templates/js/translated/part.js:1724 msgid "Requires Value" msgstr "" -#: part/models.py:2329 +#: part/models.py:2382 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:2334 templates/js/translated/part.js:1674 +#: part/models.py:2387 templates/js/translated/part.js:1731 msgid "Requires Attachment" msgstr "" -#: part/models.py:2335 +#: part/models.py:2388 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:2346 +#: part/models.py:2399 #, python-brace-format msgid "Illegal character in template name ({c})" msgstr "" -#: part/models.py:2382 +#: part/models.py:2435 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:2390 +#: part/models.py:2443 msgid "Parameter Name" msgstr "" -#: part/models.py:2397 +#: part/models.py:2450 msgid "Parameter Units" msgstr "" -#: part/models.py:2429 part/models.py:2478 part/models.py:2479 +#: part/models.py:2480 +msgid "Parent Part" +msgstr "" + +#: part/models.py:2482 part/models.py:2531 part/models.py:2532 #: templates/InvenTree/settings/settings.html:167 msgid "Parameter Template" msgstr "参数模板" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Data" msgstr "" -#: part/models.py:2431 +#: part/models.py:2484 msgid "Parameter Value" msgstr "" -#: part/models.py:2483 templates/InvenTree/settings/settings.html:176 +#: part/models.py:2536 templates/InvenTree/settings/settings.html:176 msgid "Default Value" msgstr "默认值" -#: part/models.py:2484 +#: part/models.py:2537 msgid "Default Parameter Value" msgstr "" -#: part/models.py:2561 +#: part/models.py:2614 msgid "Select parent part" msgstr "" -#: part/models.py:2569 +#: part/models.py:2622 msgid "Sub part" msgstr "" -#: part/models.py:2570 +#: part/models.py:2623 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:2576 +#: part/models.py:2629 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2578 templates/js/translated/bom.js:566 +#: part/models.py:2631 templates/js/translated/bom.js:566 #: templates/js/translated/bom.js:640 #: templates/js/translated/table_filters.js:92 msgid "Optional" msgstr "可选项" -#: part/models.py:2578 +#: part/models.py:2631 msgid "This BOM item is optional" msgstr "" -#: part/models.py:2581 +#: part/models.py:2634 msgid "Overage" msgstr "" -#: part/models.py:2582 +#: part/models.py:2635 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:2585 +#: part/models.py:2638 msgid "BOM item reference" msgstr "" -#: part/models.py:2588 +#: part/models.py:2641 msgid "BOM item notes" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "Checksum" msgstr "" -#: part/models.py:2590 +#: part/models.py:2643 msgid "BOM line checksum" msgstr "" -#: part/models.py:2594 templates/js/translated/bom.js:657 -#: templates/js/translated/bom.js:664 +#: part/models.py:2647 templates/js/translated/bom.js:657 #: templates/js/translated/table_filters.js:68 #: templates/js/translated/table_filters.js:88 msgid "Inherited" msgstr "继承项" -#: part/models.py:2595 +#: part/models.py:2648 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2600 templates/js/translated/bom.js:649 +#: part/models.py:2653 templates/js/translated/bom.js:649 msgid "Allow Variants" msgstr "" -#: part/models.py:2601 +#: part/models.py:2654 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2686 stock/models.py:355 +#: part/models.py:2739 stock/models.py:355 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:2695 part/models.py:2697 +#: part/models.py:2748 part/models.py:2750 msgid "Sub part must be specified" msgstr "" -#: part/models.py:2826 +#: part/models.py:2879 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:2848 +#: part/models.py:2901 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:2860 +#: part/models.py:2913 msgid "Parent BOM item" msgstr "" -#: part/models.py:2868 +#: part/models.py:2921 msgid "Substitute part" msgstr "" -#: part/models.py:2879 +#: part/models.py:2932 msgid "Part 1" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Part 2" msgstr "" -#: part/models.py:2883 +#: part/models.py:2936 msgid "Select Related Part" msgstr "" -#: part/models.py:2915 +#: part/models.py:2968 msgid "Error creating relationship: check that the part is not related to itself and that the relationship is unique" msgstr "" +#: part/serializers.py:659 +msgid "Select part to copy BOM from" +msgstr "" + +#: part/serializers.py:670 +msgid "Remove Existing Data" +msgstr "" + +#: part/serializers.py:671 +msgid "Remove existing BOM items before copying" +msgstr "" + +#: part/serializers.py:676 +msgid "Include Inherited" +msgstr "" + +#: part/serializers.py:677 +msgid "Include BOM items which are inherited from templated parts" +msgstr "" + +#: part/serializers.py:682 +msgid "Skip Invalid Rows" +msgstr "" + +#: part/serializers.py:683 +msgid "Enable this option to skip invalid rows" +msgstr "" + #: part/tasks.py:53 msgid "Low stock notification" msgstr "" @@ -4315,7 +4340,7 @@ msgstr "" msgid "The BOM for %(part)s has not been validated." msgstr "" -#: part/templates/part/bom.html:30 part/templates/part/detail.html:250 +#: part/templates/part/bom.html:30 part/templates/part/detail.html:253 msgid "BOM actions" msgstr "" @@ -4323,10 +4348,6 @@ msgstr "" msgid "Delete Items" msgstr "" -#: part/templates/part/bom_duplicate.html:13 -msgid "This part already has a Bill of Materials" -msgstr "" - #: part/templates/part/bom_upload/match_parts.html:29 msgid "Select Part" msgstr "选择商品" @@ -4355,15 +4376,6 @@ msgstr "" msgid "Each part must already exist in the database" msgstr "每个商品必须已经存在于数据库" -#: part/templates/part/bom_validate.html:6 -#, python-format -msgid "Confirm that the Bill of Materials (BOM) is valid for:
%(part)s" -msgstr "" - -#: part/templates/part/bom_validate.html:9 -msgid "This will validate each line in the BOM." -msgstr "" - #: part/templates/part/category.html:28 part/templates/part/category.html:32 msgid "You are subscribed to notifications for this category" msgstr "" @@ -4500,7 +4512,7 @@ msgstr "" msgid "Import Parts" msgstr "" -#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:373 +#: part/templates/part/copy_part.html:9 templates/js/translated/part.js:375 msgid "Duplicate Part" msgstr "复制部件" @@ -4561,118 +4573,118 @@ msgstr "" msgid "Add new parameter" msgstr "" -#: part/templates/part/detail.html:208 part/templates/part/part_sidebar.html:45 +#: part/templates/part/detail.html:211 part/templates/part/part_sidebar.html:45 msgid "Related Parts" msgstr "" -#: part/templates/part/detail.html:212 part/templates/part/detail.html:213 +#: part/templates/part/detail.html:215 part/templates/part/detail.html:216 msgid "Add Related" msgstr "" -#: part/templates/part/detail.html:233 part/templates/part/part_sidebar.html:17 +#: part/templates/part/detail.html:236 part/templates/part/part_sidebar.html:17 msgid "Bill of Materials" msgstr "" -#: part/templates/part/detail.html:238 +#: part/templates/part/detail.html:241 msgid "Export actions" msgstr "" -#: part/templates/part/detail.html:242 templates/js/translated/bom.js:70 +#: part/templates/part/detail.html:245 templates/js/translated/bom.js:70 msgid "Export BOM" msgstr "" -#: part/templates/part/detail.html:244 +#: part/templates/part/detail.html:247 msgid "Print BOM Report" msgstr "" -#: part/templates/part/detail.html:254 +#: part/templates/part/detail.html:257 msgid "Upload BOM" msgstr "" -#: part/templates/part/detail.html:256 templates/js/translated/part.js:270 +#: part/templates/part/detail.html:259 templates/js/translated/part.js:272 msgid "Copy BOM" msgstr "" -#: part/templates/part/detail.html:258 part/views.py:755 +#: part/templates/part/detail.html:261 msgid "Validate BOM" msgstr "" -#: part/templates/part/detail.html:263 +#: part/templates/part/detail.html:266 msgid "New BOM Item" msgstr "" -#: part/templates/part/detail.html:264 +#: part/templates/part/detail.html:267 msgid "Add BOM Item" msgstr "" -#: part/templates/part/detail.html:277 +#: part/templates/part/detail.html:280 msgid "Assemblies" msgstr "" -#: part/templates/part/detail.html:294 +#: part/templates/part/detail.html:297 msgid "Part Builds" msgstr "" -#: part/templates/part/detail.html:319 +#: part/templates/part/detail.html:322 msgid "Build Order Allocations" msgstr "" -#: part/templates/part/detail.html:329 +#: part/templates/part/detail.html:332 msgid "Part Suppliers" msgstr "商品供应商" -#: part/templates/part/detail.html:356 +#: part/templates/part/detail.html:360 msgid "Part Manufacturers" msgstr "商品制造商" -#: part/templates/part/detail.html:372 +#: part/templates/part/detail.html:376 msgid "Delete manufacturer parts" msgstr "删除制造商商品" -#: part/templates/part/detail.html:553 +#: part/templates/part/detail.html:558 msgid "Delete selected BOM items?" msgstr "" -#: part/templates/part/detail.html:554 +#: part/templates/part/detail.html:559 msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/detail.html:605 +#: part/templates/part/detail.html:608 msgid "Create BOM Item" msgstr "" -#: part/templates/part/detail.html:651 +#: part/templates/part/detail.html:652 msgid "Related Part" msgstr "" -#: part/templates/part/detail.html:659 +#: part/templates/part/detail.html:660 msgid "Add Related Part" msgstr "" -#: part/templates/part/detail.html:754 +#: part/templates/part/detail.html:755 msgid "Add Test Result Template" msgstr "" -#: part/templates/part/detail.html:811 +#: part/templates/part/detail.html:812 msgid "Edit Part Notes" msgstr "编辑商品注释" -#: part/templates/part/detail.html:924 +#: part/templates/part/detail.html:925 #, python-format msgid "Purchase Unit Price - %(currency)s" msgstr "" -#: part/templates/part/detail.html:936 +#: part/templates/part/detail.html:937 #, python-format msgid "Unit Price-Cost Difference - %(currency)s" msgstr "" -#: part/templates/part/detail.html:948 +#: part/templates/part/detail.html:949 #, python-format msgid "Supplier Unit Cost - %(currency)s" msgstr "" -#: part/templates/part/detail.html:1037 +#: part/templates/part/detail.html:1038 #, python-format msgid "Unit Price - %(currency)s" msgstr "" @@ -4784,10 +4796,10 @@ msgid "Part is virtual (not a physical part)" msgstr "商品是虚拟的(不是实体零件)" #: part/templates/part/part_base.html:139 -#: templates/js/translated/company.js:505 -#: templates/js/translated/company.js:762 +#: templates/js/translated/company.js:508 +#: templates/js/translated/company.js:765 #: templates/js/translated/model_renderers.js:175 -#: templates/js/translated/part.js:472 templates/js/translated/part.js:549 +#: templates/js/translated/part.js:527 templates/js/translated/part.js:604 msgid "Inactive" msgstr "" @@ -4806,7 +4818,7 @@ msgstr "" msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1237 +#: part/templates/part/part_base.html:203 templates/js/translated/part.js:1294 msgid "On Order" msgstr "" @@ -4826,8 +4838,8 @@ msgstr "" msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1068 -#: templates/js/translated/part.js:1241 +#: part/templates/part/part_base.html:245 templates/js/translated/part.js:1125 +#: templates/js/translated/part.js:1298 msgid "Building" msgstr "" @@ -5016,7 +5028,7 @@ msgstr "" msgid "Internal Cost" msgstr "" -#: part/templates/part/prices.html:215 part/views.py:1784 +#: part/templates/part/prices.html:215 part/views.py:1690 msgid "Add Internal Price Break" msgstr "" @@ -5037,8 +5049,8 @@ msgid "Set category for the following parts" msgstr "为以下商品设置类别" #: part/templates/part/stock_count.html:7 templates/js/translated/bom.js:588 -#: templates/js/translated/part.js:436 templates/js/translated/part.js:1058 -#: templates/js/translated/part.js:1245 +#: templates/js/translated/part.js:491 templates/js/translated/part.js:1115 +#: templates/js/translated/part.js:1302 msgid "No Stock" msgstr "" @@ -5092,87 +5104,71 @@ msgstr "更新商品图像" msgid "Part image not found" msgstr "未找到商品图像" -#: part/views.py:704 -msgid "Duplicate BOM" -msgstr "" - -#: part/views.py:734 -msgid "Confirm duplication of BOM from parent" -msgstr "" - -#: part/views.py:776 -msgid "Confirm that the BOM is valid" -msgstr "" - -#: part/views.py:787 -msgid "Validated Bill of Materials" -msgstr "" - -#: part/views.py:860 +#: part/views.py:766 msgid "Match Parts" msgstr "匹配商品" -#: part/views.py:1195 +#: part/views.py:1101 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1244 +#: part/views.py:1150 msgid "Confirm Part Deletion" msgstr "确认删除商品" -#: part/views.py:1251 +#: part/views.py:1157 msgid "Part was deleted" msgstr "商品已删除" -#: part/views.py:1260 +#: part/views.py:1166 msgid "Part Pricing" msgstr "商品价格" -#: part/views.py:1409 +#: part/views.py:1315 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1419 +#: part/views.py:1325 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1426 +#: part/views.py:1332 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1485 templates/js/translated/part.js:313 +#: part/views.py:1391 templates/js/translated/part.js:315 msgid "Edit Part Category" msgstr "编辑商品类别" -#: part/views.py:1523 +#: part/views.py:1429 msgid "Delete Part Category" msgstr "删除商品类别" -#: part/views.py:1529 +#: part/views.py:1435 msgid "Part category was deleted" msgstr "商品类别已删除" -#: part/views.py:1538 +#: part/views.py:1444 msgid "Create Category Parameter Template" msgstr "创建类别参数模板" -#: part/views.py:1639 +#: part/views.py:1545 msgid "Edit Category Parameter Template" msgstr "编辑类别参数模板" -#: part/views.py:1695 +#: part/views.py:1601 msgid "Delete Category Parameter Template" msgstr "删除类别参数模板" -#: part/views.py:1717 +#: part/views.py:1623 msgid "Added new price break" msgstr "" -#: part/views.py:1793 +#: part/views.py:1699 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:1801 +#: part/views.py:1707 msgid "Delete Internal Price Break" msgstr "" @@ -5208,11 +5204,11 @@ msgstr "" msgid "Is the plugin active" msgstr "" -#: plugin/samples/integration/sample.py:39 +#: plugin/samples/integration/sample.py:42 msgid "Enable PO" msgstr "" -#: plugin/samples/integration/sample.py:40 +#: plugin/samples/integration/sample.py:43 msgid "Enable PO functionality in InvenTree interface" msgstr "" @@ -5622,7 +5618,7 @@ msgstr "" msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:1186 stock/serializers.py:773 +#: stock/models.py:1186 stock/serializers.py:774 msgid "Duplicate stock items" msgstr "" @@ -5695,7 +5691,7 @@ msgstr "" msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:326 stock/serializers.py:730 stock/serializers.py:971 +#: stock/serializers.py:326 stock/serializers.py:731 stock/serializers.py:972 msgid "Destination stock location" msgstr "" @@ -5707,63 +5703,63 @@ msgstr "" msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:587 +#: stock/serializers.py:588 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:591 +#: stock/serializers.py:592 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:595 +#: stock/serializers.py:596 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:625 +#: stock/serializers.py:626 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:631 +#: stock/serializers.py:632 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:639 +#: stock/serializers.py:640 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:649 stock/serializers.py:879 +#: stock/serializers.py:650 stock/serializers.py:880 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:737 +#: stock/serializers.py:738 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:742 +#: stock/serializers.py:743 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:743 +#: stock/serializers.py:744 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:748 +#: stock/serializers.py:749 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:749 +#: stock/serializers.py:750 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:759 +#: stock/serializers.py:760 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:841 +#: stock/serializers.py:842 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:869 +#: stock/serializers.py:870 msgid "Stock transaction notes" msgstr "" @@ -6378,22 +6374,22 @@ msgstr "" msgid "Signup" msgstr "" -#: templates/InvenTree/settings/mixins/settings.html:4 +#: templates/InvenTree/settings/mixins/settings.html:5 #: templates/InvenTree/settings/settings.html:12 templates/navbar.html:118 msgid "Settings" msgstr "设置" -#: templates/InvenTree/settings/mixins/urls.html:4 +#: templates/InvenTree/settings/mixins/urls.html:5 msgid "URLs" msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:6 +#: templates/InvenTree/settings/mixins/urls.html:8 #, python-format msgid "The Base-URL for this plugin is %(base)s." msgstr "" -#: templates/InvenTree/settings/mixins/urls.html:21 -msgid "open in new tab" +#: templates/InvenTree/settings/mixins/urls.html:23 +msgid "Open in new tab" msgstr "" #: templates/InvenTree/settings/part.html:7 @@ -6444,11 +6440,6 @@ msgstr "" msgid "Version" msgstr "" -#: templates/InvenTree/settings/plugin.html:73 -#, python-format -msgid "has %(name)s" -msgstr "" - #: templates/InvenTree/settings/plugin.html:91 msgid "Inactive plugins" msgstr "" @@ -6482,53 +6473,53 @@ msgstr "" msgid "License" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:70 +#: templates/InvenTree/settings/plugin_settings.html:71 msgid "The code information is pulled from the latest git commit for this plugin. It might not reflect official version numbers or information but the actual code running." msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:74 +#: templates/InvenTree/settings/plugin_settings.html:77 msgid "Package information" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:80 +#: templates/InvenTree/settings/plugin_settings.html:83 msgid "Installation method" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:83 +#: templates/InvenTree/settings/plugin_settings.html:86 msgid "This plugin was installed as a package" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:85 +#: templates/InvenTree/settings/plugin_settings.html:88 msgid "This plugin was found in a local InvenTree path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:91 +#: templates/InvenTree/settings/plugin_settings.html:94 msgid "Installation path" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:97 +#: templates/InvenTree/settings/plugin_settings.html:100 msgid "Commit Author" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:101 +#: templates/InvenTree/settings/plugin_settings.html:104 #: templates/about.html:47 msgid "Commit Date" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:105 +#: templates/InvenTree/settings/plugin_settings.html:108 #: templates/about.html:40 msgid "Commit Hash" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:109 +#: templates/InvenTree/settings/plugin_settings.html:112 msgid "Commit Message" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:114 +#: templates/InvenTree/settings/plugin_settings.html:117 msgid "Sign Status" msgstr "" -#: templates/InvenTree/settings/plugin_settings.html:119 +#: templates/InvenTree/settings/plugin_settings.html:122 msgid "Sign Key" msgstr "" @@ -7262,47 +7253,55 @@ msgstr "" msgid "The requested resource could not be located on the server" msgstr "" -#: templates/js/translated/api.js:212 templates/js/translated/modals.js:1060 +#: templates/js/translated/api.js:212 +msgid "Error 405: Method Not Allowed" +msgstr "" + +#: templates/js/translated/api.js:213 +msgid "HTTP method not allowed at URL" +msgstr "" + +#: templates/js/translated/api.js:217 templates/js/translated/modals.js:1060 msgid "Error 408: Timeout" msgstr "" -#: templates/js/translated/api.js:213 templates/js/translated/modals.js:1061 +#: templates/js/translated/api.js:218 templates/js/translated/modals.js:1061 msgid "Connection timeout while requesting data from server" msgstr "" -#: templates/js/translated/api.js:216 +#: templates/js/translated/api.js:221 msgid "Unhandled Error Code" msgstr "" -#: templates/js/translated/api.js:217 +#: templates/js/translated/api.js:222 msgid "Error code" msgstr "" -#: templates/js/translated/attachment.js:76 +#: templates/js/translated/attachment.js:78 msgid "No attachments found" msgstr "" -#: templates/js/translated/attachment.js:98 +#: templates/js/translated/attachment.js:100 msgid "Edit Attachment" msgstr "编辑附件" -#: templates/js/translated/attachment.js:108 +#: templates/js/translated/attachment.js:110 msgid "Confirm Delete" msgstr "" -#: templates/js/translated/attachment.js:109 +#: templates/js/translated/attachment.js:111 msgid "Delete Attachment" msgstr "删除附件" -#: templates/js/translated/attachment.js:165 +#: templates/js/translated/attachment.js:167 msgid "Upload Date" msgstr "" -#: templates/js/translated/attachment.js:178 +#: templates/js/translated/attachment.js:180 msgid "Edit attachment" msgstr "" -#: templates/js/translated/attachment.js:185 +#: templates/js/translated/attachment.js:187 msgid "Delete attachment" msgstr "" @@ -7695,8 +7694,8 @@ msgstr "" msgid "No builds matching query" msgstr "" -#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1149 -#: templates/js/translated/part.js:1560 templates/js/translated/stock.js:1512 +#: templates/js/translated/build.js:1599 templates/js/translated/part.js:1206 +#: templates/js/translated/part.js:1617 templates/js/translated/stock.js:1512 #: templates/js/translated/stock.js:2321 msgid "Select" msgstr "" @@ -7761,55 +7760,55 @@ msgstr "" msgid "Parts Manufactured" msgstr "" -#: templates/js/translated/company.js:386 +#: templates/js/translated/company.js:387 msgid "No company information found" msgstr "未找到该公司信息" -#: templates/js/translated/company.js:405 +#: templates/js/translated/company.js:406 msgid "The following manufacturer parts will be deleted" msgstr "" -#: templates/js/translated/company.js:422 +#: templates/js/translated/company.js:423 msgid "Delete Manufacturer Parts" msgstr "删除制造商商品" -#: templates/js/translated/company.js:477 +#: templates/js/translated/company.js:480 msgid "No manufacturer parts found" msgstr "" -#: templates/js/translated/company.js:497 -#: templates/js/translated/company.js:754 templates/js/translated/part.js:456 -#: templates/js/translated/part.js:541 +#: templates/js/translated/company.js:500 +#: templates/js/translated/company.js:757 templates/js/translated/part.js:511 +#: templates/js/translated/part.js:596 msgid "Template part" msgstr "" -#: templates/js/translated/company.js:501 -#: templates/js/translated/company.js:758 templates/js/translated/part.js:460 -#: templates/js/translated/part.js:545 +#: templates/js/translated/company.js:504 +#: templates/js/translated/company.js:761 templates/js/translated/part.js:515 +#: templates/js/translated/part.js:600 msgid "Assembled part" msgstr "" -#: templates/js/translated/company.js:628 templates/js/translated/part.js:633 +#: templates/js/translated/company.js:631 templates/js/translated/part.js:690 msgid "No parameters found" msgstr "无指定参数" -#: templates/js/translated/company.js:665 templates/js/translated/part.js:675 +#: templates/js/translated/company.js:668 templates/js/translated/part.js:732 msgid "Edit parameter" msgstr "编辑参数" -#: templates/js/translated/company.js:666 templates/js/translated/part.js:676 +#: templates/js/translated/company.js:669 templates/js/translated/part.js:733 msgid "Delete parameter" msgstr "删除参数" -#: templates/js/translated/company.js:685 templates/js/translated/part.js:693 +#: templates/js/translated/company.js:688 templates/js/translated/part.js:750 msgid "Edit Parameter" msgstr "编辑参数" -#: templates/js/translated/company.js:696 templates/js/translated/part.js:705 +#: templates/js/translated/company.js:699 templates/js/translated/part.js:762 msgid "Delete Parameter" msgstr "删除参数" -#: templates/js/translated/company.js:734 +#: templates/js/translated/company.js:737 msgid "No supplier parts found" msgstr "未找到供应商商品" @@ -8110,7 +8109,7 @@ msgstr "" msgid "Receive Purchase Order Items" msgstr "" -#: templates/js/translated/order.js:790 templates/js/translated/part.js:746 +#: templates/js/translated/order.js:790 templates/js/translated/part.js:803 msgid "No purchase orders found" msgstr "" @@ -8135,7 +8134,7 @@ msgid "Total" msgstr "" #: templates/js/translated/order.js:1068 templates/js/translated/order.js:2163 -#: templates/js/translated/part.js:1777 templates/js/translated/part.js:1988 +#: templates/js/translated/part.js:1834 templates/js/translated/part.js:2045 msgid "Unit Price" msgstr "单价" @@ -8151,7 +8150,7 @@ msgstr "" msgid "Delete line item" msgstr "" -#: templates/js/translated/order.js:1166 templates/js/translated/part.js:878 +#: templates/js/translated/order.js:1166 templates/js/translated/part.js:935 msgid "Receive line item" msgstr "" @@ -8260,216 +8259,232 @@ msgstr "" msgid "No matching line items" msgstr "" -#: templates/js/translated/part.js:52 +#: templates/js/translated/part.js:54 msgid "Part Attributes" msgstr "商品属性" -#: templates/js/translated/part.js:56 +#: templates/js/translated/part.js:58 msgid "Part Creation Options" msgstr "商品创建选项" -#: templates/js/translated/part.js:60 +#: templates/js/translated/part.js:62 msgid "Part Duplication Options" msgstr "商品重复选项" -#: templates/js/translated/part.js:64 +#: templates/js/translated/part.js:66 msgid "Supplier Options" msgstr "" -#: templates/js/translated/part.js:78 +#: templates/js/translated/part.js:80 msgid "Add Part Category" msgstr "增加商品类别" -#: templates/js/translated/part.js:162 +#: templates/js/translated/part.js:164 msgid "Create Initial Stock" msgstr "" -#: templates/js/translated/part.js:163 +#: templates/js/translated/part.js:165 msgid "Create an initial stock item for this part" msgstr "" -#: templates/js/translated/part.js:170 +#: templates/js/translated/part.js:172 msgid "Initial Stock Quantity" msgstr "" -#: templates/js/translated/part.js:171 +#: templates/js/translated/part.js:173 msgid "Specify initial stock quantity for this part" msgstr "" -#: templates/js/translated/part.js:178 +#: templates/js/translated/part.js:180 msgid "Select destination stock location" msgstr "" -#: templates/js/translated/part.js:196 +#: templates/js/translated/part.js:198 msgid "Copy Category Parameters" msgstr "复制类别参数" -#: templates/js/translated/part.js:197 +#: templates/js/translated/part.js:199 msgid "Copy parameter templates from selected part category" msgstr "" -#: templates/js/translated/part.js:205 +#: templates/js/translated/part.js:207 msgid "Add Supplier Data" msgstr "" -#: templates/js/translated/part.js:206 +#: templates/js/translated/part.js:208 msgid "Create initial supplier data for this part" msgstr "" -#: templates/js/translated/part.js:262 +#: templates/js/translated/part.js:264 msgid "Copy Image" msgstr "" -#: templates/js/translated/part.js:263 +#: templates/js/translated/part.js:265 msgid "Copy image from original part" msgstr "" -#: templates/js/translated/part.js:271 +#: templates/js/translated/part.js:273 msgid "Copy bill of materials from original part" msgstr "" -#: templates/js/translated/part.js:278 +#: templates/js/translated/part.js:280 msgid "Copy Parameters" msgstr "" -#: templates/js/translated/part.js:279 +#: templates/js/translated/part.js:281 msgid "Copy parameter data from original part" msgstr "" -#: templates/js/translated/part.js:292 +#: templates/js/translated/part.js:294 msgid "Parent part category" msgstr "" -#: templates/js/translated/part.js:336 +#: templates/js/translated/part.js:338 msgid "Edit Part" msgstr "编辑商品" -#: templates/js/translated/part.js:338 +#: templates/js/translated/part.js:340 msgid "Part edited" msgstr "" -#: templates/js/translated/part.js:410 +#: templates/js/translated/part.js:412 msgid "You are subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:412 +#: templates/js/translated/part.js:414 msgid "You have subscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:417 +#: templates/js/translated/part.js:419 msgid "Subscribe to notifications for this item" msgstr "" -#: templates/js/translated/part.js:419 +#: templates/js/translated/part.js:421 msgid "You have unsubscribed to notifications for this item" msgstr "" -#: templates/js/translated/part.js:448 templates/js/translated/part.js:533 +#: templates/js/translated/part.js:438 +msgid "Validating the BOM will mark each line item as valid" +msgstr "" + +#: templates/js/translated/part.js:448 +msgid "Validate Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:451 +msgid "Validated Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:475 +msgid "Copy Bill of Materials" +msgstr "" + +#: templates/js/translated/part.js:503 templates/js/translated/part.js:588 msgid "Trackable part" msgstr "可追溯商品" -#: templates/js/translated/part.js:452 templates/js/translated/part.js:537 +#: templates/js/translated/part.js:507 templates/js/translated/part.js:592 msgid "Virtual part" msgstr "虚拟商品" -#: templates/js/translated/part.js:464 +#: templates/js/translated/part.js:519 msgid "Subscribed part" msgstr "" -#: templates/js/translated/part.js:468 +#: templates/js/translated/part.js:523 msgid "Salable part" msgstr "可销售商品" -#: templates/js/translated/part.js:583 +#: templates/js/translated/part.js:638 msgid "No variants found" msgstr "" -#: templates/js/translated/part.js:948 +#: templates/js/translated/part.js:1005 msgid "Delete part relationship" msgstr "" -#: templates/js/translated/part.js:972 +#: templates/js/translated/part.js:1029 msgid "Delete Part Relationship" msgstr "" -#: templates/js/translated/part.js:1039 templates/js/translated/part.js:1299 +#: templates/js/translated/part.js:1096 templates/js/translated/part.js:1356 msgid "No parts found" msgstr "" -#: templates/js/translated/part.js:1209 +#: templates/js/translated/part.js:1266 msgid "No category" msgstr "没有分类" -#: templates/js/translated/part.js:1232 -#: templates/js/translated/table_filters.js:412 +#: templates/js/translated/part.js:1289 +#: templates/js/translated/table_filters.js:430 msgid "Low stock" msgstr "" -#: templates/js/translated/part.js:1323 templates/js/translated/part.js:1495 +#: templates/js/translated/part.js:1380 templates/js/translated/part.js:1552 #: templates/js/translated/stock.js:2282 msgid "Display as list" msgstr "" -#: templates/js/translated/part.js:1339 +#: templates/js/translated/part.js:1396 msgid "Display as grid" msgstr "" -#: templates/js/translated/part.js:1514 templates/js/translated/stock.js:2301 +#: templates/js/translated/part.js:1571 templates/js/translated/stock.js:2301 msgid "Display as tree" msgstr "" -#: templates/js/translated/part.js:1578 +#: templates/js/translated/part.js:1635 msgid "Subscribed category" msgstr "" -#: templates/js/translated/part.js:1592 templates/js/translated/stock.js:2345 +#: templates/js/translated/part.js:1649 templates/js/translated/stock.js:2345 msgid "Path" msgstr "" -#: templates/js/translated/part.js:1636 +#: templates/js/translated/part.js:1693 msgid "No test templates matching query" msgstr "" -#: templates/js/translated/part.js:1687 templates/js/translated/stock.js:1234 +#: templates/js/translated/part.js:1744 templates/js/translated/stock.js:1234 msgid "Edit test result" msgstr "" -#: templates/js/translated/part.js:1688 templates/js/translated/stock.js:1235 +#: templates/js/translated/part.js:1745 templates/js/translated/stock.js:1235 msgid "Delete test result" msgstr "" -#: templates/js/translated/part.js:1694 +#: templates/js/translated/part.js:1751 msgid "This test is defined for a parent part" msgstr "" -#: templates/js/translated/part.js:1716 +#: templates/js/translated/part.js:1773 msgid "Edit Test Result Template" msgstr "" -#: templates/js/translated/part.js:1730 +#: templates/js/translated/part.js:1787 msgid "Delete Test Result Template" msgstr "" -#: templates/js/translated/part.js:1755 +#: templates/js/translated/part.js:1812 #, python-brace-format msgid "No ${human_name} information found" msgstr "" -#: templates/js/translated/part.js:1810 +#: templates/js/translated/part.js:1867 #, python-brace-format msgid "Edit ${human_name}" msgstr "" -#: templates/js/translated/part.js:1811 +#: templates/js/translated/part.js:1868 #, python-brace-format msgid "Delete ${human_name}" msgstr "" -#: templates/js/translated/part.js:1912 +#: templates/js/translated/part.js:1969 msgid "Single Price" msgstr "" -#: templates/js/translated/part.js:1931 +#: templates/js/translated/part.js:1988 msgid "Single Price Difference" msgstr "" @@ -8907,12 +8922,12 @@ msgstr "" #: templates/js/translated/table_filters.js:121 #: templates/js/translated/table_filters.js:122 -#: templates/js/translated/table_filters.js:389 +#: templates/js/translated/table_filters.js:407 msgid "Include subcategories" msgstr "" #: templates/js/translated/table_filters.js:126 -#: templates/js/translated/table_filters.js:424 +#: templates/js/translated/table_filters.js:442 msgid "Subscribed" msgstr "" @@ -9059,27 +9074,27 @@ msgstr "" msgid "Outstanding" msgstr "" -#: templates/js/translated/table_filters.js:390 +#: templates/js/translated/table_filters.js:408 msgid "Include parts in subcategories" msgstr "" -#: templates/js/translated/table_filters.js:394 +#: templates/js/translated/table_filters.js:412 msgid "Has IPN" msgstr "" -#: templates/js/translated/table_filters.js:395 +#: templates/js/translated/table_filters.js:413 msgid "Part has internal part number" msgstr "商品有内部编号" -#: templates/js/translated/table_filters.js:400 +#: templates/js/translated/table_filters.js:418 msgid "Show active parts" msgstr "" -#: templates/js/translated/table_filters.js:408 +#: templates/js/translated/table_filters.js:426 msgid "Stock available" msgstr "" -#: templates/js/translated/table_filters.js:436 +#: templates/js/translated/table_filters.js:454 msgid "Purchasable" msgstr "" From a02ae8c20de6f7c9a03dfae62f96cfd7e0dddc21 Mon Sep 17 00:00:00 2001 From: Matthias Mair <66015116+matmair@users.noreply.github.com> Date: Wed, 5 Jan 2022 23:41:04 +0100 Subject: [PATCH 42/67] add welcome messages --- .github/workflows/welcome.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/welcome.yml diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml new file mode 100644 index 0000000000..5b0e3a7256 --- /dev/null +++ b/.github/workflows/welcome.yml @@ -0,0 +1,17 @@ +# welcome new contributers +name: Welcome +on: + pull_request: + types: [opened] + issues: + types: [opened] + +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: 'Welcome to InvenTree! Please check the [contributing docs](https://inventree.readthedocs.io/en/latest/contribute/) on how to help.\nIf you experience setup / install issues please read all [install docs]( https://inventree.readthedocs.io/en/latest/start/intro/).' + pr-message: 'This is your first PR, welcome!\nPlease check [Contributing](https://github.com/inventree/InvenTree/blob/master/CONTRIBUTING.md) to make sure your submission fits our general code-style and workflow.\nMake sure to document why this PR is needed and to link connected issues so we can review it faster.' From e0e6dbac944ce777ad4437782eb4792742ee9323 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 6 Jan 2022 12:15:33 +1100 Subject: [PATCH 43/67] Add PLUGIN_FILE to settings.py --- InvenTree/InvenTree/settings.py | 7 +++++++ requirements.txt | 1 + 2 files changed, 8 insertions(+) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index ba2808a8dd..e811028ccc 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -89,6 +89,13 @@ with open(cfg_filename, 'r') as cfg: # We will place any config files in the same directory as the config file config_dir = os.path.dirname(cfg_filename) +# Check if the plugin.txt file (specifying required plugins) is specified +PLUGIN_FILE = os.getenv('INVENTREE_PLUGIN_FILE') + +if not PLUGIN_FILE: + # If not specified, look in the same directory as the configuration file + PLUGIN_FILE = os.path.join(config_dir, 'plugins.txt') + # Default action is to run the system in Debug mode # SECURITY WARNING: don't run with debug turned on in production! DEBUG = _is_true(get_setting( diff --git a/requirements.txt b/requirements.txt index d6405bb7bc..a150ae503a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,6 +33,7 @@ flake8==3.8.3 # PEP checking gunicorn>=20.1.0 # Gunicorn web server importlib_metadata # Backport for importlib.metadata inventree # Install the latest version of the InvenTree API python library +invoke>=1.6.0 # Invoke management tool (must be installed in venv) markdown==3.3.4 # Force particular version of markdown pep8-naming==0.11.1 # PEP naming convention extension pillow==8.3.2 # Image manipulation From 5c2121b1a115dc83050412f3d5306d4e0c11e0af Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 6 Jan 2022 12:25:07 +1100 Subject: [PATCH 44/67] Add invoke target to install plugins from file --- .gitignore | 1 + InvenTree/InvenTree/settings.py | 22 +++++++++++++++------- tasks.py | 23 +++++++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 4bc0bb1389..6532442dc7 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ static_i18n # Local config file config.yaml +plugins.txt # Default data file data.json diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index e811028ccc..894332b189 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -89,13 +89,6 @@ with open(cfg_filename, 'r') as cfg: # We will place any config files in the same directory as the config file config_dir = os.path.dirname(cfg_filename) -# Check if the plugin.txt file (specifying required plugins) is specified -PLUGIN_FILE = os.getenv('INVENTREE_PLUGIN_FILE') - -if not PLUGIN_FILE: - # If not specified, look in the same directory as the configuration file - PLUGIN_FILE = os.path.join(config_dir, 'plugins.txt') - # Default action is to run the system in Debug mode # SECURITY WARNING: don't run with debug turned on in production! DEBUG = _is_true(get_setting( @@ -150,6 +143,21 @@ LOGGING = { # Get a logger instance for this setup file logger = logging.getLogger("inventree") +# Check if the plugin.txt file (specifying required plugins) is specified +PLUGIN_FILE = os.getenv('INVENTREE_PLUGIN_FILE') + +if not PLUGIN_FILE: + # If not specified, look in the same directory as the configuration file + PLUGIN_FILE = os.path.join(config_dir, 'plugins.txt') + +if not os.path.exists(PLUGIN_FILE): + logger.warning("Plugin configuration file does not exist") + logger.info(f"Creating plugin file at '{PLUGIN_FILE}'") + + # If opening the file fails (no write permission, for example), then this will throw an error + with open(PLUGIN_FILE, 'w') as plugin_file: + plugin_file.write("# InvenTree Plugins (uses PIP framework to install)\n\n") + """ Specify a secret key to be used by django. diff --git a/tasks.py b/tasks.py index 4d5d7ff6c8..9eaaa261d9 100644 --- a/tasks.py +++ b/tasks.py @@ -78,10 +78,33 @@ def install(c): Installs required python packages """ + print("Installing required python packages from 'requirements.txt'") + # Install required Python packages with PIP c.run('pip3 install -U -r requirements.txt') +@task +def plugins(c): + """ + Installs all plugins as specified in 'plugins.txt' + """ + + try: + from InvenTree.InvenTree.settings import PLUGIN_FILE + except: + print("Error: Could not import PLUGIN_FILE from settings.py") + return + + if not os.path.exists(PLUGIN_FILE): + # Create an empty plugin + print(f"Plugins file '{PLUGIN_FILE}' does not exist") + + print(f"Installing plugin packages from '{PLUGIN_FILE}'") + + # Install the plugins + c.run(f"pip3 install -U -r '{PLUGIN_FILE}'") + @task def shell(c): """ From 75d5f9d6e606fa04e8f78aabab87e277fd90966b Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 6 Jan 2022 12:37:12 +1100 Subject: [PATCH 45/67] Allow specification of an external plugin directory - Specify directory using INVENTREE_PLUGIN_DIR - Specify installation file using INVENTREE_PLUGIN_FILE --- InvenTree/InvenTree/settings.py | 20 ++++++++++++++++++-- docker/Dockerfile | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 894332b189..8fc0562059 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -923,8 +923,7 @@ MARKDOWNIFY_BLEACH = False # Maintenance mode MAINTENANCE_MODE_RETRY_AFTER = 60 - -# Plugins +# Plugin Directories (local plugins will be loaded from these directories) PLUGIN_DIRS = ['plugin.builtin', ] if not TESTING: @@ -935,6 +934,23 @@ if DEBUG or TESTING: # load samples in debug mode PLUGIN_DIRS.append('plugin.samples') +# Check if an external plugin directory has been specified as an environment variable +# Note: This should be specified as INVENTREE_PLUGIN_DIR +plugin_dir = os.getenv('INVENTREE_PLUGIN_DIR') + +if plugin_dir: + if not os.path.exists(plugin_dir): + logger.info(f"Plugin directory '{plugin_dir}' does not exist") + + try: + os.makedirs(plugin_dir, exist_ok=True) + logger.info(f"Created plugin directory '{plugin_dir}'") + except: + logger.warning(f"Could not create plugins directory '{plugin_dir}'") + + if os.path.exists(plugin_dir): + PLUGIN_DIRS.append(plugin_dir) + # Plugin test settings PLUGIN_TESTING = get_setting('PLUGIN_TESTING', TESTING) # are plugins beeing tested? PLUGIN_TESTING_SETUP = get_setting('PLUGIN_TESTING_SETUP', False) # load plugins from setup hooks in testing? diff --git a/docker/Dockerfile b/docker/Dockerfile index 673792a22f..8fd932ff6f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -30,9 +30,11 @@ ENV INVENTREE_MNG_DIR="${INVENTREE_HOME}/InvenTree" ENV INVENTREE_DATA_DIR="${INVENTREE_HOME}/data" ENV INVENTREE_STATIC_ROOT="${INVENTREE_DATA_DIR}/static" ENV INVENTREE_MEDIA_ROOT="${INVENTREE_DATA_DIR}/media" +ENV INVENTREE_PLUGIN_DIR="${INVENTREE_DATA_DIR}/plugins" ENV INVENTREE_CONFIG_FILE="${INVENTREE_DATA_DIR}/config.yaml" ENV INVENTREE_SECRET_KEY_FILE="${INVENTREE_DATA_DIR}/secret_key.txt" +ENV INVENTREE_PLUGIN_FILE="${INVENTREE_DATA_DIR}}/plugins.txt" # Worker configuration (can be altered by user) ENV INVENTREE_GUNICORN_WORKERS="4" From 6edfe08bde0456ed886b74f5a812512e90438926 Mon Sep 17 00:00:00 2001 From: Lennart Deters Date: Thu, 6 Jan 2022 03:05:29 +0100 Subject: [PATCH 46/67] Dont localize item.quantity in JS Code --- InvenTree/stock/templates/stock/item_base.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index 9113425520..af558ced12 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -3,6 +3,7 @@ {% load inventree_extras %} {% load status_codes %} {% load i18n %} +{% load l10n %} {% block page_title %} {% inventree_title %} | {% trans "Stock Item" %} - {{ item }} @@ -429,7 +430,7 @@ $("#stock-serialize").click(function() { part: {{ item.part.pk }}, reload: true, data: { - quantity: {{ item.quantity }}, + quantity: {{ item.quantity|unlocalize }}, {% if item.location %} destination: {{ item.location.pk }}, {% elif item.part.default_location %} From 836b6275b6819e066471bd68871db2965e44df93 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 6 Jan 2022 13:31:04 +1100 Subject: [PATCH 47/67] Removes custom plugins directory - rely on plugins.txt instead --- InvenTree/InvenTree/settings.py | 17 ----------------- docker/Dockerfile | 6 +++++- tasks.py | 25 ++++++++++++------------- 3 files changed, 17 insertions(+), 31 deletions(-) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 8fc0562059..d738a640b9 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -934,23 +934,6 @@ if DEBUG or TESTING: # load samples in debug mode PLUGIN_DIRS.append('plugin.samples') -# Check if an external plugin directory has been specified as an environment variable -# Note: This should be specified as INVENTREE_PLUGIN_DIR -plugin_dir = os.getenv('INVENTREE_PLUGIN_DIR') - -if plugin_dir: - if not os.path.exists(plugin_dir): - logger.info(f"Plugin directory '{plugin_dir}' does not exist") - - try: - os.makedirs(plugin_dir, exist_ok=True) - logger.info(f"Created plugin directory '{plugin_dir}'") - except: - logger.warning(f"Could not create plugins directory '{plugin_dir}'") - - if os.path.exists(plugin_dir): - PLUGIN_DIRS.append(plugin_dir) - # Plugin test settings PLUGIN_TESTING = get_setting('PLUGIN_TESTING', TESTING) # are plugins beeing tested? PLUGIN_TESTING_SETUP = get_setting('PLUGIN_TESTING_SETUP', False) # load plugins from setup hooks in testing? diff --git a/docker/Dockerfile b/docker/Dockerfile index 8fd932ff6f..55a89210fe 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -34,7 +34,7 @@ ENV INVENTREE_PLUGIN_DIR="${INVENTREE_DATA_DIR}/plugins" ENV INVENTREE_CONFIG_FILE="${INVENTREE_DATA_DIR}/config.yaml" ENV INVENTREE_SECRET_KEY_FILE="${INVENTREE_DATA_DIR}/secret_key.txt" -ENV INVENTREE_PLUGIN_FILE="${INVENTREE_DATA_DIR}}/plugins.txt" +ENV INVENTREE_PLUGIN_FILE="${INVENTREE_DATA_DIR}/plugins.txt" # Worker configuration (can be altered by user) ENV INVENTREE_GUNICORN_WORKERS="4" @@ -131,8 +131,12 @@ ENV INVENTREE_PY_ENV="${INVENTREE_DEV_DIR}/env" # Override default path settings ENV INVENTREE_STATIC_ROOT="${INVENTREE_DEV_DIR}/static" ENV INVENTREE_MEDIA_ROOT="${INVENTREE_DEV_DIR}/media" +ENV INVENTREE_PLUGIN_DIR="${INVENTREE_DEV_DIR}/plugins" + ENV INVENTREE_CONFIG_FILE="${INVENTREE_DEV_DIR}/config.yaml" ENV INVENTREE_SECRET_KEY_FILE="${INVENTREE_DEV_DIR}/secret_key.txt" +ENV INVENTREE_PLUGIN_FILE="${INVENTREE_DEV_DIR}/plugins.txt" + WORKDIR ${INVENTREE_HOME} diff --git a/tasks.py b/tasks.py index 9eaaa261d9..89a579ac9e 100644 --- a/tasks.py +++ b/tasks.py @@ -71,19 +71,6 @@ def manage(c, cmd, pty=False): cmd=cmd ), pty=pty) - -@task -def install(c): - """ - Installs required python packages - """ - - print("Installing required python packages from 'requirements.txt'") - - # Install required Python packages with PIP - c.run('pip3 install -U -r requirements.txt') - - @task def plugins(c): """ @@ -99,12 +86,24 @@ def plugins(c): if not os.path.exists(PLUGIN_FILE): # Create an empty plugin print(f"Plugins file '{PLUGIN_FILE}' does not exist") + return print(f"Installing plugin packages from '{PLUGIN_FILE}'") # Install the plugins c.run(f"pip3 install -U -r '{PLUGIN_FILE}'") +@task(post=[plugins]) +def install(c): + """ + Installs required python packages + """ + + print("Installing required python packages from 'requirements.txt'") + + # Install required Python packages with PIP + c.run('pip3 install -U -r requirements.txt') + @task def shell(c): """ From d8d22e5f38c0451d68b36177a0dda19cbedb30e4 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 6 Jan 2022 14:20:26 +1100 Subject: [PATCH 48/67] Refactor code (so that it actually runs)... - Invoke does not have access to the local virtual environment - Some functions need to be split out from settings.py --- InvenTree/InvenTree/config.py | 90 +++++++++++++++++++++++++++++++++ InvenTree/InvenTree/settings.py | 64 +++-------------------- requirements.txt | 1 - tasks.py | 17 ++----- 4 files changed, 102 insertions(+), 70 deletions(-) create mode 100644 InvenTree/InvenTree/config.py diff --git a/InvenTree/InvenTree/config.py b/InvenTree/InvenTree/config.py new file mode 100644 index 0000000000..35671c1b26 --- /dev/null +++ b/InvenTree/InvenTree/config.py @@ -0,0 +1,90 @@ +""" +Helper functions for loading InvenTree configuration options +""" + +import os +import shutil +import logging + + +logger = logging.getLogger('inventree') + + +def get_base_dir(): + """ Returns the base (top-level) InvenTree directory """ + return os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +def get_config_file(): + """ + Returns the path of the InvenTree configuration file. + + Note: It will be created it if does not already exist! + """ + + base_dir = get_base_dir() + + cfg_filename = os.getenv('INVENTREE_CONFIG_FILE') + + if cfg_filename: + cfg_filename = cfg_filename.strip() + cfg_filename = os.path.abspath(cfg_filename) + else: + # Config file is *not* specified - use the default + cfg_filename = os.path.join(base_dir, 'config.yaml') + + if not os.path.exists(cfg_filename): + print("InvenTree configuration file 'config.yaml' not found - creating default file") + + cfg_template = os.path.join(base_dir, "config_template.yaml") + shutil.copyfile(cfg_template, cfg_filename) + print(f"Created config file {cfg_filename}") + + return cfg_filename + + +def get_plugin_file(): + """ + Returns the path of the InvenTree plugins specification file. + + Note: It will be created if it does not already exist! + """ + # Check if the plugin.txt file (specifying required plugins) is specified + PLUGIN_FILE = os.getenv('INVENTREE_PLUGIN_FILE') + + if not PLUGIN_FILE: + # If not specified, look in the same directory as the configuration file + + config_dir = os.path.dirname(get_config_file()) + + PLUGIN_FILE = os.path.join(config_dir, 'plugins.txt') + + if not os.path.exists(PLUGIN_FILE): + logger.warning("Plugin configuration file does not exist") + logger.info(f"Creating plugin file at '{PLUGIN_FILE}'") + + # If opening the file fails (no write permission, for example), then this will throw an error + with open(PLUGIN_FILE, 'w') as plugin_file: + plugin_file.write("# InvenTree Plugins (uses PIP framework to install)\n\n") + + return PLUGIN_FILE + + +def get_setting(environment_var, backup_val, default_value=None): + """ + Helper function for retrieving a configuration setting value + + - First preference is to look for the environment variable + - Second preference is to look for the value of the settings file + - Third preference is the default value + """ + + val = os.getenv(environment_var) + + if val is not None: + return val + + if backup_val is not None: + return backup_val + + return default_value diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index d738a640b9..89e60a597e 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -17,7 +17,6 @@ import os import random import socket import string -import shutil import sys from datetime import datetime @@ -28,30 +27,12 @@ from django.utils.translation import gettext_lazy as _ from django.contrib.messages import constants as messages import django.conf.locale +from .config import get_base_dir, get_config_file, get_plugin_file, get_setting + def _is_true(x): # Shortcut function to determine if a value "looks" like a boolean - return str(x).lower() in ['1', 'y', 'yes', 't', 'true'] - - -def get_setting(environment_var, backup_val, default_value=None): - """ - Helper function for retrieving a configuration setting value - - - First preference is to look for the environment variable - - Second preference is to look for the value of the settings file - - Third preference is the default value - """ - - val = os.getenv(environment_var) - - if val is not None: - return val - - if backup_val is not None: - return backup_val - - return default_value + return str(x).strip().lower() in ['1', 'y', 'yes', 't', 'true'] # Determine if we are running in "test" mode e.g. "manage.py test" @@ -61,27 +42,9 @@ TESTING = 'test' in sys.argv DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' # Build paths inside the project like this: os.path.join(BASE_DIR, ...) -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +BASE_DIR = get_base_dir() -# Specify where the "config file" is located. -# By default, this is 'config.yaml' - -cfg_filename = os.getenv('INVENTREE_CONFIG_FILE') - -if cfg_filename: - cfg_filename = cfg_filename.strip() - cfg_filename = os.path.abspath(cfg_filename) - -else: - # Config file is *not* specified - use the default - cfg_filename = os.path.join(BASE_DIR, 'config.yaml') - -if not os.path.exists(cfg_filename): - print("InvenTree configuration file 'config.yaml' not found - creating default file") - - cfg_template = os.path.join(BASE_DIR, "config_template.yaml") - shutil.copyfile(cfg_template, cfg_filename) - print(f"Created config file {cfg_filename}") +cfg_filename = get_config_file() with open(cfg_filename, 'r') as cfg: CONFIG = yaml.safe_load(cfg) @@ -89,6 +52,8 @@ with open(cfg_filename, 'r') as cfg: # We will place any config files in the same directory as the config file config_dir = os.path.dirname(cfg_filename) +PLUGIN_FILE = get_plugin_file() + # Default action is to run the system in Debug mode # SECURITY WARNING: don't run with debug turned on in production! DEBUG = _is_true(get_setting( @@ -143,21 +108,6 @@ LOGGING = { # Get a logger instance for this setup file logger = logging.getLogger("inventree") -# Check if the plugin.txt file (specifying required plugins) is specified -PLUGIN_FILE = os.getenv('INVENTREE_PLUGIN_FILE') - -if not PLUGIN_FILE: - # If not specified, look in the same directory as the configuration file - PLUGIN_FILE = os.path.join(config_dir, 'plugins.txt') - -if not os.path.exists(PLUGIN_FILE): - logger.warning("Plugin configuration file does not exist") - logger.info(f"Creating plugin file at '{PLUGIN_FILE}'") - - # If opening the file fails (no write permission, for example), then this will throw an error - with open(PLUGIN_FILE, 'w') as plugin_file: - plugin_file.write("# InvenTree Plugins (uses PIP framework to install)\n\n") - """ Specify a secret key to be used by django. diff --git a/requirements.txt b/requirements.txt index a150ae503a..d6405bb7bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,6 @@ flake8==3.8.3 # PEP checking gunicorn>=20.1.0 # Gunicorn web server importlib_metadata # Backport for importlib.metadata inventree # Install the latest version of the InvenTree API python library -invoke>=1.6.0 # Invoke management tool (must be installed in venv) markdown==3.3.4 # Force particular version of markdown pep8-naming==0.11.1 # PEP naming convention extension pillow==8.3.2 # Image manipulation diff --git a/tasks.py b/tasks.py index 89a579ac9e..34528e2609 100644 --- a/tasks.py +++ b/tasks.py @@ -77,21 +77,14 @@ def plugins(c): Installs all plugins as specified in 'plugins.txt' """ - try: - from InvenTree.InvenTree.settings import PLUGIN_FILE - except: - print("Error: Could not import PLUGIN_FILE from settings.py") - return - - if not os.path.exists(PLUGIN_FILE): - # Create an empty plugin - print(f"Plugins file '{PLUGIN_FILE}' does not exist") - return + from InvenTree.InvenTree.config import get_plugin_file - print(f"Installing plugin packages from '{PLUGIN_FILE}'") + plugin_file = get_plugin_file() + + print(f"Installing plugin packages from '{plugin_file}'") # Install the plugins - c.run(f"pip3 install -U -r '{PLUGIN_FILE}'") + c.run(f"pip3 install -U -r '{plugin_file}'") @task(post=[plugins]) def install(c): From 960784644fdf0a6e48dee810b9a86fd03d160569 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 10:50:29 +1100 Subject: [PATCH 49/67] Adds skeleton for new API endpoint for completing a build order --- InvenTree/build/api.py | 49 ++++++++++++++++++++++++---------- InvenTree/build/serializers.py | 21 ++++++++++++++- InvenTree/build/test_api.py | 4 +-- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py index 4d47cf9076..600f738982 100644 --- a/InvenTree/build/api.py +++ b/InvenTree/build/api.py @@ -18,8 +18,7 @@ from InvenTree.filters import InvenTreeOrderingFilter from InvenTree.status_codes import BuildStatus from .models import Build, BuildItem, BuildOrderAttachment -from .serializers import BuildAttachmentSerializer, BuildCompleteSerializer, BuildSerializer, BuildItemSerializer -from .serializers import BuildAllocationSerializer, BuildUnallocationSerializer +import build.serializers from users.models import Owner @@ -80,7 +79,7 @@ class BuildList(generics.ListCreateAPIView): """ queryset = Build.objects.all() - serializer_class = BuildSerializer + serializer_class = build.serializers.BuildSerializer filterset_class = BuildFilter filter_backends = [ @@ -119,7 +118,7 @@ class BuildList(generics.ListCreateAPIView): queryset = super().get_queryset().select_related('part') - queryset = BuildSerializer.annotate_queryset(queryset) + queryset = build.serializers.BuildSerializer.annotate_queryset(queryset) return queryset @@ -203,7 +202,7 @@ class BuildDetail(generics.RetrieveUpdateAPIView): """ API endpoint for detail view of a Build object """ queryset = Build.objects.all() - serializer_class = BuildSerializer + serializer_class = build.serializers.BuildSerializer class BuildUnallocate(generics.CreateAPIView): @@ -217,7 +216,7 @@ class BuildUnallocate(generics.CreateAPIView): queryset = Build.objects.none() - serializer_class = BuildUnallocationSerializer + serializer_class = build.serializers.BuildUnallocationSerializer def get_serializer_context(self): @@ -233,14 +232,14 @@ class BuildUnallocate(generics.CreateAPIView): return ctx -class BuildComplete(generics.CreateAPIView): +class BuildOutputComplete(generics.CreateAPIView): """ API endpoint for completing build outputs """ queryset = Build.objects.none() - serializer_class = BuildCompleteSerializer + serializer_class = build.serializers.BuildOutputCompleteSerializer def get_serializer_context(self): ctx = super().get_serializer_context() @@ -255,6 +254,27 @@ class BuildComplete(generics.CreateAPIView): return ctx +class BuildFinish(generics.CreateAPIView): + """ + API endpoint for marking a build as finished (completed) + """ + + queryset = Build.objects.none() + + serializer_class = build.serializers.BuildCompleteSerializer + + def get_serializer_context(self): + ctx = super().get_serializer_context() + + ctx['request'] = self.request + + try: + ctx['build'] = Build.objects.get(pk=self.kwargs.get('pk', None)) + except: + pass + + return ctx + class BuildAllocate(generics.CreateAPIView): """ API endpoint to allocate stock items to a build order @@ -269,7 +289,7 @@ class BuildAllocate(generics.CreateAPIView): queryset = Build.objects.none() - serializer_class = BuildAllocationSerializer + serializer_class = build.serializers.BuildAllocationSerializer def get_serializer_context(self): """ @@ -294,7 +314,7 @@ class BuildItemDetail(generics.RetrieveUpdateDestroyAPIView): """ queryset = BuildItem.objects.all() - serializer_class = BuildItemSerializer + serializer_class = build.serializers.BuildItemSerializer class BuildItemList(generics.ListCreateAPIView): @@ -304,7 +324,7 @@ class BuildItemList(generics.ListCreateAPIView): - POST: Create a new BuildItem object """ - serializer_class = BuildItemSerializer + serializer_class = build.serializers.BuildItemSerializer def get_serializer(self, *args, **kwargs): @@ -373,7 +393,7 @@ class BuildAttachmentList(generics.ListCreateAPIView, AttachmentMixin): """ queryset = BuildOrderAttachment.objects.all() - serializer_class = BuildAttachmentSerializer + serializer_class = build.serializers.BuildAttachmentSerializer filter_backends = [ DjangoFilterBackend, @@ -390,7 +410,7 @@ class BuildAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, AttachmentMix """ queryset = BuildOrderAttachment.objects.all() - serializer_class = BuildAttachmentSerializer + serializer_class = build.serializers.BuildAttachmentSerializer build_api_urls = [ @@ -410,7 +430,8 @@ build_api_urls = [ # Build Detail url(r'^(?P\d+)/', include([ url(r'^allocate/', BuildAllocate.as_view(), name='api-build-allocate'), - url(r'^complete/', BuildComplete.as_view(), name='api-build-complete'), + url(r'^complete/', BuildOutputComplete.as_view(), name='api-build-output-complete'), + url(r'^finish/', BuildFinish.as_view(), name='api-build-finish'), url(r'^unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'), url(r'^.*$', BuildDetail.as_view(), name='api-build-detail'), ])), diff --git a/InvenTree/build/serializers.py b/InvenTree/build/serializers.py index 452864e3c4..41b4f84009 100644 --- a/InvenTree/build/serializers.py +++ b/InvenTree/build/serializers.py @@ -165,7 +165,7 @@ class BuildOutputSerializer(serializers.Serializer): ] -class BuildCompleteSerializer(serializers.Serializer): +class BuildOutputCompleteSerializer(serializers.Serializer): """ DRF serializer for completing one or more build outputs """ @@ -240,6 +240,25 @@ class BuildCompleteSerializer(serializers.Serializer): ) +class BuildCompleteSerializer(serializers.Serializer): + """ + DRF serializer for marking a BuildOrder as complete + """ + + accept_unallocated = serializers.BooleanField( + label=_('Accept Unallocated'), + help_text=_('Accept that stock items have not been fully allocated to this build order'), + ) + + accept_incomplete = serializers.BooleanField( + label=_('Accept Incomplete'), + help_text=_('Accept that the required number of build outputs have not been completed'), + ) + + def save(self): + pass + + class BuildUnallocationSerializer(serializers.Serializer): """ DRF serializer for unallocating stock from a BuildOrder diff --git a/InvenTree/build/test_api.py b/InvenTree/build/test_api.py index e2b6448f2f..45662a58d6 100644 --- a/InvenTree/build/test_api.py +++ b/InvenTree/build/test_api.py @@ -49,7 +49,7 @@ class BuildCompleteTest(BuildAPITest): self.build = Build.objects.get(pk=1) - self.url = reverse('api-build-complete', kwargs={'pk': self.build.pk}) + self.url = reverse('api-build-output-complete', kwargs={'pk': self.build.pk}) def test_invalid(self): """ @@ -58,7 +58,7 @@ class BuildCompleteTest(BuildAPITest): # Test with an invalid build ID self.post( - reverse('api-build-complete', kwargs={'pk': 99999}), + reverse('api-build-output-complete', kwargs={'pk': 99999}), {}, expected_code=400 ) From ceed90217b66d1043679a06af80cef6d0106d193 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 7 Jan 2022 01:03:05 +0100 Subject: [PATCH 50/67] restructuring --- InvenTree/plugin/serializers.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/InvenTree/plugin/serializers.py b/InvenTree/plugin/serializers.py index e25e253498..f59348601f 100644 --- a/InvenTree/plugin/serializers.py +++ b/InvenTree/plugin/serializers.py @@ -83,26 +83,28 @@ class PluginConfigInstallSerializer(serializers.Serializer): url = data.get('url', '') # build up the command - command = 'python -m pip install'.split() + install_name = [] if url: # use custom registration / VCS if True in [identifier in url for identifier in ['git+https', 'hg+https', 'svn+svn', ]]: # using a VCS provider if packagename: - command.append(f'{packagename}@{url}') + install_name.append(f'{packagename}@{url}') else: - command.append(url) + install_name.append(url) else: # using a custom package repositories - command.append('-i') - command.append(url) - command.append(packagename) + install_name.append('-i') + install_name.append(url) + install_name.append(packagename) elif packagename: # use pypi - command.append(packagename) + install_name.append(packagename) + command = 'python -m pip install'.split() + command.extend(install_name) ret = {'command': ' '.join(command)} # execute pypi try: From edc648d61932bd097597f6eff214ab21c0bf7618 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 7 Jan 2022 01:09:44 +0100 Subject: [PATCH 51/67] write installd plugins to plugins.txt --- InvenTree/plugin/serializers.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/InvenTree/plugin/serializers.py b/InvenTree/plugin/serializers.py index f59348601f..83c3136620 100644 --- a/InvenTree/plugin/serializers.py +++ b/InvenTree/plugin/serializers.py @@ -11,10 +11,12 @@ import subprocess from django.core.exceptions import ValidationError from django.conf import settings from django.utils.translation import ugettext_lazy as _ +from django.utils import timezone from rest_framework import serializers from plugin.models import PluginConfig +from InvenTree.config import get_plugin_file class PluginConfigSerializer(serializers.ModelSerializer): @@ -106,16 +108,20 @@ class PluginConfigInstallSerializer(serializers.Serializer): command = 'python -m pip install'.split() command.extend(install_name) ret = {'command': ' '.join(command)} + success = False # execute pypi try: result = subprocess.check_output(command, cwd=os.path.dirname(settings.BASE_DIR)) ret['result'] = str(result, 'utf-8') ret['success'] = True + success = True except subprocess.CalledProcessError as error: ret['result'] = str(error.output, 'utf-8') ret['error'] = True - # register plugins - # TODO + # save plugin to plugin_file if installed successfull + if success: + with open(get_plugin_file(), "a") as plugin_file: + plugin_file.write(f'{" ".join(install_name)} # Installed {timezone.now()} by {str(self.context["request"].user)}\n') return ret From 0974ebb5cd0b3a96eedbaac1bb6047df8885dec5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 7 Jan 2022 01:10:44 +0100 Subject: [PATCH 52/67] shield plugin package load --- InvenTree/plugin/registry.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index d858d6c7f0..1a05a2ed34 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -150,9 +150,12 @@ class Plugins: if (not settings.PLUGIN_TESTING) or (settings.PLUGIN_TESTING and settings.PLUGIN_TESTING_SETUP): # Collect plugins from setup entry points for entry in metadata.entry_points().get('inventree_plugins', []): - plugin = entry.load() - plugin.is_package = True - self.plugin_modules.append(plugin) + try: + plugin = entry.load() + plugin.is_package = True + self.plugin_modules.append(plugin) + except Exception as error: + get_plugin_error(error, do_log=True, log_name='discovery') # Log collected plugins logger.info(f'Collected {len(self.plugin_modules)} plugins!') From 12b3a5c9ccc5f3f1b33cffc513d39c685ac5c2e8 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 11:33:27 +1100 Subject: [PATCH 53/67] Validate and save the new serailizer --- InvenTree/build/api.py | 1 + InvenTree/build/models.py | 2 +- InvenTree/build/serializers.py | 24 ++++++++- .../build/templates/build/build_base.html | 7 +++ InvenTree/templates/js/translated/build.js | 52 +++++++++++++++++++ 5 files changed, 84 insertions(+), 2 deletions(-) diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py index 600f738982..733799f890 100644 --- a/InvenTree/build/api.py +++ b/InvenTree/build/api.py @@ -275,6 +275,7 @@ class BuildFinish(generics.CreateAPIView): return ctx + class BuildAllocate(generics.CreateAPIView): """ API endpoint to allocate stock items to a build order diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 392c773e6b..f03cb30c74 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -555,7 +555,7 @@ class Build(MPTTModel, ReferenceIndexingMixin): if self.incomplete_count > 0: return False - if self.completed < self.quantity: + if self.remaining > 0: return False if not self.areUntrackedPartsFullyAllocated(): diff --git a/InvenTree/build/serializers.py b/InvenTree/build/serializers.py index 41b4f84009..55f89c1844 100644 --- a/InvenTree/build/serializers.py +++ b/InvenTree/build/serializers.py @@ -250,13 +250,35 @@ class BuildCompleteSerializer(serializers.Serializer): help_text=_('Accept that stock items have not been fully allocated to this build order'), ) + def validate_accept_unallocated(self, value): + + build = self.context['build'] + + if not build.areUntrackedPartsFullyAllocated() and not value: + raise ValidationError(_('Required stock has not been fully allocated')) + + return value + accept_incomplete = serializers.BooleanField( label=_('Accept Incomplete'), help_text=_('Accept that the required number of build outputs have not been completed'), ) + def validate_accept_incomplete(self, value): + + build = self.context['build'] + + if build.remaining > 0 and not value: + raise ValidationError(_('Required build quantity has not been completed')) + + return value + def save(self): - pass + + request = self.context['request'] + build = self.context['build'] + + build.complete_build(request.user) class BuildUnallocationSerializer(serializers.Serializer): diff --git a/InvenTree/build/templates/build/build_base.html b/InvenTree/build/templates/build/build_base.html index 48ef98b2b1..74cd1a9d96 100644 --- a/InvenTree/build/templates/build/build_base.html +++ b/InvenTree/build/templates/build/build_base.html @@ -224,6 +224,13 @@ src="{% static 'img/blank_image.png' %}" '{% trans "Build Order cannot be completed as incomplete build outputs remain" %}' ); {% else %} + + completeBuildOrder({{ build.pk }}, { + allocated: {% if build.areUntrackedPartsFullyAllocated %}true{% else %}false{% endif %}, + completed: {% if build.remaining == 0 %}true{% else %}false{% endif %}, + }); + + return; launchModalForm( "{% url 'build-complete' build.id %}", { diff --git a/InvenTree/templates/js/translated/build.js b/InvenTree/templates/js/translated/build.js index 0deec4f859..ebb37fa61c 100644 --- a/InvenTree/templates/js/translated/build.js +++ b/InvenTree/templates/js/translated/build.js @@ -20,6 +20,7 @@ /* exported allocateStockToBuild, + completeBuildOrder, editBuildOrder, loadAllocationTable, loadBuildOrderAllocationTable, @@ -120,6 +121,57 @@ function newBuildOrder(options={}) { } +/* Construct a form to "complete" (finish) a build order */ +function completeBuildOrder(build_id, options={}) { + + var url = `/api/build/${build_id}/finish/`; + + var fields = { + accept_unallocated: {}, + accept_incomplete: {}, + }; + + var html = ''; + + if (options.can_complete) { + + } else { + html += ` +
+ {% trans "Build Order is incomplete" %} +
+ `; + + if (!options.allocated) { + html += `
{% trans "Required stock has not been fully allocated" %}
`; + } + + if (!options.completed) { + html += `
{% trans "Required build quantity has not been completed" %}
`; + } + } + + // Hide particular fields if they are not required + + if (options.allocated) { + delete fields.accept_unallocated; + } + + if (options.completed) { + delete fields.accept_incomplete; + } + + constructForm(url, { + fields: fields, + reload: true, + confirm: true, + method: 'POST', + title: '{% trans "Complete Build Order" %}', + preFormContent: html, + }); +} + + /* * Construct a set of output buttons for a particular build output */ From 2bb1c4ea7767fa567579c44cc2585a6534d6e47e Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 11:34:33 +1100 Subject: [PATCH 54/67] Remove old forms / outdated code --- InvenTree/build/forms.py | 18 ---------- .../build/templates/build/build_base.html | 9 ----- InvenTree/build/templates/build/complete.html | 26 --------------- InvenTree/build/urls.py | 1 - InvenTree/build/views.py | 33 ------------------- 5 files changed, 87 deletions(-) delete mode 100644 InvenTree/build/templates/build/complete.html diff --git a/InvenTree/build/forms.py b/InvenTree/build/forms.py index 19bf3566dc..43899ba819 100644 --- a/InvenTree/build/forms.py +++ b/InvenTree/build/forms.py @@ -83,24 +83,6 @@ class BuildOutputDeleteForm(HelperForm): ] -class CompleteBuildForm(HelperForm): - """ - Form for marking a build as complete - """ - - confirm = forms.BooleanField( - required=True, - label=_('Confirm'), - help_text=_('Mark build as complete'), - ) - - class Meta: - model = Build - fields = [ - 'confirm', - ] - - class CancelBuildForm(HelperForm): """ Form for cancelling a build """ diff --git a/InvenTree/build/templates/build/build_base.html b/InvenTree/build/templates/build/build_base.html index 74cd1a9d96..312accb18f 100644 --- a/InvenTree/build/templates/build/build_base.html +++ b/InvenTree/build/templates/build/build_base.html @@ -229,15 +229,6 @@ src="{% static 'img/blank_image.png' %}" allocated: {% if build.areUntrackedPartsFullyAllocated %}true{% else %}false{% endif %}, completed: {% if build.remaining == 0 %}true{% else %}false{% endif %}, }); - - return; - launchModalForm( - "{% url 'build-complete' build.id %}", - { - reload: true, - submit_text: '{% trans "Complete Build" %}', - } - ); {% endif %} }); diff --git a/InvenTree/build/templates/build/complete.html b/InvenTree/build/templates/build/complete.html deleted file mode 100644 index eeedc027dd..0000000000 --- a/InvenTree/build/templates/build/complete.html +++ /dev/null @@ -1,26 +0,0 @@ -{% extends "modal_form.html" %} -{% load i18n %} - -{% block pre_form_content %} - -{% if build.can_complete %} -
- {% trans "Build Order is complete" %} -
-{% else %} -
- {% trans "Build Order is incomplete" %}
-
    - {% if build.incomplete_count > 0 %} -
  • {% trans "Incompleted build outputs remain" %}
  • - {% endif %} - {% if build.completed < build.quantity %} -
  • {% trans "Required build quantity has not been completed" %}
  • - {% endif %} - {% if not build.areUntrackedPartsFullyAllocated %} -
  • {% trans "Required stock has not been fully allocated" %}
  • - {% endif %} -
-
-{% endif %} -{% endblock %} \ No newline at end of file diff --git a/InvenTree/build/urls.py b/InvenTree/build/urls.py index 8ea339ae26..fecece232e 100644 --- a/InvenTree/build/urls.py +++ b/InvenTree/build/urls.py @@ -11,7 +11,6 @@ build_detail_urls = [ url(r'^delete/', views.BuildDelete.as_view(), name='build-delete'), url(r'^create-output/', views.BuildOutputCreate.as_view(), name='build-output-create'), url(r'^delete-output/', views.BuildOutputDelete.as_view(), name='build-output-delete'), - url(r'^complete/', views.BuildComplete.as_view(), name='build-complete'), url(r'^.*$', views.BuildDetail.as_view(), name='build-detail'), ] diff --git a/InvenTree/build/views.py b/InvenTree/build/views.py index 1d28cb8d50..1a933af835 100644 --- a/InvenTree/build/views.py +++ b/InvenTree/build/views.py @@ -246,39 +246,6 @@ class BuildOutputDelete(AjaxUpdateView): } -class BuildComplete(AjaxUpdateView): - """ - View to mark the build as complete. - - Requirements: - - There can be no outstanding build outputs - - The "completed" value must meet or exceed the "quantity" value - """ - - model = Build - form_class = forms.CompleteBuildForm - - ajax_form_title = _('Complete Build Order') - ajax_template_name = 'build/complete.html' - - def validate(self, build, form, **kwargs): - - if build.incomplete_count > 0: - form.add_error(None, _('Build order cannot be completed - incomplete outputs remain')) - - def save(self, build, form, **kwargs): - """ - Perform the build completion step - """ - - build.complete_build(self.request.user) - - def get_data(self): - return { - 'success': _('Completed build order') - } - - class BuildDetail(InvenTreeRoleMixin, DetailView): """ Detail view of a single Build object. From aaf35e6c76e2d413ca9c642a561b4058cc218926 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 13:14:47 +1100 Subject: [PATCH 55/67] Customize text if totalRows not known --- InvenTree/templates/js/translated/tables.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/InvenTree/templates/js/translated/tables.js b/InvenTree/templates/js/translated/tables.js index e4b189a074..4c9bec0476 100644 --- a/InvenTree/templates/js/translated/tables.js +++ b/InvenTree/templates/js/translated/tables.js @@ -371,7 +371,12 @@ function customGroupSorter(sortName, sortOrder, sortData) { return `${pageNumber} {% trans "rows per page" %}`; }, formatShowingRows: function(pageFrom, pageTo, totalRows) { - return `{% trans "Showing" %} ${pageFrom} {% trans "to" %} ${pageTo} {% trans "of" %} ${totalRows} {% trans "rows" %}`; + + if (totalRows === undefined || totalRows === NaN) { + return '{% trans "Showing all rows" %}'; + } else { + return `{% trans "Showing" %} ${pageFrom} {% trans "to" %} ${pageTo} {% trans "of" %} ${totalRows} {% trans "rows" %}`; + } }, formatSearch: function() { return '{% trans "Search" %}'; From 8103b842689c7430dcde809a3ecdd238d3ea4f6e Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 14:23:32 +1100 Subject: [PATCH 56/67] Move mixins.py into main plugin directory --- InvenTree/plugin/builtin/integration/__init__.py | 0 InvenTree/plugin/{builtin/integration => }/mixins.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 InvenTree/plugin/builtin/integration/__init__.py rename InvenTree/plugin/{builtin/integration => }/mixins.py (100%) diff --git a/InvenTree/plugin/builtin/integration/__init__.py b/InvenTree/plugin/builtin/integration/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/mixins.py similarity index 100% rename from InvenTree/plugin/builtin/integration/mixins.py rename to InvenTree/plugin/mixins.py From 0773545615654930c66a01decec64aa527c6a809 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 14:54:04 +1100 Subject: [PATCH 57/67] Add "ScheduleMixin" for scheduling tasks --- InvenTree/plugin/mixins.py | 49 ++++++++++++++++++- .../samples/integration/scheduled_tasks.py | 16 ++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 InvenTree/plugin/samples/integration/scheduled_tasks.py diff --git a/InvenTree/plugin/mixins.py b/InvenTree/plugin/mixins.py index c5d2411e4d..580afdc888 100644 --- a/InvenTree/plugin/mixins.py +++ b/InvenTree/plugin/mixins.py @@ -53,6 +53,51 @@ class SettingsMixin: PluginSetting.set_setting(key, value, user, plugin=plugin) +class ScheduleMixin: + """ + Mixin that provides support for scheduled tasks. + + Implementing classes must provide a dict object called SCHEDULED_TASKS, + which provides information on the tasks to be scheduled. + + SCHEDULED_TASKS = { + # Name of the task (will be prepended with the plugin name) + 'test_server': { + 'func': 'myplugin.tasks.test_server', # Python function to call (no arguments!) + 'schedule': "I", # Schedule type (see django_q.Schedule) + 'minutes': 30, # Number of minutes (only if schedule type = Minutes) + 'repeats': 5, # Number of repeats (leave blank for 'forever') + } + } + """ + + SCHEDULED_TASKS = {} + + class MixinMeta: + MIXIN_NAME = 'Schedule' + + def __init__(self): + super().__init__() + self.add_mixin('schedule', 'has_scheduled_tasks', __class__) + self.scheduled_tasks = getattr(self, 'SCHEDULED_TASKS', {}) + + self.validate_scheduled_tasks() + + @property + def has_scheduled_tasks(self): + return bool(self.scheduled_tasks) + + def validate_scheduled_tasks(self): + """ + Check that the provided scheduled tasks are valid + """ + + if not self.has_scheduled_tasks(): + raise ValueError(f"SCHEDULED_TASKS not defined for plugin '{__class__}'") + + for key, task in self.scheduled_tasks.items(): + print(key, task) + class UrlsMixin: """ Mixin that enables custom URLs for the plugin @@ -112,7 +157,9 @@ class NavigationMixin: NAVIGATION_TAB_ICON = "fas fa-question" class MixinMeta: - """meta options for this mixin""" + """ + meta options for this mixin + """ MIXIN_NAME = 'Navigation Links' def __init__(self): diff --git a/InvenTree/plugin/samples/integration/scheduled_tasks.py b/InvenTree/plugin/samples/integration/scheduled_tasks.py new file mode 100644 index 0000000000..14d8399f03 --- /dev/null +++ b/InvenTree/plugin/samples/integration/scheduled_tasks.py @@ -0,0 +1,16 @@ +""" +Sample plugin which supports task scheduling +""" + +from plugin import IntegrationPluginBase +from plugin.mixins import ScheduleMixin + + +class ScheduledTaskPlugin(ScheduleMixin, IntegrationPluginBase): + """ + A sample plugin which provides support for scheduled tasks + """ + + PLUGIN_NAME = "ScheduledTasksPlugin" + PLUGIN_SLUG = "schedule" + PLUGIN_TITLE = "A plugin which provides scheduled task support" From 326b897d14f4bd2d6ddacd2d1c2105942283cc7b Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 14:54:12 +1100 Subject: [PATCH 58/67] Revert "Move mixins.py into main plugin directory" This reverts commit 8103b842689c7430dcde809a3ecdd238d3ea4f6e. --- InvenTree/plugin/builtin/integration/__init__.py | 0 InvenTree/plugin/{ => builtin/integration}/mixins.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 InvenTree/plugin/builtin/integration/__init__.py rename InvenTree/plugin/{ => builtin/integration}/mixins.py (100%) diff --git a/InvenTree/plugin/builtin/integration/__init__.py b/InvenTree/plugin/builtin/integration/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/InvenTree/plugin/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py similarity index 100% rename from InvenTree/plugin/mixins.py rename to InvenTree/plugin/builtin/integration/mixins.py From 794a9e75e8ed11ce544eacb75fdd64453edc81b4 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 15:37:43 +1100 Subject: [PATCH 59/67] Add validation for scheduled tasks defined by a plugin --- InvenTree/common/models.py | 7 ++++++ .../plugin/builtin/integration/mixins.py | 24 ++++++++++++++++--- InvenTree/plugin/integration.py | 4 ++++ InvenTree/plugin/mixins/__init__.py | 8 +++++-- .../samples/integration/scheduled_tasks.py | 23 +++++++++++++++++- .../templates/InvenTree/settings/plugin.html | 3 ++- 6 files changed, 62 insertions(+), 7 deletions(-) diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 16d0be035a..15c12f1a36 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -978,6 +978,13 @@ class InvenTreeSetting(BaseInvenTreeSetting): 'validator': bool, 'requires_restart': True, }, + 'ENABLE_PLUGINS_SCHEDULE': { + 'name': _('Enable schedule integration'), + 'description': _('Enable plugins to run scheduled tasks'), + 'default': False, + 'validator': bool, + 'requires_restart': True, + } } class Meta: diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 580afdc888..9be1598fe7 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -69,8 +69,12 @@ class ScheduleMixin: 'repeats': 5, # Number of repeats (leave blank for 'forever') } } + + Note: 'schedule' parameter must be one of ['I', 'H', 'D', 'W', 'M', 'Q', 'Y'] """ + ALLOWABLE_SCHEDULE_TYPES = ['I', 'H', 'D', 'W', 'M', 'Q', 'Y'] + SCHEDULED_TASKS = {} class MixinMeta: @@ -92,11 +96,25 @@ class ScheduleMixin: Check that the provided scheduled tasks are valid """ - if not self.has_scheduled_tasks(): - raise ValueError(f"SCHEDULED_TASKS not defined for plugin '{__class__}'") + if not self.has_scheduled_tasks: + raise ValueError(f"SCHEDULED_TASKS not defined") for key, task in self.scheduled_tasks.items(): - print(key, task) + + if 'func' not in task: + raise ValueError(f"Task '{key}' is missing 'func' parameter") + + if 'schedule' not in task: + raise ValueError(f"Task '{key}' is missing 'schedule' parameter") + + schedule = task['schedule'].upper().strip() + + if schedule not in self.ALLOWABLE_SCHEDULE_TYPES: + raise ValueError(f"Task '{key}': Schedule '{schedule}' is not a valid option") + + # If 'minutes' is selected, it must be provided! + if schedule == 'I' and 'minutes' not in task: + raise ValueError(f"Task '{key}' is missing 'minutes' parameter") class UrlsMixin: """ diff --git a/InvenTree/plugin/integration.py b/InvenTree/plugin/integration.py index 73223593a5..b7ae7d1fc4 100644 --- a/InvenTree/plugin/integration.py +++ b/InvenTree/plugin/integration.py @@ -94,6 +94,10 @@ class IntegrationPluginBase(MixinBase, plugin.InvenTreePlugin): def slug(self): return self.plugin_slug() + @property + def name(self): + return self.plugin_name() + @property def human_name(self): """human readable name for labels etc.""" diff --git a/InvenTree/plugin/mixins/__init__.py b/InvenTree/plugin/mixins/__init__.py index ceb5de5885..e9c910bb9e 100644 --- a/InvenTree/plugin/mixins/__init__.py +++ b/InvenTree/plugin/mixins/__init__.py @@ -1,9 +1,13 @@ -"""utility class to enable simpler imports""" -from ..builtin.integration.mixins import AppMixin, SettingsMixin, UrlsMixin, NavigationMixin +""" +Utility class to enable simpler imports +""" + +from ..builtin.integration.mixins import AppMixin, SettingsMixin, ScheduleMixin, UrlsMixin, NavigationMixin __all__ = [ 'AppMixin', 'NavigationMixin', + 'ScheduleMixin', 'SettingsMixin', 'UrlsMixin', ] diff --git a/InvenTree/plugin/samples/integration/scheduled_tasks.py b/InvenTree/plugin/samples/integration/scheduled_tasks.py index 14d8399f03..04672ebed3 100644 --- a/InvenTree/plugin/samples/integration/scheduled_tasks.py +++ b/InvenTree/plugin/samples/integration/scheduled_tasks.py @@ -6,6 +6,15 @@ from plugin import IntegrationPluginBase from plugin.mixins import ScheduleMixin +# Define some simple tasks to perform +def print_hello(): + print("Hello") + + +def print_world(): + print("World") + + class ScheduledTaskPlugin(ScheduleMixin, IntegrationPluginBase): """ A sample plugin which provides support for scheduled tasks @@ -13,4 +22,16 @@ class ScheduledTaskPlugin(ScheduleMixin, IntegrationPluginBase): PLUGIN_NAME = "ScheduledTasksPlugin" PLUGIN_SLUG = "schedule" - PLUGIN_TITLE = "A plugin which provides scheduled task support" + PLUGIN_TITLE = "Scheduled Tasks" + + SCHEDULED_TASKS = { + 'hello': { + 'func': 'plugin.builtin.integration.mixins.ScheduleMixin.print_hello', + 'schedule': 'I', + 'minutes': 5, + }, + 'world': { + 'func': 'plugin.builtin.integration.mixins.ScheduleMixin.print_world', + 'schedule': 'H', + } + } \ No newline at end of file diff --git a/InvenTree/templates/InvenTree/settings/plugin.html b/InvenTree/templates/InvenTree/settings/plugin.html index 960ec852b8..858d0f3ab9 100644 --- a/InvenTree/templates/InvenTree/settings/plugin.html +++ b/InvenTree/templates/InvenTree/settings/plugin.html @@ -19,6 +19,7 @@
+ {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_SCHEDULE" icon="fa-calendar-alt" %} {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_URL" icon="fa-link" %} {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_NAVIGATION" icon="fa-sitemap" %} {% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_APP" icon="fa-rocket" %} @@ -28,7 +29,7 @@
-

{% trans "Plugin list" %}

+

{% trans "Plugins" %}

{% include "spacer.html" %}
{% url 'admin:plugin_pluginconfig_changelist' as url %} From 0ab9b2dbc76889d1fb53021b3798cc65a4888377 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 15:41:31 +1100 Subject: [PATCH 60/67] Bug fix - always allow plugins to register settings --- InvenTree/plugin/registry.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index fe28acfadb..f01f452607 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -272,14 +272,15 @@ class PluginsRegistry: self.deactivate_integration_settings() def activate_integration_settings(self, plugins): - from common.models import InvenTreeSetting - if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_GLOBALSETTING'): - logger.info('Registering IntegrationPlugin global settings') - for slug, plugin in plugins: - if plugin.mixin_enabled('settings'): - plugin_setting = plugin.settings - self.mixins_settings[slug] = plugin_setting + logger.info('Registering IntegrationPlugin global settings') + + self.mixins_settings = {} + + for slug, plugin in plugins: + if plugin.mixin_enabled('settings'): + plugin_setting = plugin.settings + self.mixins_settings[slug] = plugin_setting def deactivate_integration_settings(self): @@ -290,7 +291,7 @@ class PluginsRegistry: plugin_settings.update(plugin_setting) # clear cache - self.mixins_Fsettings = {} + self.mixins_settings = {} def activate_integration_app(self, plugins, force_reload=False): """activate AppMixin plugins - add custom apps and reload From ff598a22ffdf8bbd8a57f0a7cc18d9b1626a7743 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 16:20:16 +1100 Subject: [PATCH 61/67] bug fix : correct setting name when changing a 'requires restart' setting --- InvenTree/common/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 15c12f1a36..dee0eb2e8b 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -571,7 +571,7 @@ class InvenTreeSetting(BaseInvenTreeSetting): super().save() if self.requires_restart(): - InvenTreeSetting.set_setting('SERVER_REQUIRES_RESTART', True, None) + InvenTreeSetting.set_setting('SERVER_RESTART_REQUIRED', True, None) """ Dict of all global settings values: From 3eb1fa32f9b808c5861eb300e78bbcdee4b3c537 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 16:51:00 +1100 Subject: [PATCH 62/67] Scheduled tasks get registered for the background worker --- .../plugin/builtin/integration/mixins.py | 57 +++++++++++++++++++ InvenTree/plugin/registry.py | 54 +++++++++++++++++- .../{scheduled_tasks.py => scheduled_task.py} | 4 +- 3 files changed, 110 insertions(+), 5 deletions(-) rename InvenTree/plugin/samples/integration/{scheduled_tasks.py => scheduled_task.py} (79%) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 9be1598fe7..ca3af01e53 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -2,6 +2,8 @@ Plugin mixin classes """ +import logging + from django.conf.urls import url, include from django.db.utils import OperationalError, ProgrammingError @@ -9,6 +11,9 @@ from plugin.models import PluginConfig, PluginSetting from plugin.urls import PLUGIN_BASE +logger = logging.getLogger('inventree') + + class SettingsMixin: """ Mixin that enables global settings for the plugin @@ -116,6 +121,58 @@ class ScheduleMixin: if schedule == 'I' and 'minutes' not in task: raise ValueError(f"Task '{key}' is missing 'minutes' parameter") + def get_task_name(self, key): + # Generate a 'unique' task name + slug = self.plugin_slug() + return f"plugin.{slug}.{key}" + + def get_task_names(self): + # Returns a list of all task names associated with this plugin instance + return [self.get_task_name(key) for key in self.scheduled_tasks.keys()] + + def register_tasks(self): + """ + Register the tasks with the database + """ + + from django_q.models import Schedule + + for key, task in self.scheduled_tasks.items(): + + task_name = self.get_task_name(key) + + # If a matching scheduled task does not exist, create it! + if not Schedule.objects.filter(name=task_name).exists(): + + logger.info(f"Adding scheduled task '{task_name}'") + + Schedule.objects.create( + name=task_name, + func=task['func'], + schedule_type=task['schedule'], + minutes=task.get('minutes', None), + repeats=task.get('repeats', -1), + ) + + + def unregister_tasks(self): + """ + Deregister the tasks with the database + """ + + from django_q.models import Schedule + + for key, task in self.scheduled_tasks.items(): + + task_name = self.get_task_name(key) + + try: + scheduled_task = Schedule.objects.get(name=task_name) + scheduled_task.delete() + except Schedule.DoesNotExist: + pass + + class UrlsMixin: """ Mixin that enables custom URLs for the plugin diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index f01f452607..86e31608e7 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -262,18 +262,21 @@ class PluginsRegistry: logger.info(f'Found {len(plugins)} active plugins') self.activate_integration_settings(plugins) + self.activate_integration_schedule(plugins) self.activate_integration_app(plugins, force_reload=force_reload) def _deactivate_plugins(self): """ Run integration deactivation functions for all plugins """ + self.deactivate_integration_app() + self.deactivate_integration_schedule() self.deactivate_integration_settings() def activate_integration_settings(self, plugins): - logger.info('Registering IntegrationPlugin global settings') + logger.info('Activating plugin settings') self.mixins_settings = {} @@ -293,8 +296,50 @@ class PluginsRegistry: # clear cache self.mixins_settings = {} + def activate_integration_schedule(self, plugins): + + logger.info('Activating plugin tasks') + + from common.models import InvenTreeSetting + from django_q.models import Schedule + + # List of tasks we have activated + task_keys = [] + + if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_SCHEDULE'): + + for slug, plugin in plugins: + + if plugin.mixin_enabled('schedule'): + config = plugin.plugin_config() + + # Only active tasks for plugins which are enabled + if config and config.active: + plugin.register_tasks() + task_keys += plugin.get_task_names() + + logger.info(f"Activated {len(task_keys)} scheduled tasks") + + # Remove any scheduled tasks which do not match + # This stops 'old' plugin tasks from accumulating + scheduled_plugin_tasks = Schedule.objects.filter(name__istartswith="plugin.") + + deleted_count = 0 + + for task in scheduled_plugin_tasks: + if task.name not in task_keys: + task.delete() + deleted_count += 1 + + if deleted_count > 0: + logger.info(f"Removed {deleted_count} old scheduled tasks") + + def deactivate_integration_schedule(self): + pass + def activate_integration_app(self, plugins, force_reload=False): - """activate AppMixin plugins - add custom apps and reload + """ + Activate AppMixin plugins - add custom apps and reload :param plugins: list of IntegrationPlugins that should be installed :type plugins: dict @@ -378,7 +423,10 @@ class PluginsRegistry: return plugin_path def deactivate_integration_app(self): - """deactivate integration app - some magic required""" + """ + Deactivate integration app - some magic required + """ + # unregister models from admin for plugin_path in self.installed_apps: models = [] # the modelrefs need to be collected as poping an item in a iter is not welcomed diff --git a/InvenTree/plugin/samples/integration/scheduled_tasks.py b/InvenTree/plugin/samples/integration/scheduled_task.py similarity index 79% rename from InvenTree/plugin/samples/integration/scheduled_tasks.py rename to InvenTree/plugin/samples/integration/scheduled_task.py index 04672ebed3..fb84c03503 100644 --- a/InvenTree/plugin/samples/integration/scheduled_tasks.py +++ b/InvenTree/plugin/samples/integration/scheduled_task.py @@ -26,12 +26,12 @@ class ScheduledTaskPlugin(ScheduleMixin, IntegrationPluginBase): SCHEDULED_TASKS = { 'hello': { - 'func': 'plugin.builtin.integration.mixins.ScheduleMixin.print_hello', + 'func': 'plugin.samples.integration.scheduled_task.print_hello', 'schedule': 'I', 'minutes': 5, }, 'world': { - 'func': 'plugin.builtin.integration.mixins.ScheduleMixin.print_world', + 'func': 'plugin.samples.integration.scheduled_task.print_hello', 'schedule': 'H', } } \ No newline at end of file From 36feef65584c73f57969c8da7cde014e0e443251 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 16:53:51 +1100 Subject: [PATCH 63/67] Remove log message if not relevent --- InvenTree/plugin/registry.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index 86e31608e7..7e08ce3efb 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -318,7 +318,8 @@ class PluginsRegistry: plugin.register_tasks() task_keys += plugin.get_task_names() - logger.info(f"Activated {len(task_keys)} scheduled tasks") + if len(task_keys) > 0: + logger.info(f"Activated {len(task_keys)} scheduled tasks") # Remove any scheduled tasks which do not match # This stops 'old' plugin tasks from accumulating From c04e07c1fa391726d318677f8a390985b5f0aa9f Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 17:04:33 +1100 Subject: [PATCH 64/67] Add a task which fails on purpose --- InvenTree/plugin/builtin/integration/mixins.py | 9 ++++----- InvenTree/plugin/registry.py | 6 +++--- .../plugin/samples/integration/scheduled_task.py | 12 ++++++++++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index ca3af01e53..54f739d04d 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -102,16 +102,16 @@ class ScheduleMixin: """ if not self.has_scheduled_tasks: - raise ValueError(f"SCHEDULED_TASKS not defined") + raise ValueError("SCHEDULED_TASKS not defined") for key, task in self.scheduled_tasks.items(): - + if 'func' not in task: raise ValueError(f"Task '{key}' is missing 'func' parameter") - + if 'schedule' not in task: raise ValueError(f"Task '{key}' is missing 'schedule' parameter") - + schedule = task['schedule'].upper().strip() if schedule not in self.ALLOWABLE_SCHEDULE_TYPES: @@ -153,7 +153,6 @@ class ScheduleMixin: minutes=task.get('minutes', None), repeats=task.get('repeats', -1), ) - def unregister_tasks(self): """ diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index 7e08ce3efb..12dfc9d43e 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -299,7 +299,7 @@ class PluginsRegistry: def activate_integration_schedule(self, plugins): logger.info('Activating plugin tasks') - + from common.models import InvenTreeSetting from django_q.models import Schedule @@ -307,7 +307,7 @@ class PluginsRegistry: task_keys = [] if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_SCHEDULE'): - + for slug, plugin in plugins: if plugin.mixin_enabled('schedule'): @@ -427,7 +427,7 @@ class PluginsRegistry: """ Deactivate integration app - some magic required """ - + # unregister models from admin for plugin_path in self.installed_apps: models = [] # the modelrefs need to be collected as poping an item in a iter is not welcomed diff --git a/InvenTree/plugin/samples/integration/scheduled_task.py b/InvenTree/plugin/samples/integration/scheduled_task.py index fb84c03503..5a8f866cd7 100644 --- a/InvenTree/plugin/samples/integration/scheduled_task.py +++ b/InvenTree/plugin/samples/integration/scheduled_task.py @@ -15,6 +15,10 @@ def print_world(): print("World") +def fail_task(): + raise ValueError("This task should fail!") + + class ScheduledTaskPlugin(ScheduleMixin, IntegrationPluginBase): """ A sample plugin which provides support for scheduled tasks @@ -33,5 +37,9 @@ class ScheduledTaskPlugin(ScheduleMixin, IntegrationPluginBase): 'world': { 'func': 'plugin.samples.integration.scheduled_task.print_hello', 'schedule': 'H', - } - } \ No newline at end of file + }, + 'failure': { + 'func': 'plugin.samples.integration.scheduled_task.fail_task', + 'schedule': 'D', + }, + } From 103dfaa2a57e1d1f5a635ed128d0b0725c90d709 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 17:11:53 +1100 Subject: [PATCH 65/67] try/catch for operational error - Database might not yet be ready to load models --- .../plugin/builtin/integration/mixins.py | 50 +++++++++++-------- InvenTree/plugin/registry.py | 23 +++++---- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 54f739d04d..cd757edc9f 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -135,41 +135,49 @@ class ScheduleMixin: Register the tasks with the database """ - from django_q.models import Schedule + try: + from django_q.models import Schedule - for key, task in self.scheduled_tasks.items(): + for key, task in self.scheduled_tasks.items(): - task_name = self.get_task_name(key) + task_name = self.get_task_name(key) - # If a matching scheduled task does not exist, create it! - if not Schedule.objects.filter(name=task_name).exists(): + # If a matching scheduled task does not exist, create it! + if not Schedule.objects.filter(name=task_name).exists(): - logger.info(f"Adding scheduled task '{task_name}'") + logger.info(f"Adding scheduled task '{task_name}'") - Schedule.objects.create( - name=task_name, - func=task['func'], - schedule_type=task['schedule'], - minutes=task.get('minutes', None), - repeats=task.get('repeats', -1), - ) + Schedule.objects.create( + name=task_name, + func=task['func'], + schedule_type=task['schedule'], + minutes=task.get('minutes', None), + repeats=task.get('repeats', -1), + ) + except OperationalError: + # Database might not yet be ready + pass def unregister_tasks(self): """ Deregister the tasks with the database """ - from django_q.models import Schedule + try: + from django_q.models import Schedule - for key, task in self.scheduled_tasks.items(): + for key, task in self.scheduled_tasks.items(): - task_name = self.get_task_name(key) + task_name = self.get_task_name(key) - try: - scheduled_task = Schedule.objects.get(name=task_name) - scheduled_task.delete() - except Schedule.DoesNotExist: - pass + try: + scheduled_task = Schedule.objects.get(name=task_name) + scheduled_task.delete() + except Schedule.DoesNotExist: + pass + except OperationalError: + # Database might not yet be ready + pass class UrlsMixin: diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index 12dfc9d43e..37196d7e54 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -301,7 +301,6 @@ class PluginsRegistry: logger.info('Activating plugin tasks') from common.models import InvenTreeSetting - from django_q.models import Schedule # List of tasks we have activated task_keys = [] @@ -323,17 +322,23 @@ class PluginsRegistry: # Remove any scheduled tasks which do not match # This stops 'old' plugin tasks from accumulating - scheduled_plugin_tasks = Schedule.objects.filter(name__istartswith="plugin.") + try: + from django_q.models import Schedule - deleted_count = 0 + scheduled_plugin_tasks = Schedule.objects.filter(name__istartswith="plugin.") - for task in scheduled_plugin_tasks: - if task.name not in task_keys: - task.delete() - deleted_count += 1 + deleted_count = 0 - if deleted_count > 0: - logger.info(f"Removed {deleted_count} old scheduled tasks") + for task in scheduled_plugin_tasks: + if task.name not in task_keys: + task.delete() + deleted_count += 1 + + if deleted_count > 0: + logger.info(f"Removed {deleted_count} old scheduled tasks") + except OperationalError: + # Database might not yet be ready + pass def deactivate_integration_schedule(self): pass From 668e2bfcd593d06d9e4441a1e4ebc50af1238b9b Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 17:20:57 +1100 Subject: [PATCH 66/67] Further error catching --- InvenTree/plugin/builtin/integration/mixins.py | 4 ++-- InvenTree/plugin/registry.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index cd757edc9f..5390740c03 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -154,7 +154,7 @@ class ScheduleMixin: minutes=task.get('minutes', None), repeats=task.get('repeats', -1), ) - except OperationalError: + except (ProgrammingError, OperationalError): # Database might not yet be ready pass @@ -175,7 +175,7 @@ class ScheduleMixin: scheduled_task.delete() except Schedule.DoesNotExist: pass - except OperationalError: + except (ProgrammingError, OperationalError): # Database might not yet be ready pass diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index 37196d7e54..c6dbe959b8 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -336,7 +336,7 @@ class PluginsRegistry: if deleted_count > 0: logger.info(f"Removed {deleted_count} old scheduled tasks") - except OperationalError: + except (ProgrammingError, OperationalError): # Database might not yet be ready pass From 8efd45f0adc4e9766c7b64f9e565371c162ad077 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 7 Jan 2022 18:00:38 +1100 Subject: [PATCH 67/67] log warning message if db not ready --- InvenTree/plugin/builtin/integration/mixins.py | 4 ++-- InvenTree/plugin/registry.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 5390740c03..c6198ed7a1 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -156,7 +156,7 @@ class ScheduleMixin: ) except (ProgrammingError, OperationalError): # Database might not yet be ready - pass + logger.warning("register_tasks failed, database not ready") def unregister_tasks(self): """ @@ -177,7 +177,7 @@ class ScheduleMixin: pass except (ProgrammingError, OperationalError): # Database might not yet be ready - pass + logger.warning("unregister_tasks failed, database not ready") class UrlsMixin: diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py index c6dbe959b8..45df8cf94b 100644 --- a/InvenTree/plugin/registry.py +++ b/InvenTree/plugin/registry.py @@ -338,7 +338,7 @@ class PluginsRegistry: logger.info(f"Removed {deleted_count} old scheduled tasks") except (ProgrammingError, OperationalError): # Database might not yet be ready - pass + logger.warning("activate_integration_schedule failed, database not ready") def deactivate_integration_schedule(self): pass