diff --git a/InvenTree/InvenTree/api_tester.py b/InvenTree/InvenTree/api_tester.py index 1cbc62ec0a..e2bdae1d8f 100644 --- a/InvenTree/InvenTree/api_tester.py +++ b/InvenTree/InvenTree/api_tester.py @@ -78,6 +78,22 @@ class InvenTreeAPITestCase(APITestCase): ruleset.save() break + def getActions(self, url): + """ + Return a dict of the 'actions' available at a given endpoint. + Makes use of the HTTP 'OPTIONS' method to request this. + """ + + response = self.client.options(url) + self.assertEqual(response.status_code, 200) + + actions = response.data.get('actions', None) + + if not actions: + actions = {} + + return actions + def get(self, url, data={}, expected_code=200): """ Issue a GET request diff --git a/InvenTree/InvenTree/fields.py b/InvenTree/InvenTree/fields.py index 8d9ab77463..462d2b0e0e 100644 --- a/InvenTree/InvenTree/fields.py +++ b/InvenTree/InvenTree/fields.py @@ -14,8 +14,10 @@ from django.core import validators from django import forms from decimal import Decimal + from djmoney.models.fields import MoneyField as ModelMoneyField from djmoney.forms.fields import MoneyField +from djmoney.models.validators import MinMoneyValidator import InvenTree.helpers import common.settings @@ -47,7 +49,10 @@ def money_kwargs(): class InvenTreeModelMoneyField(ModelMoneyField): - """ custom MoneyField for clean migrations while using dynamic currency settings """ + """ + Custom MoneyField for clean migrations while using dynamic currency settings + """ + def __init__(self, **kwargs): # detect if creating migration if 'makemigrations' in sys.argv: @@ -58,6 +63,16 @@ class InvenTreeModelMoneyField(ModelMoneyField): # set defaults kwargs.update(money_kwargs()) + # Set a minimum value validator + validators = kwargs.get('validators', []) + + if len(validators) == 0: + validators.append( + MinMoneyValidator(0), + ) + + kwargs['validators'] = validators + super().__init__(**kwargs) def formfield(self, **kwargs): diff --git a/InvenTree/InvenTree/metadata.py b/InvenTree/InvenTree/metadata.py new file mode 100644 index 0000000000..f1b1c0c040 --- /dev/null +++ b/InvenTree/InvenTree/metadata.py @@ -0,0 +1,172 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals + +import logging + +from rest_framework import serializers +from rest_framework.metadata import SimpleMetadata +from rest_framework.utils import model_meta +from rest_framework.fields import empty + +import users.models + + +logger = logging.getLogger('inventree') + + +class InvenTreeMetadata(SimpleMetadata): + """ + Custom metadata class for the DRF API. + + This custom metadata class imits the available "actions", + based on the user's role permissions. + + Thus when a client send an OPTIONS request to an API endpoint, + it will only receive a list of actions which it is allowed to perform! + + Additionally, we include some extra information about database models, + so we can perform lookup for ForeignKey related fields. + + """ + + def determine_metadata(self, request, view): + + metadata = super().determine_metadata(request, view) + + user = request.user + + if user is None: + # No actions for you! + metadata['actions'] = {} + return metadata + + try: + # Extract the model name associated with the view + self.model = view.serializer_class.Meta.model + + # Construct the 'table name' from the model + app_label = self.model._meta.app_label + tbl_label = self.model._meta.model_name + + metadata['model'] = tbl_label + + table = f"{app_label}_{tbl_label}" + + actions = metadata.get('actions', None) + + if actions is not None: + + check = users.models.RuleSet.check_table_permission + + # Map the request method to a permission type + rolemap = { + 'POST': 'add', + 'PUT': 'change', + 'PATCH': 'change', + 'DELETE': 'delete', + } + + # Remove any HTTP methods that the user does not have permission for + for method, permission in rolemap.items(): + if method in actions and not check(user, table, permission): + del actions[method] + + # Add a 'DELETE' action if we are allowed to delete + if 'DELETE' in view.allowed_methods and check(user, table, 'delete'): + actions['DELETE'] = True + + # Add a 'VIEW' action if we are allowed to view + if 'GET' in view.allowed_methods and check(user, table, 'view'): + actions['GET'] = True + + except AttributeError: + # We will assume that if the serializer class does *not* have a Meta + # then we don't need a permission + pass + + return metadata + + def get_serializer_info(self, serializer): + """ + Override get_serializer_info so that we can add 'default' values + to any fields whose Meta.model specifies a default value + """ + + serializer_info = super().get_serializer_info(serializer) + + try: + ModelClass = serializer.Meta.model + + model_fields = model_meta.get_field_info(ModelClass) + + # Iterate through simple fields + for name, field in model_fields.fields.items(): + + if field.has_default() and name in serializer_info.keys(): + + default = field.default + + if callable(default): + try: + default = default() + except: + continue + + serializer_info[name]['default'] = default + + # Iterate through relations + for name, relation in model_fields.relations.items(): + + if name not in serializer_info.keys(): + # Skip relation not defined in serializer + continue + + if relation.reverse: + # Ignore reverse relations + continue + + # Extract and provide the "limit_choices_to" filters + # This is used to automatically filter AJAX requests + serializer_info[name]['filters'] = relation.model_field.get_limit_choices_to() + + if 'help_text' not in serializer_info[name] and hasattr(relation.model_field, 'help_text'): + serializer_info[name]['help_text'] = relation.model_field.help_text + + except AttributeError: + pass + + return serializer_info + + def get_field_info(self, field): + """ + Given an instance of a serializer field, return a dictionary + of metadata about it. + + We take the regular DRF metadata and add our own unique flavor + """ + + # Run super method first + field_info = super().get_field_info(field) + + # If a default value is specified for the serializer field, add it! + if 'default' not in field_info and not field.default == empty: + field_info['default'] = field.get_default() + + # Introspect writable related fields + if field_info['type'] == 'field' and not field_info['read_only']: + + # If the field is a PrimaryKeyRelatedField, we can extract the model from the queryset + if isinstance(field, serializers.PrimaryKeyRelatedField): + model = field.queryset.model + else: + logger.debug("Could not extract model for:", field_info['label'], '->', field) + model = None + + if model: + # Mark this field as "related", and point to the URL where we can get the data! + field_info['type'] = 'related field' + field_info['api_url'] = model.get_api_url() + field_info['model'] = model._meta.model_name + + return field_info diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py index 5822f8a19f..2831a23151 100644 --- a/InvenTree/InvenTree/models.py +++ b/InvenTree/InvenTree/models.py @@ -10,11 +10,13 @@ from django.db import models from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.utils.translation import gettext_lazy as _ +from django.core.exceptions import ValidationError from django.db.models.signals import pre_delete from django.dispatch import receiver from mptt.models import MPTTModel, TreeForeignKey +from mptt.exceptions import InvalidMove from .validators import validate_tree_name @@ -91,6 +93,15 @@ class InvenTreeTree(MPTTModel): parent: The item immediately above this one. An item with a null parent is a top-level item """ + def save(self, *args, **kwargs): + + try: + super().save(*args, **kwargs) + except InvalidMove: + raise ValidationError({ + 'parent': _("Invalid choice"), + }) + class Meta: abstract = True diff --git a/InvenTree/InvenTree/serializers.py b/InvenTree/InvenTree/serializers.py index 772daa06ab..58d33697b7 100644 --- a/InvenTree/InvenTree/serializers.py +++ b/InvenTree/InvenTree/serializers.py @@ -5,16 +5,58 @@ Serializers used in various InvenTree apps # -*- coding: utf-8 -*- from __future__ import unicode_literals + import os +from decimal import Decimal + from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import ValidationError as DjangoValidationError +from django.utils.translation import ugettext_lazy as _ + +from djmoney.contrib.django_rest_framework.fields import MoneyField +from djmoney.money import Money +from djmoney.utils import MONEY_CLASSES, get_currency_field_name from rest_framework import serializers from rest_framework.utils import model_meta from rest_framework.fields import empty from rest_framework.exceptions import ValidationError +from rest_framework.serializers import DecimalField + + +class InvenTreeMoneySerializer(MoneyField): + """ + Custom serializer for 'MoneyField', + which ensures that passed values are numerically valid + + Ref: https://github.com/django-money/django-money/blob/master/djmoney/contrib/django_rest_framework/fields.py + """ + + def get_value(self, data): + """ + Test that the returned amount is a valid Decimal + """ + + amount = super(DecimalField, self).get_value(data) + + # Convert an empty string to None + if len(str(amount).strip()) == 0: + amount = None + + try: + if amount is not None: + amount = Decimal(amount) + except: + raise ValidationError(_("Must be a valid number")) + + currency = data.get(get_currency_field_name(self.field_name), self.default_currency) + + if currency and amount is not None and not isinstance(amount, MONEY_CLASSES) and amount is not empty: + return Money(amount, currency) + + return amount class UserSerializer(serializers.ModelSerializer): @@ -110,6 +152,19 @@ class InvenTreeModelSerializer(serializers.ModelSerializer): return initials + def save(self, **kwargs): + """ + Catch any django ValidationError thrown at the moment save() is called, + and re-throw as a DRF ValidationError + """ + + try: + super().save(**kwargs) + except (ValidationError, DjangoValidationError) as exc: + raise ValidationError(detail=serializers.as_serializer_error(exc)) + + return self.instance + def run_validation(self, data=empty): """ Perform serializer validation. diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 6c1d52487d..3b7c95e245 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -342,6 +342,7 @@ REST_FRAMEWORK = { 'InvenTree.permissions.RolePermission', ), 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema', + 'DEFAULT_METADATA_CLASS': 'InvenTree.metadata.InvenTreeMetadata' } WSGI_APPLICATION = 'InvenTree.wsgi.application' diff --git a/InvenTree/InvenTree/static/css/inventree.css b/InvenTree/InvenTree/static/css/inventree.css index e4d12576fa..61815f0587 100644 --- a/InvenTree/InvenTree/static/css/inventree.css +++ b/InvenTree/InvenTree/static/css/inventree.css @@ -640,6 +640,14 @@ z-index: 9999; } +.modal-header { + border-bottom: 1px solid #ddd; +} + +.modal-footer { + border-top: 1px solid #ddd; +} + .modal-primary { z-index: 10000; } @@ -960,4 +968,57 @@ input[type="date"].form-control, input[type="time"].form-control, input[type="da .sidebar-icon { min-width: 19px; -} \ No newline at end of file +} + +.row.full-height { + display: flex; + flex-wrap: wrap; +} + +.row.full-height > [class*='col-'] { + display: flex; + flex-direction: column; +} + +a.anchor { + display: block; + position: relative; + top: -60px; + visibility: hidden; +} + +.select2-close-mask { + z-index: 99999; +} + +.select2-dropdown { + z-index: 99998; +} + +.select2-container { + width: 100%; +} + +.select2-container .select2-selection--single { + height: 30px; +} + +.select2-thumbnail { + max-width: 24px; + max-height: 24px; + border-radius: 4px; + margin-right: 10px; +} + +.select2-selection { + overflow-y: clip; +} + +.form-clear { + padding: 6px 6px; +} + +.form-control { + height: 30px; +} + diff --git a/InvenTree/InvenTree/static/script/select2/i18n/af.js b/InvenTree/InvenTree/static/script/select2/i18n/af.js deleted file mode 100644 index 920e249f0f..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/af.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Verwyders asseblief "+t+" character";return t!=1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Voer asseblief "+t+" of meer karakters";return n},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var t="Kies asseblief net "+e.maximum+" item";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/ar.js b/InvenTree/InvenTree/static/script/select2/i18n/ar.js deleted file mode 100644 index 63acd51047..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/ar.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(e){var t=e.input.length-e.maximum;return"الرجاء حذف "+t+" عناصر"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"الرجاء إضافة "+t+" عناصر"},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(e){return"تستطيع إختيار "+e.maximum+" بنود فقط"},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/az.js b/InvenTree/InvenTree/static/script/select2/i18n/az.js deleted file mode 100644 index d19712199c..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/az.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/az",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return t+" simvol silin"},inputTooShort:function(e){var t=e.minimum-e.input.length;return t+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(e){return"Sadəcə "+e.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/bg.js b/InvenTree/InvenTree/static/script/select2/i18n/bg.js deleted file mode 100644 index bba64766bc..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/bg.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/bg",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Моля въведете с "+t+" по-малко символ";return t>1&&(n+="a"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Моля въведете още "+t+" символ";return t>1&&(n+="a"),n},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(e){var t="Можете да направите до "+e.maximum+" ";return e.maximum>1?t+="избора":t+="избор",t},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/bs.js b/InvenTree/InvenTree/static/script/select2/i18n/bs.js deleted file mode 100644 index 77edfed65e..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/bs.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/bs",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Obrišite "+n+" simbol";return r+=e(n,"","a","a"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Ukucajte bar još "+n+" simbol";return r+=e(n,"","a","a"),r},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(t){var n="Možete izabrati samo "+t.maximum+" stavk";return n+=e(t.maximum,"u","e","i"),n},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/ca.js b/InvenTree/InvenTree/static/script/select2/i18n/ca.js deleted file mode 100644 index bd1174b241..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/ca.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Si us plau, elimina "+t+" car";return t==1?n+="àcter":n+="àcters",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Si us plau, introdueix "+t+" car";return t==1?n+="àcter":n+="àcters",n},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var t="Només es pot seleccionar "+e.maximum+" element";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/cs.js b/InvenTree/InvenTree/static/script/select2/i18n/cs.js deleted file mode 100644 index 60b44835b0..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/cs.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/cs",[],function(){function e(e,t){switch(e){case 2:return t?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?"Prosím, zadejte o jeden znak méně.":n<=4?"Prosím, zadejte o "+e(n,!0)+" znaky méně.":"Prosím, zadejte o "+n+" znaků méně."},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?"Prosím, zadejte ještě jeden znak.":n<=4?"Prosím, zadejte ještě další "+e(n,!0)+" znaky.":"Prosím, zadejte ještě dalších "+n+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(t){var n=t.maximum;return n==1?"Můžete zvolit jen jednu položku.":n<=4?"Můžete zvolit maximálně "+e(n,!1)+" položky.":"Můžete zvolit maximálně "+n+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/da.js b/InvenTree/InvenTree/static/script/select2/i18n/da.js deleted file mode 100644 index ac57934cf3..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/da.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Angiv venligst "+t+" tegn mindre"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Angiv venligst "+t+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var t="Du kan kun vælge "+e.maximum+" emne";return e.maximum!=1&&(t+="r"),t},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/de.js b/InvenTree/InvenTree/static/script/select2/i18n/de.js deleted file mode 100644 index 283f6823ac..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/de.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Bitte "+t+" Zeichen weniger eingeben"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Bitte "+t+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var t="Sie können nur "+e.maximum+" Eintr";return e.maximum===1?t+="ag":t+="äge",t+=" auswählen",t},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/dsb.js b/InvenTree/InvenTree/static/script/select2/i18n/dsb.js deleted file mode 100644 index cec4f57f0c..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/dsb.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/dsb",[],function(){var e=["znamuško","znamušce","znamuška","znamuškow"],t=["zapisk","zapiska","zapiski","zapiskow"],n=function(t,n){if(t===1)return n[0];if(t===2)return n[1];if(t>2&&t<=4)return n[2];if(t>=5)return n[3]};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(t){var r=t.input.length-t.maximum;return"Pšosym lašuj "+r+" "+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return"Pšosym zapódaj nanejmjenjej "+r+" "+n(r,e)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(e){return"Móžoš jano "+e.maximum+" "+n(e.maximum,t)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/el.js b/InvenTree/InvenTree/static/script/select2/i18n/el.js deleted file mode 100644 index 93b09d26a6..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/el.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Παρακαλώ διαγράψτε "+t+" χαρακτήρ";return t==1&&(n+="α"),t!=1&&(n+="ες"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Παρακαλώ συμπληρώστε "+t+" ή περισσότερους χαρακτήρες";return n},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(e){var t="Μπορείτε να επιλέξετε μόνο "+e.maximum+" επιλογ";return e.maximum==1&&(t+="ή"),e.maximum!=1&&(t+="ές"),t},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/en.js b/InvenTree/InvenTree/static/script/select2/i18n/en.js deleted file mode 100644 index ddeabddc40..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/en.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Please delete "+t+" character";return t!=1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Please enter "+t+" or more characters";return n},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var t="You can only select "+e.maximum+" item";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/es.js b/InvenTree/InvenTree/static/script/select2/i18n/es.js deleted file mode 100644 index f3812d611f..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/es.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"No se pudieron cargar los resultados"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor, elimine "+t+" car";return t==1?n+="ácter":n+="acteres",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Por favor, introduzca "+t+" car";return t==1?n+="ácter":n+="acteres",n},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var t="Sólo puede seleccionar "+e.maximum+" elemento";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/et.js b/InvenTree/InvenTree/static/script/select2/i18n/et.js deleted file mode 100644 index cf7ce543a1..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/et.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Sisesta "+t+" täht";return t!=1&&(n+="e"),n+=" vähem",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Sisesta "+t+" täht";return t!=1&&(n+="e"),n+=" rohkem",n},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var t="Saad vaid "+e.maximum+" tulemus";return e.maximum==1?t+="e":t+="t",t+=" valida",t},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/eu.js b/InvenTree/InvenTree/static/script/select2/i18n/eu.js deleted file mode 100644 index a5659ef9a0..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/eu.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return t==1?n+="karaktere bat":n+=t+" karaktere",n+=" gutxiago",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return t==1?n+="karaktere bat":n+=t+" karaktere",n+=" gehiago",n},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return e.maximum===1?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/fa.js b/InvenTree/InvenTree/static/script/select2/i18n/fa.js deleted file mode 100644 index 522be28ced..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/fa.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="لطفاً "+t+" کاراکتر را حذف نمایید";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="لطفاً تعداد "+t+" کاراکتر یا بیشتر وارد نمایید";return n},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(e){var t="شما تنها می‌توانید "+e.maximum+" آیتم را انتخاب نمایید";return t},noResults:function(){return"هیچ نتیجه‌ای یافت نشد"},searching:function(){return"در حال جستجو..."}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/fi.js b/InvenTree/InvenTree/static/script/select2/i18n/fi.js deleted file mode 100644 index 5984f81553..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/fi.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Ole hyvä ja anna "+t+" merkkiä vähemmän"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Ole hyvä ja anna "+t+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(e){return"Voit valita ainoastaan "+e.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/fr.js b/InvenTree/InvenTree/static/script/select2/i18n/fr.js deleted file mode 100644 index 8ccd0fc87d..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/fr.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Supprimez "+t+" caractère"+(t>1)?"s":""},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Saisissez au moins "+t+" caractère"+(t>1)?"s":""},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){return"Vous pouvez seulement sélectionner "+e.maximum+" élément"+(e.maximum>1)?"s":""},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/gl.js b/InvenTree/InvenTree/static/script/select2/i18n/gl.js deleted file mode 100644 index 46131ad7f7..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/gl.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/gl",[],function(){return{errorLoading:function(){return"Non foi posíbel cargar os resultados."},inputTooLong:function(e){var t=e.input.length-e.maximum;return t===1?"Elimine un carácter":"Elimine "+t+" caracteres"},inputTooShort:function(e){var t=e.minimum-e.input.length;return t===1?"Engada un carácter":"Engada "+t+" caracteres"},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){return e.maximum===1?"Só pode seleccionar un elemento":"Só pode seleccionar "+e.maximum+" elementos"},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/he.js b/InvenTree/InvenTree/static/script/select2/i18n/he.js deleted file mode 100644 index caf9739ce6..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/he.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="נא למחוק ";return t===1?n+="תו אחד":n+=t+" תווים",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="נא להכניס ";return t===1?n+="תו אחד":n+=t+" תווים",n+=" או יותר",n},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(e){var t="באפשרותך לבחור עד ";return e.maximum===1?t+="פריט אחד":t+=e.maximum+" פריטים",t},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/hi.js b/InvenTree/InvenTree/static/script/select2/i18n/hi.js deleted file mode 100644 index d71b80c908..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/hi.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" अक्षर को हटा दें";return t>1&&(n=t+" अक्षरों को हटा दें "),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="कृपया "+t+" या अधिक अक्षर दर्ज करें";return n},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(e){var t="आप केवल "+e.maximum+" आइटम का चयन कर सकते हैं";return t},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/hr.js b/InvenTree/InvenTree/static/script/select2/i18n/hr.js deleted file mode 100644 index a483a34b81..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/hr.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hr",[],function(){function e(e){var t=" "+e+" znak";return e%10<5&&e%10>0&&(e%100<5||e%100>19)?e%10>1&&(t+="a"):t+="ova",t}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(t){var n=t.input.length-t.maximum;return"Unesite "+e(n)},inputTooShort:function(t){var n=t.minimum-t.input.length;return"Unesite još "+e(n)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(e){return"Maksimalan broj odabranih stavki je "+e.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/hsb.js b/InvenTree/InvenTree/static/script/select2/i18n/hsb.js deleted file mode 100644 index 6cb2c4e8d1..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/hsb.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hsb",[],function(){var e=["znamješko","znamješce","znamješka","znamješkow"],t=["zapisk","zapiskaj","zapiski","zapiskow"],n=function(t,n){if(t===1)return n[0];if(t===2)return n[1];if(t>2&&t<=4)return n[2];if(t>=5)return n[3]};return{errorLoading:function(){return"Wuslědki njedachu so začitać."},inputTooLong:function(t){var r=t.input.length-t.maximum;return"Prošu zhašej "+r+" "+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return"Prošu zapodaj znajmjeńša "+r+" "+n(r,e)},loadingMore:function(){return"Dalše wuslědki so začitaja…"},maximumSelected:function(e){return"Móžeš jenož "+e.maximum+" "+n(e.maximum,t)+"wubrać"},noResults:function(){return"Žane wuslědki namakane"},searching:function(){return"Pyta so…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/hu.js b/InvenTree/InvenTree/static/script/select2/i18n/hu.js deleted file mode 100644 index 2e3d1f2c53..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/hu.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Túl hosszú. "+t+" karakterrel több, mint kellene."},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Túl rövid. Még "+t+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/hy.js b/InvenTree/InvenTree/static/script/select2/i18n/hy.js deleted file mode 100644 index 6c76664a28..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/hy.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Խնդրում ենք հեռացնել "+t+" նշան";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Խնդրում ենք մուտքագրել "+t+" կամ ավել նշաններ";return n},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(e){var t="Դուք կարող եք ընտրել առավելագույնը "+e.maximum+" կետ";return t},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/id.js b/InvenTree/InvenTree/static/script/select2/i18n/id.js deleted file mode 100644 index 4ca371a754..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/id.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Hapuskan "+t+" huruf"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Masukkan "+t+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(e){return"Anda hanya dapat memilih "+e.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/is.js b/InvenTree/InvenTree/static/script/select2/i18n/is.js deleted file mode 100644 index 560d3bf399..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/is.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/is",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vinsamlegast styttið texta um "+t+" staf";return t<=1?n:n+"i"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vinsamlegast skrifið "+t+" staf";return t>1&&(n+="i"),n+=" í viðbót",n},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(e){return"Þú getur aðeins valið "+e.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/it.js b/InvenTree/InvenTree/static/script/select2/i18n/it.js deleted file mode 100644 index fa65659e03..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/it.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Per favore cancella "+t+" caratter";return t!==1?n+="i":n+="e",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Per favore inserisci "+t+" o più caratteri";return n},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var t="Puoi selezionare solo "+e.maximum+" element";return e.maximum!==1?t+="i":t+="o",t},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/ja.js b/InvenTree/InvenTree/static/script/select2/i18n/ja.js deleted file mode 100644 index 5787930dfe..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/ja.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" 文字を削除してください";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="少なくとも "+t+" 文字を入力してください";return n},loadingMore:function(){return"読み込み中…"},maximumSelected:function(e){var t=e.maximum+" 件しか選択できません";return t},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/km.js b/InvenTree/InvenTree/static/script/select2/i18n/km.js deleted file mode 100644 index 210d6c80bb..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/km.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="សូមលុបចេញ "+t+" អក្សរ";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="សូមបញ្ចូល"+t+" អក្សរ រឺ ច្រើនជាងនេះ";return n},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(e){var t="អ្នកអាចជ្រើសរើសបានតែ "+e.maximum+" ជម្រើសប៉ុណ្ណោះ";return t},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/ko.js b/InvenTree/InvenTree/static/script/select2/i18n/ko.js deleted file mode 100644 index 97b5a839d0..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/ko.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="너무 깁니다. "+t+" 글자 지워주세요.";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="너무 짧습니다. "+t+" 글자 더 입력해주세요.";return n},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(e){var t="최대 "+e.maximum+"개까지만 선택 가능합니다.";return t},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/lt.js b/InvenTree/InvenTree/static/script/select2/i18n/lt.js deleted file mode 100644 index e507a62a97..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/lt.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/lt",[],function(){function e(e,t,n,r){return e%10===1&&(e%100<11||e%100>19)?t:e%10>=2&&e%10<=9&&(e%100<11||e%100>19)?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r="Pašalinkite "+n+" simbol";return r+=e(n,"į","ius","ių"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Įrašykite dar "+n+" simbol";return r+=e(n,"į","ius","ių"),r},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(t){var n="Jūs galite pasirinkti tik "+t.maximum+" element";return n+=e(t.maximum,"ą","us","ų"),n},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/lv.js b/InvenTree/InvenTree/static/script/select2/i18n/lv.js deleted file mode 100644 index a08242b167..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/lv.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/lv",[],function(){function e(e,t,n,r){return e===11?t:e%10===1?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r="Lūdzu ievadiet par "+n;return r+=" simbol"+e(n,"iem","u","iem"),r+" mazāk"},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Lūdzu ievadiet vēl "+n;return r+=" simbol"+e(n,"us","u","us"),r},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(t){var n="Jūs varat izvēlēties ne vairāk kā "+t.maximum;return n+=" element"+e(t.maximum,"us","u","us"),n},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/mk.js b/InvenTree/InvenTree/static/script/select2/i18n/mk.js deleted file mode 100644 index ac1cb140ba..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/mk.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/mk",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Ве молиме внесете "+e.maximum+" помалку карактер";return e.maximum!==1&&(n+="и"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Ве молиме внесете уште "+e.maximum+" карактер";return e.maximum!==1&&(n+="и"),n},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(e){var t="Можете да изберете само "+e.maximum+" ставк";return e.maximum===1?t+="а":t+="и",t},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/ms.js b/InvenTree/InvenTree/static/script/select2/i18n/ms.js deleted file mode 100644 index fcd26aa592..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/ms.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Sila hapuskan "+t+" aksara"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Sila masukkan "+t+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(e){return"Anda hanya boleh memilih "+e.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/nb.js b/InvenTree/InvenTree/static/script/select2/i18n/nb.js deleted file mode 100644 index 1330a36e4f..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/nb.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Vennligst fjern "+t+" tegn"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vennligst skriv inn "+t+" tegn til";return n+" tegn til"},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/nl.js b/InvenTree/InvenTree/static/script/select2/i18n/nl.js deleted file mode 100644 index d2df9e9a43..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/nl.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Gelieve "+t+" karakters te verwijderen";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Gelieve "+t+" of meer karakters in te voeren";return n},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var t=e.maximum==1?"kan":"kunnen",n="Er "+t+" maar "+e.maximum+" item";return e.maximum!=1&&(n+="s"),n+=" worden geselecteerd",n},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/pl.js b/InvenTree/InvenTree/static/script/select2/i18n/pl.js deleted file mode 100644 index bc5a89a2ce..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/pl.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pl",[],function(){var e=["znak","znaki","znaków"],t=["element","elementy","elementów"],n=function(t,n){if(t===1)return n[0];if(t>1&&t<=4)return n[1];if(t>=5)return n[2]};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(t){var r=t.input.length-t.maximum;return"Usuń "+r+" "+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return"Podaj przynajmniej "+r+" "+n(r,e)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(e){return"Możesz zaznaczyć tylko "+e.maximum+" "+n(e.maximum,t)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/ps.js b/InvenTree/InvenTree/static/script/select2/i18n/ps.js deleted file mode 100644 index a7ddf8c33f..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/ps.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="د مهربانۍ لمخي "+t+" توری ړنګ کړئ";return t!=1&&(n=n.replace("توری","توري")),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="لږ تر لږه "+t+" يا ډېر توري وليکئ";return n},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(e){var t="تاسو يوازي "+e.maximum+" قلم په نښه کولای سی";return e.maximum!=1&&(t=t.replace("قلم","قلمونه")),t},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/pt-BR.js b/InvenTree/InvenTree/static/script/select2/i18n/pt-BR.js deleted file mode 100644 index ae52dd551a..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/pt-BR.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Apague "+t+" caracter";return t!=1&&(n+="es"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Digite "+t+" ou mais caracteres";return n},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var t="Você só pode selecionar "+e.maximum+" ite";return e.maximum==1?t+="m":t+="ns",t},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/pt.js b/InvenTree/InvenTree/static/script/select2/i18n/pt.js deleted file mode 100644 index 8b5780043a..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/pt.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor apague "+t+" ";return n+=t!=1?"caracteres":"caractere",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Introduza "+t+" ou mais caracteres";return n},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var t="Apenas pode seleccionar "+e.maximum+" ";return t+=e.maximum!=1?"itens":"item",t},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/ro.js b/InvenTree/InvenTree/static/script/select2/i18n/ro.js deleted file mode 100644 index 9d2dfe7939..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/ro.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return t!==1&&(n+="e"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vă rugăm să introduceți "+t+" sau mai multe caractere";return n},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",e.maximum!==1&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/ru.js b/InvenTree/InvenTree/static/script/select2/i18n/ru.js deleted file mode 100644 index 4b7655ef8c..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/ru.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ru",[],function(){function e(e,t,n,r){return e%10<5&&e%10>0&&e%100<5||e%100>20?e%10>1?n:t:r}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Пожалуйста, введите на "+n+" символ";return r+=e(n,"","a","ов"),r+=" меньше",r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Пожалуйста, введите еще хотя бы "+n+" символ";return r+=e(n,"","a","ов"),r},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(t){var n="Вы можете выбрать не более "+t.maximum+" элемент";return n+=e(t.maximum,"","a","ов"),n},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/sk.js b/InvenTree/InvenTree/static/script/select2/i18n/sk.js deleted file mode 100644 index b9139452d0..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/sk.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{errorLoading:function(){return"Výsledky sa nepodarilo načítať."},inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?"Prosím, zadajte o jeden znak menej":n>=2&&n<=4?"Prosím, zadajte o "+e[n](!0)+" znaky menej":"Prosím, zadajte o "+n+" znakov menej"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?"Prosím, zadajte ešte jeden znak":n<=4?"Prosím, zadajte ešte ďalšie "+e[n](!0)+" znaky":"Prosím, zadajte ešte ďalších "+n+" znakov"},loadingMore:function(){return"Načítanie ďalších výsledkov…"},maximumSelected:function(t){return t.maximum==1?"Môžete zvoliť len jednu položku":t.maximum>=2&&t.maximum<=4?"Môžete zvoliť najviac "+e[t.maximum](!1)+" položky":"Môžete zvoliť najviac "+t.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/sl.js b/InvenTree/InvenTree/static/script/select2/i18n/sl.js deleted file mode 100644 index 2fe0cc7ef9..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/sl.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sl",[],function(){return{errorLoading:function(){return"Zadetkov iskanja ni bilo mogoče naložiti."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Prosim zbrišite "+t+" znak";return t==2?n+="a":t!=1&&(n+="e"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Prosim vpišite še "+t+" znak";return t==2?n+="a":t!=1&&(n+="e"),n},loadingMore:function(){return"Nalagam več zadetkov…"},maximumSelected:function(e){var t="Označite lahko največ "+e.maximum+" predmet";return e.maximum==2?t+="a":e.maximum!=1&&(t+="e"),t},noResults:function(){return"Ni zadetkov."},searching:function(){return"Iščem…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/sr-Cyrl.js b/InvenTree/InvenTree/static/script/select2/i18n/sr-Cyrl.js deleted file mode 100644 index 17e620c1e3..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/sr-Cyrl.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sr-Cyrl",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Обришите "+n+" симбол";return r+=e(n,"","а","а"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Укуцајте бар још "+n+" симбол";return r+=e(n,"","а","а"),r},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(t){var n="Можете изабрати само "+t.maximum+" ставк";return n+=e(t.maximum,"у","е","и"),n},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/sr.js b/InvenTree/InvenTree/static/script/select2/i18n/sr.js deleted file mode 100644 index 76b8275350..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/sr.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sr",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Obrišite "+n+" simbol";return r+=e(n,"","a","a"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Ukucajte bar još "+n+" simbol";return r+=e(n,"","a","a"),r},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(t){var n="Možete izabrati samo "+t.maximum+" stavk";return n+=e(t.maximum,"u","e","i"),n},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/sv.js b/InvenTree/InvenTree/static/script/select2/i18n/sv.js deleted file mode 100644 index a0a40dc520..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/sv.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vänligen sudda ut "+t+" tecken";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vänligen skriv in "+t+" eller fler tecken";return n},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(e){var t="Du kan max välja "+e.maximum+" element";return t},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/th.js b/InvenTree/InvenTree/static/script/select2/i18n/th.js deleted file mode 100644 index 503b7e2b7c..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/th.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/th",[],function(){return{errorLoading:function(){return"ไม่สามารถค้นข้อมูลได้"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="โปรดลบออก "+t+" ตัวอักษร";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="โปรดพิมพ์เพิ่มอีก "+t+" ตัวอักษร";return n},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(e){var t="คุณสามารถเลือกได้ไม่เกิน "+e.maximum+" รายการ";return t},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/tr.js b/InvenTree/InvenTree/static/script/select2/i18n/tr.js deleted file mode 100644 index ef4a6da236..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/tr.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/tr",[],function(){return{errorLoading:function(){return"Sonuç yüklenemedi"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" karakter daha girmelisiniz";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="En az "+t+" karakter daha girmelisiniz";return n},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(e){var t="Sadece "+e.maximum+" seçim yapabilirsiniz";return t},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/uk.js b/InvenTree/InvenTree/static/script/select2/i18n/uk.js deleted file mode 100644 index 057463d738..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/uk.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/uk",[],function(){function e(e,t,n,r){return e%100>10&&e%100<15?r:e%10===1?t:e%10>1&&e%10<5?n:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(t){var n=t.input.length-t.maximum;return"Будь ласка, видаліть "+n+" "+e(t.maximum,"літеру","літери","літер")},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Будь ласка, введіть "+t+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(t){return"Ви можете вибрати лише "+t.maximum+" "+e(t.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/vi.js b/InvenTree/InvenTree/static/script/select2/i18n/vi.js deleted file mode 100644 index 8c0a4f2a7a..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/vi.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/vi",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vui lòng nhập ít hơn "+t+" ký tự";return t!=1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vui lòng nhập nhiều hơn "+t+" ký tự";return n},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(e){var t="Chỉ có thể chọn được "+e.maximum+" lựa chọn";return t},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/zh-CN.js b/InvenTree/InvenTree/static/script/select2/i18n/zh-CN.js deleted file mode 100644 index 0b3d7970d9..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/zh-CN.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="请删除"+t+"个字符";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="请再输入至少"+t+"个字符";return n},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(e){var t="最多只能选择"+e.maximum+"个项目";return t},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/i18n/zh-TW.js b/InvenTree/InvenTree/static/script/select2/i18n/zh-TW.js deleted file mode 100644 index 4ba879bd3a..0000000000 --- a/InvenTree/InvenTree/static/script/select2/i18n/zh-TW.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */ - -(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="請刪掉"+t+"個字元";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="請再輸入"+t+"個字元";return n},loadingMore:function(){return"載入中…"},maximumSelected:function(e){var t="你只能選擇最多"+e.maximum+"項";return t},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/select2.full.min.js b/InvenTree/InvenTree/static/script/select2/select2.full.min.js deleted file mode 100644 index 96ba80cd81..0000000000 --- a/InvenTree/InvenTree/static/script/select2/select2.full.min.js +++ /dev/null @@ -1 +0,0 @@ -/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=w.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),o.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var c=s[a];delete s[a],u[a]=!0,n.apply(b,c)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,c,d,f){var h,k,m,n,o,t,v,w=[],x=typeof d;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(c=!c.length&&d.length?["require","exports","module"]:c,o=0;o0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('
    ');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('
  • '),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()});b.$results.find(".select2-results__option[aria-selected]").each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j",{class:"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):h-g<0&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var c=a(this),e=c.data("data");if("true"===c.attr("aria-selected"))return void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{}));d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),c<=2?this.$results.scrollTop(0):(g>this.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2");a(".select2.select2-container--open").each(function(){var b=a(this);this!=d[0]&&b.data("element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(''),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a("")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('
      '),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('
    • ×
    • ')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1||c)return a.call(this,b);this.clear();var d=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(d)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e0||0===c.length)){var d=a('×');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===e.$search.val()){var b=e.$searchContainer.prev(".select2-selection__choice");if(b.length>0){var d=b.data("data");e.searchRemoveChoice(d),a.preventDefault()}}});var f=document.documentMode,g=f&&f<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(g)return void e.$selection.off("input.search input.searchcheck");e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(g&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("focus",function(){c.isOpen()||e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
    • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(f=d(this))&&g.push(f)})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;if(this._isInitialized)return void b.call(this,c);this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===e.$search.val()){var b=e.$searchContainer.prev(".select2-selection__choice");if(b.length>0){var d=b.data("data");e.searchRemoveChoice(d),a.preventDefault()}}});var f=document.documentMode,g=f&&f<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(g)return void e.$selection.off("input.search input.searchcheck");e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(g&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("focus",function(){c.isOpen()||e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
    • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("jquery-mousewheel",["jquery"],function(a){return a}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults"],function(a,b,c,d){if(null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if("object"==typeof(b=b||{}))return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,f=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=a(this).data("select2");null==c&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=c[b].apply(c,f)}),a.inArray(b,e)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c}); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/css/select2-bootstrap.css b/InvenTree/InvenTree/static/select2/css/select2-bootstrap.css similarity index 100% rename from InvenTree/InvenTree/static/css/select2-bootstrap.css rename to InvenTree/InvenTree/static/select2/css/select2-bootstrap.css diff --git a/InvenTree/InvenTree/static/css/select2.css b/InvenTree/InvenTree/static/select2/css/select2.css similarity index 97% rename from InvenTree/InvenTree/static/css/select2.css rename to InvenTree/InvenTree/static/select2/css/select2.css index 447b2b86cc..750b3207ae 100644 --- a/InvenTree/InvenTree/static/css/select2.css +++ b/InvenTree/InvenTree/static/select2/css/select2.css @@ -118,12 +118,14 @@ .select2-hidden-accessible { border: 0 !important; clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(50%) !important; + clip-path: inset(50%) !important; height: 1px !important; - margin: -1px !important; overflow: hidden !important; padding: 0 !important; position: absolute !important; - width: 1px !important; } + width: 1px !important; + white-space: nowrap !important; } .select2-container--default .select2-selection--single { background-color: #fff; @@ -186,16 +188,13 @@ width: 100%; } .select2-container--default .select2-selection--multiple .select2-selection__rendered li { list-style: none; } - .select2-container--default .select2-selection--multiple .select2-selection__placeholder { - color: #999; - margin-top: 5px; - float: left; } .select2-container--default .select2-selection--multiple .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; margin-top: 5px; - margin-right: 10px; } + margin-right: 10px; + padding: 1px; } .select2-container--default .select2-selection--multiple .select2-selection__choice { background-color: #e4e4e4; border: 1px solid #aaa; @@ -214,7 +213,7 @@ .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { color: #333; } -.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { float: right; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { @@ -420,9 +419,7 @@ color: #555; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { - float: right; } - -.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + float: right; margin-left: 5px; margin-right: auto; } diff --git a/InvenTree/InvenTree/static/select2/css/select2.min.css b/InvenTree/InvenTree/static/select2/css/select2.min.css new file mode 100644 index 0000000000..7c18ad59df --- /dev/null +++ b/InvenTree/InvenTree/static/select2/css/select2.min.css @@ -0,0 +1 @@ +.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} diff --git a/InvenTree/InvenTree/static/select2/js/i18n/af.js b/InvenTree/InvenTree/static/select2/js/i18n/af.js new file mode 100644 index 0000000000..32e5ac7de8 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/af.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Verwyders asseblief "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Voer asseblief "+(e.minimum-e.input.length)+" of meer karakters"},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var n="Kies asseblief net "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"},removeAllItems:function(){return"Verwyder alle items"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ar.js b/InvenTree/InvenTree/static/select2/js/i18n/ar.js new file mode 100644 index 0000000000..64e1caad34 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ar.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(n){return"الرجاء حذف "+(n.input.length-n.maximum)+" عناصر"},inputTooShort:function(n){return"الرجاء إضافة "+(n.minimum-n.input.length)+" عناصر"},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(n){return"تستطيع إختيار "+n.maximum+" بنود فقط"},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"},removeAllItems:function(){return"قم بإزالة كل العناصر"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/az.js b/InvenTree/InvenTree/static/select2/js/i18n/az.js new file mode 100644 index 0000000000..1d52c260f2 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/az.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/az",[],function(){return{inputTooLong:function(n){return n.input.length-n.maximum+" simvol silin"},inputTooShort:function(n){return n.minimum-n.input.length+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(n){return"Sadəcə "+n.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"},removeAllItems:function(){return"Bütün elementləri sil"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/bg.js b/InvenTree/InvenTree/static/select2/js/i18n/bg.js new file mode 100644 index 0000000000..73b730a705 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/bg.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bg",[],function(){return{inputTooLong:function(n){var e=n.input.length-n.maximum,u="Моля въведете с "+e+" по-малко символ";return e>1&&(u+="a"),u},inputTooShort:function(n){var e=n.minimum-n.input.length,u="Моля въведете още "+e+" символ";return e>1&&(u+="a"),u},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(n){var e="Можете да направите до "+n.maximum+" ";return n.maximum>1?e+="избора":e+="избор",e},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/bn.js b/InvenTree/InvenTree/static/select2/js/i18n/bn.js new file mode 100644 index 0000000000..2d17b9d8e0 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/bn.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।";return 1!=e&&(u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।"),u},inputTooShort:function(n){return n.minimum-n.input.length+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।"},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(n){var e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return 1!=n.maximum&&(e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),e},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/bs.js b/InvenTree/InvenTree/static/select2/js/i18n/bs.js new file mode 100644 index 0000000000..46b084d758 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/bs.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/bs",[],function(){function e(e,n,r,t){return e%10==1&&e%100!=11?n:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(n){var r=n.input.length-n.maximum,t="Obrišite "+r+" simbol";return t+=e(r,"","a","a")},inputTooShort:function(n){var r=n.minimum-n.input.length,t="Ukucajte bar još "+r+" simbol";return t+=e(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(n){var r="Možete izabrati samo "+n.maximum+" stavk";return r+=e(n.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Uklonite sve stavke"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ca.js b/InvenTree/InvenTree/static/select2/js/i18n/ca.js new file mode 100644 index 0000000000..82dbbb7a21 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ca.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Si us plau, elimina "+n+" car";return r+=1==n?"àcter":"àcters"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Si us plau, introdueix "+n+" car";return r+=1==n?"àcter":"àcters"},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var n="Només es pot seleccionar "+e.maximum+" element";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/cs.js b/InvenTree/InvenTree/static/select2/js/i18n/cs.js new file mode 100644 index 0000000000..7116d6c1df --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/cs.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/cs",[],function(){function e(e,n){switch(e){case 2:return n?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadejte o jeden znak méně.":t<=4?"Prosím, zadejte o "+e(t,!0)+" znaky méně.":"Prosím, zadejte o "+t+" znaků méně."},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadejte ještě jeden znak.":t<=4?"Prosím, zadejte ještě další "+e(t,!0)+" znaky.":"Prosím, zadejte ještě dalších "+t+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(n){var t=n.maximum;return 1==t?"Můžete zvolit jen jednu položku.":t<=4?"Můžete zvolit maximálně "+e(t,!1)+" položky.":"Můžete zvolit maximálně "+t+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"},removeAllItems:function(){return"Odstraňte všechny položky"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/da.js b/InvenTree/InvenTree/static/select2/js/i18n/da.js new file mode 100644 index 0000000000..cda32c34aa --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/da.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){return"Angiv venligst "+(e.input.length-e.maximum)+" tegn mindre"},inputTooShort:function(e){return"Angiv venligst "+(e.minimum-e.input.length)+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var n="Du kan kun vælge "+e.maximum+" emne";return 1!=e.maximum&&(n+="r"),n},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/de.js b/InvenTree/InvenTree/static/select2/js/i18n/de.js new file mode 100644 index 0000000000..c2e61e5800 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/de.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){return"Bitte "+(e.input.length-e.maximum)+" Zeichen weniger eingeben"},inputTooShort:function(e){return"Bitte "+(e.minimum-e.input.length)+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var n="Sie können nur "+e.maximum+" Element";return 1!=e.maximum&&(n+="e"),n+=" auswählen"},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Elemente"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/dsb.js b/InvenTree/InvenTree/static/select2/js/i18n/dsb.js new file mode 100644 index 0000000000..02f283abad --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/dsb.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/dsb",[],function(){var n=["znamuško","znamušce","znamuška","znamuškow"],e=["zapisk","zapiska","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Pšosym lašuj "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Pšosym zapódaj nanejmjenjej "+a+" "+u(a,n)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(n){return"Móžoš jano "+n.maximum+" "+u(n.maximum,e)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/el.js b/InvenTree/InvenTree/static/select2/js/i18n/el.js new file mode 100644 index 0000000000..d4922a1df5 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/el.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(n){var e=n.input.length-n.maximum,u="Παρακαλώ διαγράψτε "+e+" χαρακτήρ";return 1==e&&(u+="α"),1!=e&&(u+="ες"),u},inputTooShort:function(n){return"Παρακαλώ συμπληρώστε "+(n.minimum-n.input.length)+" ή περισσότερους χαρακτήρες"},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(n){var e="Μπορείτε να επιλέξετε μόνο "+n.maximum+" επιλογ";return 1==n.maximum&&(e+="ή"),1!=n.maximum&&(e+="ές"),e},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/en.js b/InvenTree/InvenTree/static/select2/js/i18n/en.js new file mode 100644 index 0000000000..3b19285734 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/en.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Please delete "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var n="You can only select "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/es.js b/InvenTree/InvenTree/static/select2/js/i18n/es.js new file mode 100644 index 0000000000..68afd6d259 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/es.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"No se pudieron cargar los resultados"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Por favor, elimine "+n+" car";return r+=1==n?"ácter":"acteres"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Por favor, introduzca "+n+" car";return r+=1==n?"ácter":"acteres"},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var n="Sólo puede seleccionar "+e.maximum+" elemento";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Eliminar todos los elementos"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/et.js b/InvenTree/InvenTree/static/select2/js/i18n/et.js new file mode 100644 index 0000000000..070b61a26d --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/et.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var n=e.input.length-e.maximum,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" vähem"},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" rohkem"},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var n="Saad vaid "+e.maximum+" tulemus";return 1==e.maximum?n+="e":n+="t",n+=" valida"},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"},removeAllItems:function(){return"Eemalda kõik esemed"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/eu.js b/InvenTree/InvenTree/static/select2/js/i18n/eu.js new file mode 100644 index 0000000000..90d5e73f8a --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/eu.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gutxiago"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gehiago"},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return 1===e.maximum?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"},removeAllItems:function(){return"Kendu elementu guztiak"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/fa.js b/InvenTree/InvenTree/static/select2/js/i18n/fa.js new file mode 100644 index 0000000000..e1ffdbed0d --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/fa.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(n){return"لطفاً "+(n.input.length-n.maximum)+" کاراکتر را حذف نمایید"},inputTooShort:function(n){return"لطفاً تعداد "+(n.minimum-n.input.length)+" کاراکتر یا بیشتر وارد نمایید"},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(n){return"شما تنها می‌توانید "+n.maximum+" آیتم را انتخاب نمایید"},noResults:function(){return"هیچ نتیجه‌ای یافت نشد"},searching:function(){return"در حال جستجو..."},removeAllItems:function(){return"همه موارد را حذف کنید"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/fi.js b/InvenTree/InvenTree/static/select2/js/i18n/fi.js new file mode 100644 index 0000000000..ffed1247dd --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/fi.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(n){return"Ole hyvä ja anna "+(n.input.length-n.maximum)+" merkkiä vähemmän"},inputTooShort:function(n){return"Ole hyvä ja anna "+(n.minimum-n.input.length)+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(n){return"Voit valita ainoastaan "+n.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"},removeAllItems:function(){return"Poista kaikki kohteet"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/fr.js b/InvenTree/InvenTree/static/select2/js/i18n/fr.js new file mode 100644 index 0000000000..dd02f973ff --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/fr.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var n=e.input.length-e.maximum;return"Supprimez "+n+" caractère"+(n>1?"s":"")},inputTooShort:function(e){var n=e.minimum-e.input.length;return"Saisissez au moins "+n+" caractère"+(n>1?"s":"")},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){return"Vous pouvez seulement sélectionner "+e.maximum+" élément"+(e.maximum>1?"s":"")},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"},removeAllItems:function(){return"Supprimer tous les éléments"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/gl.js b/InvenTree/InvenTree/static/select2/js/i18n/gl.js new file mode 100644 index 0000000000..208a005705 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/gl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/gl",[],function(){return{errorLoading:function(){return"Non foi posíbel cargar os resultados."},inputTooLong:function(e){var n=e.input.length-e.maximum;return 1===n?"Elimine un carácter":"Elimine "+n+" caracteres"},inputTooShort:function(e){var n=e.minimum-e.input.length;return 1===n?"Engada un carácter":"Engada "+n+" caracteres"},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){return 1===e.maximum?"Só pode seleccionar un elemento":"Só pode seleccionar "+e.maximum+" elementos"},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Elimina todos os elementos"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/he.js b/InvenTree/InvenTree/static/select2/js/i18n/he.js new file mode 100644 index 0000000000..25a8805aa0 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/he.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="נא למחוק ";return r+=1===e?"תו אחד":e+" תווים"},inputTooShort:function(n){var e=n.minimum-n.input.length,r="נא להכניס ";return r+=1===e?"תו אחד":e+" תווים",r+=" או יותר"},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(n){var e="באפשרותך לבחור עד ";return 1===n.maximum?e+="פריט אחד":e+=n.maximum+" פריטים",e},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"},removeAllItems:function(){return"הסר את כל הפריטים"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/hi.js b/InvenTree/InvenTree/static/select2/js/i18n/hi.js new file mode 100644 index 0000000000..f3ed798434 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/hi.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(n){var e=n.input.length-n.maximum,r=e+" अक्षर को हटा दें";return e>1&&(r=e+" अक्षरों को हटा दें "),r},inputTooShort:function(n){return"कृपया "+(n.minimum-n.input.length)+" या अधिक अक्षर दर्ज करें"},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(n){return"आप केवल "+n.maximum+" आइटम का चयन कर सकते हैं"},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."},removeAllItems:function(){return"सभी वस्तुओं को हटा दें"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/hr.js b/InvenTree/InvenTree/static/select2/js/i18n/hr.js new file mode 100644 index 0000000000..cb3268db16 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/hr.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hr",[],function(){function n(n){var e=" "+n+" znak";return n%10<5&&n%10>0&&(n%100<5||n%100>19)?n%10>1&&(e+="a"):e+="ova",e}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(e){return"Unesite "+n(e.input.length-e.maximum)},inputTooShort:function(e){return"Unesite još "+n(e.minimum-e.input.length)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(n){return"Maksimalan broj odabranih stavki je "+n.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Ukloni sve stavke"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/hsb.js b/InvenTree/InvenTree/static/select2/js/i18n/hsb.js new file mode 100644 index 0000000000..3d5bf09dbd --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/hsb.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hsb",[],function(){var n=["znamješko","znamješce","znamješka","znamješkow"],e=["zapisk","zapiskaj","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njedachu so začitać."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Prošu zhašej "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Prošu zapodaj znajmjeńša "+a+" "+u(a,n)},loadingMore:function(){return"Dalše wuslědki so začitaja…"},maximumSelected:function(n){return"Móžeš jenož "+n.maximum+" "+u(n.maximum,e)+"wubrać"},noResults:function(){return"Žane wuslědki namakane"},searching:function(){return"Pyta so…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/hu.js b/InvenTree/InvenTree/static/select2/js/i18n/hu.js new file mode 100644 index 0000000000..4893aa2f70 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/hu.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){return"Túl hosszú. "+(e.input.length-e.maximum)+" karakterrel több, mint kellene."},inputTooShort:function(e){return"Túl rövid. Még "+(e.minimum-e.input.length)+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"},removeAllItems:function(){return"Távolítson el minden elemet"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/hy.js b/InvenTree/InvenTree/static/select2/js/i18n/hy.js new file mode 100644 index 0000000000..8230007141 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/hy.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(n){return"Խնդրում ենք հեռացնել "+(n.input.length-n.maximum)+" նշան"},inputTooShort:function(n){return"Խնդրում ենք մուտքագրել "+(n.minimum-n.input.length)+" կամ ավել նշաններ"},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(n){return"Դուք կարող եք ընտրել առավելագույնը "+n.maximum+" կետ"},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"},removeAllItems:function(){return"Հեռացնել բոլոր տարրերը"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/id.js b/InvenTree/InvenTree/static/select2/js/i18n/id.js new file mode 100644 index 0000000000..4a0b3bf009 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/id.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(n){return"Hapuskan "+(n.input.length-n.maximum)+" huruf"},inputTooShort:function(n){return"Masukkan "+(n.minimum-n.input.length)+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(n){return"Anda hanya dapat memilih "+n.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Hapus semua item"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/is.js b/InvenTree/InvenTree/static/select2/js/i18n/is.js new file mode 100644 index 0000000000..cca5bbecf0 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/is.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/is",[],function(){return{inputTooLong:function(n){var t=n.input.length-n.maximum,e="Vinsamlegast styttið texta um "+t+" staf";return t<=1?e:e+"i"},inputTooShort:function(n){var t=n.minimum-n.input.length,e="Vinsamlegast skrifið "+t+" staf";return t>1&&(e+="i"),e+=" í viðbót"},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(n){return"Þú getur aðeins valið "+n.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"},removeAllItems:function(){return"Fjarlægðu öll atriði"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/it.js b/InvenTree/InvenTree/static/select2/js/i18n/it.js new file mode 100644 index 0000000000..507c7d9f29 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/it.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Per favore cancella "+n+" caratter";return t+=1!==n?"i":"e"},inputTooShort:function(e){return"Per favore inserisci "+(e.minimum-e.input.length)+" o più caratteri"},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var n="Puoi selezionare solo "+e.maximum+" element";return 1!==e.maximum?n+="i":n+="o",n},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"},removeAllItems:function(){return"Rimuovi tutti gli oggetti"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ja.js b/InvenTree/InvenTree/static/select2/js/i18n/ja.js new file mode 100644 index 0000000000..451025e2c7 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ja.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(n){return n.input.length-n.maximum+" 文字を削除してください"},inputTooShort:function(n){return"少なくとも "+(n.minimum-n.input.length)+" 文字を入力してください"},loadingMore:function(){return"読み込み中…"},maximumSelected:function(n){return n.maximum+" 件しか選択できません"},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"},removeAllItems:function(){return"すべてのアイテムを削除"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ka.js b/InvenTree/InvenTree/static/select2/js/i18n/ka.js new file mode 100644 index 0000000000..60c593b705 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ka.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ka",[],function(){return{errorLoading:function(){return"მონაცემების ჩატვირთვა შეუძლებელია."},inputTooLong:function(n){return"გთხოვთ აკრიფეთ "+(n.input.length-n.maximum)+" სიმბოლოთი ნაკლები"},inputTooShort:function(n){return"გთხოვთ აკრიფეთ "+(n.minimum-n.input.length)+" სიმბოლო ან მეტი"},loadingMore:function(){return"მონაცემების ჩატვირთვა…"},maximumSelected:function(n){return"თქვენ შეგიძლიათ აირჩიოთ არაუმეტეს "+n.maximum+" ელემენტი"},noResults:function(){return"რეზულტატი არ მოიძებნა"},searching:function(){return"ძიება…"},removeAllItems:function(){return"ამოიღე ყველა ელემენტი"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/km.js b/InvenTree/InvenTree/static/select2/js/i18n/km.js new file mode 100644 index 0000000000..4dca94f414 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/km.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(n){return"សូមលុបចេញ "+(n.input.length-n.maximum)+" អក្សរ"},inputTooShort:function(n){return"សូមបញ្ចូល"+(n.minimum-n.input.length)+" អក្សរ រឺ ច្រើនជាងនេះ"},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(n){return"អ្នកអាចជ្រើសរើសបានតែ "+n.maximum+" ជម្រើសប៉ុណ្ណោះ"},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."},removeAllItems:function(){return"លុបធាតុទាំងអស់"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ko.js b/InvenTree/InvenTree/static/select2/js/i18n/ko.js new file mode 100644 index 0000000000..f2880fb004 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ko.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(n){return"너무 깁니다. "+(n.input.length-n.maximum)+" 글자 지워주세요."},inputTooShort:function(n){return"너무 짧습니다. "+(n.minimum-n.input.length)+" 글자 더 입력해주세요."},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(n){return"최대 "+n.maximum+"개까지만 선택 가능합니다."},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"},removeAllItems:function(){return"모든 항목 삭제"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/lt.js b/InvenTree/InvenTree/static/select2/js/i18n/lt.js new file mode 100644 index 0000000000..f6a42155ad --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/lt.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/lt",[],function(){function n(n,e,i,t){return n%10==1&&(n%100<11||n%100>19)?e:n%10>=2&&n%10<=9&&(n%100<11||n%100>19)?i:t}return{inputTooLong:function(e){var i=e.input.length-e.maximum,t="Pašalinkite "+i+" simbol";return t+=n(i,"į","ius","ių")},inputTooShort:function(e){var i=e.minimum-e.input.length,t="Įrašykite dar "+i+" simbol";return t+=n(i,"į","ius","ių")},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(e){var i="Jūs galite pasirinkti tik "+e.maximum+" element";return i+=n(e.maximum,"ą","us","ų")},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"},removeAllItems:function(){return"Pašalinti visus elementus"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/lv.js b/InvenTree/InvenTree/static/select2/js/i18n/lv.js new file mode 100644 index 0000000000..806dc5c433 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/lv.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/lv",[],function(){function e(e,n,u,i){return 11===e?n:e%10==1?u:i}return{inputTooLong:function(n){var u=n.input.length-n.maximum,i="Lūdzu ievadiet par "+u;return(i+=" simbol"+e(u,"iem","u","iem"))+" mazāk"},inputTooShort:function(n){var u=n.minimum-n.input.length,i="Lūdzu ievadiet vēl "+u;return i+=" simbol"+e(u,"us","u","us")},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(n){var u="Jūs varat izvēlēties ne vairāk kā "+n.maximum;return u+=" element"+e(n.maximum,"us","u","us")},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"},removeAllItems:function(){return"Noņemt visus vienumus"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/mk.js b/InvenTree/InvenTree/static/select2/js/i18n/mk.js new file mode 100644 index 0000000000..cb7b84a263 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/mk.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/mk",[],function(){return{inputTooLong:function(n){var e=(n.input.length,n.maximum,"Ве молиме внесете "+n.maximum+" помалку карактер");return 1!==n.maximum&&(e+="и"),e},inputTooShort:function(n){var e=(n.minimum,n.input.length,"Ве молиме внесете уште "+n.maximum+" карактер");return 1!==n.maximum&&(e+="и"),e},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(n){var e="Можете да изберете само "+n.maximum+" ставк";return 1===n.maximum?e+="а":e+="и",e},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"},removeAllItems:function(){return"Отстрани ги сите предмети"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ms.js b/InvenTree/InvenTree/static/select2/js/i18n/ms.js new file mode 100644 index 0000000000..6bd7eaa3e0 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ms.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(n){return"Sila hapuskan "+(n.input.length-n.maximum)+" aksara"},inputTooShort:function(n){return"Sila masukkan "+(n.minimum-n.input.length)+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(n){return"Anda hanya boleh memilih "+n.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Keluarkan semua item"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/nb.js b/InvenTree/InvenTree/static/select2/js/i18n/nb.js new file mode 100644 index 0000000000..25d89c6870 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/nb.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){return"Vennligst fjern "+(e.input.length-e.maximum)+" tegn"},inputTooShort:function(e){return"Vennligst skriv inn "+(e.minimum-e.input.length)+" tegn til"},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ne.js b/InvenTree/InvenTree/static/select2/js/i18n/ne.js new file mode 100644 index 0000000000..1c39f67210 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ne.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ne",[],function(){return{errorLoading:function(){return"नतिजाहरु देखाउन सकिएन।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="कृपया "+e+" अक्षर मेटाउनुहोस्।";return 1!=e&&(u+="कृपया "+e+" अक्षरहरु मेटाउनुहोस्।"),u},inputTooShort:function(n){return"कृपया बाँकी रहेका "+(n.minimum-n.input.length)+" वा अरु धेरै अक्षरहरु भर्नुहोस्।"},loadingMore:function(){return"अरु नतिजाहरु भरिँदैछन् …"},maximumSelected:function(n){var e="तँपाई "+n.maximum+" वस्तु मात्र छान्न पाउँनुहुन्छ।";return 1!=n.maximum&&(e="तँपाई "+n.maximum+" वस्तुहरु मात्र छान्न पाउँनुहुन्छ।"),e},noResults:function(){return"कुनै पनि नतिजा भेटिएन।"},searching:function(){return"खोजि हुँदैछ…"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/nl.js b/InvenTree/InvenTree/static/select2/js/i18n/nl.js new file mode 100644 index 0000000000..2b74058d23 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/nl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){return"Gelieve "+(e.input.length-e.maximum)+" karakters te verwijderen"},inputTooShort:function(e){return"Gelieve "+(e.minimum-e.input.length)+" of meer karakters in te voeren"},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var n=1==e.maximum?"kan":"kunnen",r="Er "+n+" maar "+e.maximum+" item";return 1!=e.maximum&&(r+="s"),r+=" worden geselecteerd"},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"},removeAllItems:function(){return"Verwijder alle items"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/pl.js b/InvenTree/InvenTree/static/select2/js/i18n/pl.js new file mode 100644 index 0000000000..4ca5748c38 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/pl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/pl",[],function(){var n=["znak","znaki","znaków"],e=["element","elementy","elementów"],r=function(n,e){return 1===n?e[0]:n>1&&n<=4?e[1]:n>=5?e[2]:void 0};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Usuń "+t+" "+r(t,n)},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Podaj przynajmniej "+t+" "+r(t,n)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(n){return"Możesz zaznaczyć tylko "+n.maximum+" "+r(n.maximum,e)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"},removeAllItems:function(){return"Usuń wszystkie przedmioty"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ps.js b/InvenTree/InvenTree/static/select2/js/i18n/ps.js new file mode 100644 index 0000000000..9b008e4c14 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ps.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="د مهربانۍ لمخي "+e+" توری ړنګ کړئ";return 1!=e&&(r=r.replace("توری","توري")),r},inputTooShort:function(n){return"لږ تر لږه "+(n.minimum-n.input.length)+" يا ډېر توري وليکئ"},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(n){var e="تاسو يوازي "+n.maximum+" قلم په نښه کولای سی";return 1!=n.maximum&&(e=e.replace("قلم","قلمونه")),e},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."},removeAllItems:function(){return"ټول توکي لرې کړئ"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/pt-BR.js b/InvenTree/InvenTree/static/select2/js/i18n/pt-BR.js new file mode 100644 index 0000000000..c991e2550a --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/pt-BR.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Apague "+n+" caracter";return 1!=n&&(r+="es"),r},inputTooShort:function(e){return"Digite "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var n="Você só pode selecionar "+e.maximum+" ite";return 1==e.maximum?n+="m":n+="ns",n},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/pt.js b/InvenTree/InvenTree/static/select2/js/i18n/pt.js new file mode 100644 index 0000000000..b5da1a6b49 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/pt.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var r=e.input.length-e.maximum,n="Por favor apague "+r+" ";return n+=1!=r?"caracteres":"caractere"},inputTooShort:function(e){return"Introduza "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var r="Apenas pode seleccionar "+e.maximum+" ";return r+=1!=e.maximum?"itens":"item"},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ro.js b/InvenTree/InvenTree/static/select2/js/i18n/ro.js new file mode 100644 index 0000000000..1ba7b40bef --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ro.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return 1!==t&&(n+="e"),n},inputTooShort:function(e){return"Vă rugăm să introduceți "+(e.minimum-e.input.length)+" sau mai multe caractere"},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",1!==e.maximum&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"},removeAllItems:function(){return"Eliminați toate elementele"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/ru.js b/InvenTree/InvenTree/static/select2/js/i18n/ru.js new file mode 100644 index 0000000000..63a7d66c3b --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/ru.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ru",[],function(){function n(n,e,r,u){return n%10<5&&n%10>0&&n%100<5||n%100>20?n%10>1?r:e:u}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Пожалуйста, введите на "+r+" символ";return u+=n(r,"","a","ов"),u+=" меньше"},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Пожалуйста, введите ещё хотя бы "+r+" символ";return u+=n(r,"","a","ов")},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(e){var r="Вы можете выбрать не более "+e.maximum+" элемент";return r+=n(e.maximum,"","a","ов")},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"},removeAllItems:function(){return"Удалить все элементы"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/sk.js b/InvenTree/InvenTree/static/select2/js/i18n/sk.js new file mode 100644 index 0000000000..5049528ad0 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/sk.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{errorLoading:function(){return"Výsledky sa nepodarilo načítať."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadajte o jeden znak menej":t>=2&&t<=4?"Prosím, zadajte o "+e[t](!0)+" znaky menej":"Prosím, zadajte o "+t+" znakov menej"},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadajte ešte jeden znak":t<=4?"Prosím, zadajte ešte ďalšie "+e[t](!0)+" znaky":"Prosím, zadajte ešte ďalších "+t+" znakov"},loadingMore:function(){return"Načítanie ďalších výsledkov…"},maximumSelected:function(n){return 1==n.maximum?"Môžete zvoliť len jednu položku":n.maximum>=2&&n.maximum<=4?"Môžete zvoliť najviac "+e[n.maximum](!1)+" položky":"Môžete zvoliť najviac "+n.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"},removeAllItems:function(){return"Odstráňte všetky položky"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/sl.js b/InvenTree/InvenTree/static/select2/js/i18n/sl.js new file mode 100644 index 0000000000..4d0b7d3e34 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/sl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sl",[],function(){return{errorLoading:function(){return"Zadetkov iskanja ni bilo mogoče naložiti."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Prosim zbrišite "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Prosim vpišite še "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},loadingMore:function(){return"Nalagam več zadetkov…"},maximumSelected:function(e){var n="Označite lahko največ "+e.maximum+" predmet";return 2==e.maximum?n+="a":1!=e.maximum&&(n+="e"),n},noResults:function(){return"Ni zadetkov."},searching:function(){return"Iščem…"},removeAllItems:function(){return"Odstranite vse elemente"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/sq.js b/InvenTree/InvenTree/static/select2/js/i18n/sq.js new file mode 100644 index 0000000000..59162024ed --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/sq.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sq",[],function(){return{errorLoading:function(){return"Rezultatet nuk mund të ngarkoheshin."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Të lutem fshi "+n+" karakter";return 1!=n&&(t+="e"),t},inputTooShort:function(e){return"Të lutem shkruaj "+(e.minimum-e.input.length)+" ose më shumë karaktere"},loadingMore:function(){return"Duke ngarkuar më shumë rezultate…"},maximumSelected:function(e){var n="Mund të zgjedhësh vetëm "+e.maximum+" element";return 1!=e.maximum&&(n+="e"),n},noResults:function(){return"Nuk u gjet asnjë rezultat"},searching:function(){return"Duke kërkuar…"},removeAllItems:function(){return"Hiq të gjitha sendet"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/sr-Cyrl.js b/InvenTree/InvenTree/static/select2/js/i18n/sr-Cyrl.js new file mode 100644 index 0000000000..ce13ce8f9a --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/sr-Cyrl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr-Cyrl",[],function(){function n(n,e,r,u){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:u}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Обришите "+r+" симбол";return u+=n(r,"","а","а")},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Укуцајте бар још "+r+" симбол";return u+=n(r,"","а","а")},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(e){var r="Можете изабрати само "+e.maximum+" ставк";return r+=n(e.maximum,"у","е","и")},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/sr.js b/InvenTree/InvenTree/static/select2/js/i18n/sr.js new file mode 100644 index 0000000000..dd407a06dc --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/sr.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr",[],function(){function n(n,e,r,t){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(e){var r=e.input.length-e.maximum,t="Obrišite "+r+" simbol";return t+=n(r,"","a","a")},inputTooShort:function(e){var r=e.minimum-e.input.length,t="Ukucajte bar još "+r+" simbol";return t+=n(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(e){var r="Možete izabrati samo "+e.maximum+" stavk";return r+=n(e.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/sv.js b/InvenTree/InvenTree/static/select2/js/i18n/sv.js new file mode 100644 index 0000000000..1bc8724a79 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/sv.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(n){return"Vänligen sudda ut "+(n.input.length-n.maximum)+" tecken"},inputTooShort:function(n){return"Vänligen skriv in "+(n.minimum-n.input.length)+" eller fler tecken"},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(n){return"Du kan max välja "+n.maximum+" element"},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"},removeAllItems:function(){return"Ta bort alla objekt"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/th.js b/InvenTree/InvenTree/static/select2/js/i18n/th.js new file mode 100644 index 0000000000..63eab7114b --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/th.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/th",[],function(){return{errorLoading:function(){return"ไม่สามารถค้นข้อมูลได้"},inputTooLong:function(n){return"โปรดลบออก "+(n.input.length-n.maximum)+" ตัวอักษร"},inputTooShort:function(n){return"โปรดพิมพ์เพิ่มอีก "+(n.minimum-n.input.length)+" ตัวอักษร"},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(n){return"คุณสามารถเลือกได้ไม่เกิน "+n.maximum+" รายการ"},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"},removeAllItems:function(){return"ลบรายการทั้งหมด"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/tk.js b/InvenTree/InvenTree/static/select2/js/i18n/tk.js new file mode 100644 index 0000000000..30255ff377 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/tk.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/tk",[],function(){return{errorLoading:function(){return"Netije ýüklenmedi."},inputTooLong:function(e){return e.input.length-e.maximum+" harp bozuň."},inputTooShort:function(e){return"Ýene-de iň az "+(e.minimum-e.input.length)+" harp ýazyň."},loadingMore:function(){return"Köpräk netije görkezilýär…"},maximumSelected:function(e){return"Diňe "+e.maximum+" sanysyny saýlaň."},noResults:function(){return"Netije tapylmady."},searching:function(){return"Gözlenýär…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/tr.js b/InvenTree/InvenTree/static/select2/js/i18n/tr.js new file mode 100644 index 0000000000..fc4c0bf051 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/tr.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/tr",[],function(){return{errorLoading:function(){return"Sonuç yüklenemedi"},inputTooLong:function(n){return n.input.length-n.maximum+" karakter daha girmelisiniz"},inputTooShort:function(n){return"En az "+(n.minimum-n.input.length)+" karakter daha girmelisiniz"},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(n){return"Sadece "+n.maximum+" seçim yapabilirsiniz"},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"},removeAllItems:function(){return"Tüm öğeleri kaldır"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/uk.js b/InvenTree/InvenTree/static/select2/js/i18n/uk.js new file mode 100644 index 0000000000..63697e3884 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/uk.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/uk",[],function(){function n(n,e,u,r){return n%100>10&&n%100<15?r:n%10==1?e:n%10>1&&n%10<5?u:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(e){return"Будь ласка, видаліть "+(e.input.length-e.maximum)+" "+n(e.maximum,"літеру","літери","літер")},inputTooShort:function(n){return"Будь ласка, введіть "+(n.minimum-n.input.length)+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(e){return"Ви можете вибрати лише "+e.maximum+" "+n(e.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"},removeAllItems:function(){return"Видалити всі елементи"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/vi.js b/InvenTree/InvenTree/static/select2/js/i18n/vi.js new file mode 100644 index 0000000000..24f3bc2d61 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/vi.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/vi",[],function(){return{inputTooLong:function(n){return"Vui lòng xóa bớt "+(n.input.length-n.maximum)+" ký tự"},inputTooShort:function(n){return"Vui lòng nhập thêm từ "+(n.minimum-n.input.length)+" ký tự trở lên"},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(n){return"Chỉ có thể chọn được "+n.maximum+" lựa chọn"},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"},removeAllItems:function(){return"Xóa tất cả các mục"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/zh-CN.js b/InvenTree/InvenTree/static/select2/js/i18n/zh-CN.js new file mode 100644 index 0000000000..2c5649d310 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/zh-CN.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(n){return"请删除"+(n.input.length-n.maximum)+"个字符"},inputTooShort:function(n){return"请再输入至少"+(n.minimum-n.input.length)+"个字符"},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(n){return"最多只能选择"+n.maximum+"个项目"},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"},removeAllItems:function(){return"删除所有项目"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/select2/js/i18n/zh-TW.js b/InvenTree/InvenTree/static/select2/js/i18n/zh-TW.js new file mode 100644 index 0000000000..570a566937 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/i18n/zh-TW.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(n){return"請刪掉"+(n.input.length-n.maximum)+"個字元"},inputTooShort:function(n){return"請再輸入"+(n.minimum-n.input.length)+"個字元"},loadingMore:function(){return"載入中…"},maximumSelected:function(n){return"你只能選擇最多"+n.maximum+"項"},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"},removeAllItems:function(){return"刪除所有項目"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/InvenTree/InvenTree/static/script/select2/select2.full.js b/InvenTree/InvenTree/static/select2/js/select2.full.js similarity index 89% rename from InvenTree/InvenTree/static/script/select2/select2.full.js rename to InvenTree/InvenTree/static/select2/js/select2.full.js index 608642bf64..358572a657 100644 --- a/InvenTree/InvenTree/static/script/select2/select2.full.js +++ b/InvenTree/InvenTree/static/select2/js/select2.full.js @@ -1,11 +1,11 @@ /*! - * Select2 4.0.5 + * Select2 4.0.13 * https://select2.github.io * * Released under the MIT license * https://github.com/select2/select2/blob/master/LICENSE.md */ -(function (factory) { +;(function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); @@ -574,10 +574,10 @@ S2.define('select2/utils',[ DecoratedClass.prototype = new ctr(); for (var m = 0; m < superMethods.length; m++) { - var superMethod = superMethods[m]; + var superMethod = superMethods[m]; - DecoratedClass.prototype[superMethod] = - SuperClass.prototype[superMethod]; + DecoratedClass.prototype[superMethod] = + SuperClass.prototype[superMethod]; } var calledMethod = function (methodName) { @@ -772,6 +772,70 @@ S2.define('select2/utils',[ $element.append($nodes); }; + // Cache objects in Utils.__cache instead of $.data (see #4346) + Utils.__cache = {}; + + var id = 0; + Utils.GetUniqueElementId = function (element) { + // Get a unique element Id. If element has no id, + // creates a new unique number, stores it in the id + // attribute and returns the new id. + // If an id already exists, it simply returns it. + + var select2Id = element.getAttribute('data-select2-id'); + if (select2Id == null) { + // If element has id, use it. + if (element.id) { + select2Id = element.id; + element.setAttribute('data-select2-id', select2Id); + } else { + element.setAttribute('data-select2-id', ++id); + select2Id = id.toString(); + } + } + return select2Id; + }; + + Utils.StoreData = function (element, name, value) { + // Stores an item in the cache for a specified element. + // name is the cache key. + var id = Utils.GetUniqueElementId(element); + if (!Utils.__cache[id]) { + Utils.__cache[id] = {}; + } + + Utils.__cache[id][name] = value; + }; + + Utils.GetData = function (element, name) { + // Retrieves a value from the cache by its key (name) + // name is optional. If no name specified, return + // all cache items for the specified element. + // and for a specified element. + var id = Utils.GetUniqueElementId(element); + if (name) { + if (Utils.__cache[id]) { + if (Utils.__cache[id][name] != null) { + return Utils.__cache[id][name]; + } + return $(element).data(name); // Fallback to HTML5 data attribs. + } + return $(element).data(name); // Fallback to HTML5 data attribs. + } else { + return Utils.__cache[id]; + } + }; + + Utils.RemoveData = function (element) { + // Removes all cached items for a specified element. + var id = Utils.GetUniqueElementId(element); + if (Utils.__cache[id] != null) { + delete Utils.__cache[id]; + } + + element.removeAttribute('data-select2-id'); + }; + return Utils; }); @@ -791,7 +855,7 @@ S2.define('select2/results',[ Results.prototype.render = function () { var $results = $( - '
        ' + '
          ' ); if (this.options.get('multiple')) { @@ -814,7 +878,7 @@ S2.define('select2/results',[ this.hideLoading(); var $message = $( - '
        • ' ); @@ -907,7 +971,7 @@ S2.define('select2/results',[ $options.each(function () { var $option = $(this); - var item = $.data(this, 'data'); + var item = Utils.GetData(this, 'data'); // id needs to be converted to a string when comparing var id = '' + item.id; @@ -948,11 +1012,16 @@ S2.define('select2/results',[ option.className = 'select2-results__option'; var attrs = { - 'role': 'treeitem', + 'role': 'option', 'aria-selected': 'false' }; - if (data.disabled) { + var matches = window.Element.prototype.matches || + window.Element.prototype.msMatchesSelector || + window.Element.prototype.webkitMatchesSelector; + + if ((data.element != null && matches.call(data.element, ':disabled')) || + (data.element == null && data.disabled)) { delete attrs['aria-selected']; attrs['aria-disabled'] = 'true'; } @@ -1012,7 +1081,7 @@ S2.define('select2/results',[ this.template(data, option); } - $.data(option, 'data', data); + Utils.StoreData(option, 'data', data); return option; }; @@ -1053,7 +1122,10 @@ S2.define('select2/results',[ } self.setClasses(); - self.highlightFirstItem(); + + if (self.options.get('scrollAfterSelect')) { + self.highlightFirstItem(); + } }); container.on('unselect', function () { @@ -1062,7 +1134,10 @@ S2.define('select2/results',[ } self.setClasses(); - self.highlightFirstItem(); + + if (self.options.get('scrollAfterSelect')) { + self.highlightFirstItem(); + } }); container.on('open', function () { @@ -1098,7 +1173,7 @@ S2.define('select2/results',[ return; } - var data = $highlighted.data('data'); + var data = Utils.GetData($highlighted[0], 'data'); if ($highlighted.attr('aria-selected') == 'true') { self.trigger('close', {}); @@ -1116,8 +1191,9 @@ S2.define('select2/results',[ var currentIndex = $options.index($highlighted); - // If we are already at te top, don't move further - if (currentIndex === 0) { + // If we are already at the top, don't move further + // If no options, currentIndex will be -1 + if (currentIndex <= 0) { return; } @@ -1210,7 +1286,7 @@ S2.define('select2/results',[ function (evt) { var $this = $(this); - var data = $this.data('data'); + var data = Utils.GetData(this, 'data'); if ($this.attr('aria-selected') === 'true') { if (self.options.get('multiple')) { @@ -1233,7 +1309,7 @@ S2.define('select2/results',[ this.$results.on('mouseenter', '.select2-results__option[aria-selected]', function (evt) { - var data = $(this).data('data'); + var data = Utils.GetData(this, 'data'); self.getHighlightedResults() .removeClass('select2-results__option--highlighted'); @@ -1348,14 +1424,15 @@ S2.define('select2/selection/base',[ this._tabindex = 0; - if (this.$element.data('old-tabindex') != null) { - this._tabindex = this.$element.data('old-tabindex'); + if (Utils.GetData(this.$element[0], 'old-tabindex') != null) { + this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex'); } else if (this.$element.attr('tabindex') != null) { this._tabindex = this.$element.attr('tabindex'); } $selection.attr('title', this.$element.attr('title')); $selection.attr('tabindex', this._tabindex); + $selection.attr('aria-disabled', 'false'); this.$selection = $selection; @@ -1365,7 +1442,6 @@ S2.define('select2/selection/base',[ BaseSelection.prototype.bind = function (container, $container) { var self = this; - var id = container.id + '-container'; var resultsId = container.id + '-results'; this.container = container; @@ -1408,17 +1484,19 @@ S2.define('select2/selection/base',[ self.$selection.removeAttr('aria-activedescendant'); self.$selection.removeAttr('aria-owns'); - self.$selection.focus(); + self.$selection.trigger('focus'); self._detachCloseHandler(container); }); container.on('enable', function () { self.$selection.attr('tabindex', self._tabindex); + self.$selection.attr('aria-disabled', 'false'); }); container.on('disable', function () { self.$selection.attr('tabindex', '-1'); + self.$selection.attr('aria-disabled', 'true'); }); }; @@ -1441,7 +1519,6 @@ S2.define('select2/selection/base',[ }; BaseSelection.prototype._attachCloseHandler = function (container) { - var self = this; $(document.body).on('mousedown.select2.' + container.id, function (e) { var $target = $(e.target); @@ -1451,13 +1528,11 @@ S2.define('select2/selection/base',[ var $all = $('.select2.select2-container--open'); $all.each(function () { - var $this = $(this); - if (this == $select[0]) { return; } - var $element = $this.data('element'); + var $element = Utils.GetData(this, 'element'); $element.select2('close'); }); @@ -1481,6 +1556,27 @@ S2.define('select2/selection/base',[ throw new Error('The `update` method must be defined in child classes.'); }; + /** + * Helper method to abstract the "enabled" (not "disabled") state of this + * object. + * + * @return {true} if the instance is not disabled. + * @return {false} if the instance is disabled. + */ + BaseSelection.prototype.isEnabled = function () { + return !this.isDisabled(); + }; + + /** + * Helper method to abstract the "disabled" state of this object. + * + * @return {true} if the disabled option is true. + * @return {false} if the disabled option is false. + */ + BaseSelection.prototype.isDisabled = function () { + return this.options.get('disabled'); + }; + return BaseSelection; }); @@ -1518,7 +1614,10 @@ S2.define('select2/selection/single',[ var id = container.id + '-container'; - this.$selection.find('.select2-selection__rendered').attr('id', id); + this.$selection.find('.select2-selection__rendered') + .attr('id', id) + .attr('role', 'textbox') + .attr('aria-readonly', 'true'); this.$selection.attr('aria-labelledby', id); this.$selection.on('mousedown', function (evt) { @@ -1542,17 +1641,15 @@ S2.define('select2/selection/single',[ container.on('focus', function (evt) { if (!container.isOpen()) { - self.$selection.focus(); + self.$selection.trigger('focus'); } }); - - container.on('selection:update', function (params) { - self.update(params.data); - }); }; SingleSelection.prototype.clear = function () { - this.$selection.find('.select2-selection__rendered').empty(); + var $rendered = this.$selection.find('.select2-selection__rendered'); + $rendered.empty(); + $rendered.removeAttr('title'); // clear tooltip on empty }; SingleSelection.prototype.display = function (data, container) { @@ -1578,7 +1675,14 @@ S2.define('select2/selection/single',[ var formatted = this.display(selection, $rendered); $rendered.empty().append(formatted); - $rendered.prop('title', selection.title || selection.text); + + var title = selection.title || selection.text; + + if (title) { + $rendered.attr('title', title); + } else { + $rendered.removeAttr('title'); + } }; return SingleSelection; @@ -1623,14 +1727,14 @@ S2.define('select2/selection/multiple',[ '.select2-selection__choice__remove', function (evt) { // Ignore the event if it is disabled - if (self.options.get('disabled')) { + if (self.isDisabled()) { return; } var $remove = $(this); var $selection = $remove.parent(); - var data = $selection.data('data'); + var data = Utils.GetData($selection[0], 'data'); self.trigger('unselect', { originalEvent: evt, @@ -1641,7 +1745,9 @@ S2.define('select2/selection/multiple',[ }; MultipleSelection.prototype.clear = function () { - this.$selection.find('.select2-selection__rendered').empty(); + var $rendered = this.$selection.find('.select2-selection__rendered'); + $rendered.empty(); + $rendered.removeAttr('title'); }; MultipleSelection.prototype.display = function (data, container) { @@ -1679,9 +1785,14 @@ S2.define('select2/selection/multiple',[ var formatted = this.display(selection, $selection); $selection.append(formatted); - $selection.prop('title', selection.title || selection.text); - $selection.data('data', selection); + var title = selection.title || selection.text; + + if (title) { + $selection.attr('title', title); + } + + Utils.StoreData($selection[0], 'data', selection); $selections.push($selection); } @@ -1746,8 +1857,9 @@ S2.define('select2/selection/placeholder',[ S2.define('select2/selection/allowClear',[ 'jquery', - '../keys' -], function ($, KEYS) { + '../keys', + '../utils' +], function ($, KEYS, Utils) { function AllowClear () { } AllowClear.prototype.bind = function (decorated, container, $container) { @@ -1776,7 +1888,7 @@ S2.define('select2/selection/allowClear',[ AllowClear.prototype._handleClear = function (_, evt) { // Ignore the event if it is disabled - if (this.options.get('disabled')) { + if (this.isDisabled()) { return; } @@ -1789,10 +1901,22 @@ S2.define('select2/selection/allowClear',[ evt.stopPropagation(); - var data = $clear.data('data'); + var data = Utils.GetData($clear[0], 'data'); + + var previousVal = this.$element.val(); + this.$element.val(this.placeholder.id); + + var unselectData = { + data: data + }; + this.trigger('clear', unselectData); + if (unselectData.prevented) { + this.$element.val(previousVal); + return; + } for (var d = 0; d < data.length; d++) { - var unselectData = { + unselectData = { data: data[d] }; @@ -1802,11 +1926,12 @@ S2.define('select2/selection/allowClear',[ // If the event was prevented, don't clear it out. if (unselectData.prevented) { + this.$element.val(previousVal); return; } } - this.$element.val(this.placeholder.id).trigger('change'); + this.$element.trigger('input').trigger('change'); this.trigger('toggle', {}); }; @@ -1829,12 +1954,14 @@ S2.define('select2/selection/allowClear',[ return; } + var removeAll = this.options.get('translations').get('removeAllItems'); + var $remove = $( - '' + + '' + '×' + '' ); - $remove.data('data', data); + Utils.StoreData($remove[0], 'data', data); this.$selection.find('.select2-selection__rendered').prepend($remove); }; @@ -1856,7 +1983,7 @@ S2.define('select2/selection/search',[ '' ); @@ -1873,14 +2000,18 @@ S2.define('select2/selection/search',[ Search.prototype.bind = function (decorated, container, $container) { var self = this; + var resultsId = container.id + '-results'; + decorated.call(this, container, $container); container.on('open', function () { + self.$search.attr('aria-controls', resultsId); self.$search.trigger('focus'); }); container.on('close', function () { self.$search.val(''); + self.$search.removeAttr('aria-controls'); self.$search.removeAttr('aria-activedescendant'); self.$search.trigger('focus'); }); @@ -1900,7 +2031,11 @@ S2.define('select2/selection/search',[ }); container.on('results:focus', function (params) { - self.$search.attr('aria-activedescendant', params.id); + if (params.data._resultId) { + self.$search.attr('aria-activedescendant', params.data._resultId); + } else { + self.$search.removeAttr('aria-activedescendant'); + } }); this.$selection.on('focusin', '.select2-search--inline', function (evt) { @@ -1925,7 +2060,7 @@ S2.define('select2/selection/search',[ .prev('.select2-selection__choice'); if ($previousChoice.length > 0) { - var item = $previousChoice.data('data'); + var item = Utils.GetData($previousChoice[0], 'data'); self.searchRemoveChoice(item); @@ -1934,6 +2069,12 @@ S2.define('select2/selection/search',[ } }); + this.$selection.on('click', '.select2-search--inline', function (evt) { + if (self.$search.val()) { + evt.stopPropagation(); + } + }); + // Try to detect the IE version should the `documentMode` property that // is stored on the document. This is only implemented in IE and is // slightly cleaner than doing a user agent check. @@ -2019,7 +2160,7 @@ S2.define('select2/selection/search',[ this.resizeSearch(); if (searchHadFocus) { - this.$search.focus(); + this.$search.trigger('focus'); } }; @@ -2052,7 +2193,7 @@ S2.define('select2/selection/search',[ var width = ''; if (this.$search.attr('placeholder') !== '') { - width = this.$selection.find('.select2-selection__rendered').innerWidth(); + width = this.$selection.find('.select2-selection__rendered').width(); } else { var minimumWidth = this.$search.val().length + 1; @@ -2076,10 +2217,13 @@ S2.define('select2/selection/eventRelay',[ 'open', 'opening', 'close', 'closing', 'select', 'selecting', - 'unselect', 'unselecting' + 'unselect', 'unselecting', + 'clear', 'clearing' ]; - var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting']; + var preventableEvents = [ + 'opening', 'closing', 'selecting', 'unselecting', 'clearing' + ]; decorated.call(this, container, $container); @@ -2412,6 +2556,7 @@ S2.define('select2/diacritics',[ '\u019F': 'O', '\uA74A': 'O', '\uA74C': 'O', + '\u0152': 'OE', '\u01A2': 'OI', '\uA74E': 'OO', '\u0222': 'OU', @@ -2821,6 +2966,7 @@ S2.define('select2/diacritics',[ '\uA74B': 'o', '\uA74D': 'o', '\u0275': 'o', + '\u0153': 'oe', '\u01A3': 'oi', '\u0223': 'ou', '\uA74F': 'oo', @@ -2989,8 +3135,9 @@ S2.define('select2/diacritics',[ '\u03CD': '\u03C5', '\u03CB': '\u03C5', '\u03B0': '\u03C5', - '\u03C9': '\u03C9', - '\u03C2': '\u03C3' + '\u03CE': '\u03C9', + '\u03C2': '\u03C3', + '\u2019': '\'' }; return diacritics; @@ -3075,7 +3222,7 @@ S2.define('select2/data/select',[ if ($(data.element).is('option')) { data.element.selected = true; - this.$element.trigger('change'); + this.$element.trigger('input').trigger('change'); return; } @@ -3096,13 +3243,13 @@ S2.define('select2/data/select',[ } self.$element.val(val); - self.$element.trigger('change'); + self.$element.trigger('input').trigger('change'); }); } else { var val = data.id; this.$element.val(val); - this.$element.trigger('change'); + this.$element.trigger('input').trigger('change'); } }; @@ -3118,7 +3265,7 @@ S2.define('select2/data/select',[ if ($(data.element).is('option')) { data.element.selected = false; - this.$element.trigger('change'); + this.$element.trigger('input').trigger('change'); return; } @@ -3136,7 +3283,7 @@ S2.define('select2/data/select',[ self.$element.val(val); - self.$element.trigger('change'); + self.$element.trigger('input').trigger('change'); }); }; @@ -3158,7 +3305,7 @@ S2.define('select2/data/select',[ // Remove anything added to child elements this.$element.find('*').each(function () { // Remove any custom data set by Select2 - $.removeData(this, 'data'); + Utils.RemoveData(this); }); }; @@ -3231,7 +3378,7 @@ S2.define('select2/data/select',[ normalizedData.element = option; // Override the option's data with the combined data - $.data(option, 'data', normalizedData); + Utils.StoreData(option, 'data', normalizedData); return $option; }; @@ -3239,7 +3386,7 @@ S2.define('select2/data/select',[ SelectAdapter.prototype.item = function ($option) { var data = {}; - data = $.data($option[0], 'data'); + data = Utils.GetData($option[0], 'data'); if (data != null) { return data; @@ -3277,13 +3424,13 @@ S2.define('select2/data/select',[ data = this._normalizeItem(data); data.element = $option[0]; - $.data($option[0], 'data', data); + Utils.StoreData($option[0], 'data', data); return data; }; SelectAdapter.prototype._normalizeItem = function (item) { - if (!$.isPlainObject(item)) { + if (item !== Object(item)) { item = { id: item, text: item @@ -3329,15 +3476,19 @@ S2.define('select2/data/array',[ 'jquery' ], function (SelectAdapter, Utils, $) { function ArrayAdapter ($element, options) { - var data = options.get('data') || []; + this._dataToConvert = options.get('data') || []; ArrayAdapter.__super__.constructor.call(this, $element, options); - - this.addOptions(this.convertToOptions(data)); } Utils.Extend(ArrayAdapter, SelectAdapter); + ArrayAdapter.prototype.bind = function (container, $container) { + ArrayAdapter.__super__.bind.call(this, container, $container); + + this.addOptions(this.convertToOptions(this._dataToConvert)); + }; + ArrayAdapter.prototype.select = function (data) { var $option = this.$element.find('option').filter(function (i, elm) { return elm.value == data.id.toString(); @@ -3487,7 +3638,8 @@ S2.define('select2/data/ajax',[ }, function () { // Attempt to detect if a request was aborted // Only works if the transport exposes a status property - if ($request.status && $request.status === '0') { + if ('status' in $request && + ($request.status === 0 || $request.status === '0')) { return; } @@ -3626,8 +3778,6 @@ S2.define('select2/data/tags',[ }; Tags.prototype._removeOldTags = function (_) { - var tag = this._lastTag; - var $options = this.$element.find('option[data-select2-tag]'); $options.each(function () { @@ -3702,7 +3852,7 @@ S2.define('select2/data/tokenizer',[ // Replace the search term if we have the search box if (this.$search.length) { this.$search.val(tokenData.term); - this.$search.focus(); + this.$search.trigger('focus'); } params.term = tokenData.term; @@ -3831,10 +3981,30 @@ S2.define('select2/data/maximumSelectionLength',[ decorated.call(this, $e, options); } + MaximumSelectionLength.prototype.bind = + function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('select', function () { + self._checkIfMaximumSelected(); + }); + }; + MaximumSelectionLength.prototype.query = function (decorated, params, callback) { var self = this; + this._checkIfMaximumSelected(function () { + decorated.call(self, params, callback); + }); + }; + + MaximumSelectionLength.prototype._checkIfMaximumSelected = + function (_, successCallback) { + var self = this; + this.current(function (currentData) { var count = currentData != null ? currentData.length : 0; if (self.maximumSelectionLength > 0 && @@ -3847,7 +4017,10 @@ S2.define('select2/data/maximumSelectionLength',[ }); return; } - decorated.call(self, params, callback); + + if (successCallback) { + successCallback(); + } }); }; @@ -3886,7 +4059,7 @@ S2.define('select2/dropdown',[ }; Dropdown.prototype.position = function ($dropdown, $container) { - // Should be implmented in subclasses + // Should be implemented in subclasses }; Dropdown.prototype.destroy = function () { @@ -3910,7 +4083,7 @@ S2.define('select2/dropdown/search',[ '' + '' + + ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' + '' ); @@ -3925,6 +4098,8 @@ S2.define('select2/dropdown/search',[ Search.prototype.bind = function (decorated, container, $container) { var self = this; + var resultsId = container.id + '-results'; + decorated.call(this, container, $container); this.$search.on('keydown', function (evt) { @@ -3947,23 +4122,27 @@ S2.define('select2/dropdown/search',[ container.on('open', function () { self.$search.attr('tabindex', 0); + self.$search.attr('aria-controls', resultsId); - self.$search.focus(); + self.$search.trigger('focus'); window.setTimeout(function () { - self.$search.focus(); + self.$search.trigger('focus'); }, 0); }); container.on('close', function () { self.$search.attr('tabindex', -1); + self.$search.removeAttr('aria-controls'); + self.$search.removeAttr('aria-activedescendant'); self.$search.val(''); + self.$search.trigger('blur'); }); container.on('focus', function () { if (!container.isOpen()) { - self.$search.focus(); + self.$search.trigger('focus'); } }); @@ -3978,6 +4157,14 @@ S2.define('select2/dropdown/search',[ } } }); + + container.on('results:focus', function (params) { + if (params.data._resultId) { + self.$search.attr('aria-activedescendant', params.data._resultId); + } else { + self.$search.removeAttr('aria-activedescendant'); + } + }); }; Search.prototype.handleSearch = function (evt) { @@ -4062,6 +4249,7 @@ S2.define('select2/dropdown/infiniteScroll',[ if (this.showLoadingMore(data)) { this.$results.append(this.$loadingMore); + this.loadMoreIfNeeded(); } }; @@ -4080,25 +4268,27 @@ S2.define('select2/dropdown/infiniteScroll',[ self.loading = true; }); - this.$results.on('scroll', function () { - var isLoadMoreVisible = $.contains( - document.documentElement, - self.$loadingMore[0] - ); + this.$results.on('scroll', this.loadMoreIfNeeded.bind(this)); + }; - if (self.loading || !isLoadMoreVisible) { - return; - } + InfiniteScroll.prototype.loadMoreIfNeeded = function () { + var isLoadMoreVisible = $.contains( + document.documentElement, + this.$loadingMore[0] + ); - var currentOffset = self.$results.offset().top + - self.$results.outerHeight(false); - var loadingMoreOffset = self.$loadingMore.offset().top + - self.$loadingMore.outerHeight(false); + if (this.loading || !isLoadMoreVisible) { + return; + } - if (currentOffset + 50 >= loadingMoreOffset) { - self.loadMore(); - } - }); + var currentOffset = this.$results.offset().top + + this.$results.outerHeight(false); + var loadingMoreOffset = this.$loadingMore.offset().top + + this.$loadingMore.outerHeight(false); + + if (currentOffset + 50 >= loadingMoreOffset) { + this.loadMore(); + } }; InfiniteScroll.prototype.loadMore = function () { @@ -4119,7 +4309,7 @@ S2.define('select2/dropdown/infiniteScroll',[ var $option = $( '
        • ' + 'role="option" aria-disabled="true">' ); var message = this.options.get('translations').get('loadingMore'); @@ -4137,7 +4327,7 @@ S2.define('select2/dropdown/attachBody',[ '../utils' ], function ($, Utils) { function AttachBody (decorated, $element, options) { - this.$dropdownParent = options.get('dropdownParent') || $(document.body); + this.$dropdownParent = $(options.get('dropdownParent') || document.body); decorated.call(this, $element, options); } @@ -4145,27 +4335,14 @@ S2.define('select2/dropdown/attachBody',[ AttachBody.prototype.bind = function (decorated, container, $container) { var self = this; - var setupResultsEvents = false; - decorated.call(this, container, $container); container.on('open', function () { self._showDropdown(); self._attachPositioningHandler(container); - if (!setupResultsEvents) { - setupResultsEvents = true; - - container.on('results:all', function () { - self._positionDropdown(); - self._resizeDropdown(); - }); - - container.on('results:append', function () { - self._positionDropdown(); - self._resizeDropdown(); - }); - } + // Must bind after the results handlers to ensure correct sizing + self._bindContainerResultHandlers(container); }); container.on('close', function () { @@ -4214,6 +4391,44 @@ S2.define('select2/dropdown/attachBody',[ this.$dropdownContainer.detach(); }; + AttachBody.prototype._bindContainerResultHandlers = + function (decorated, container) { + + // These should only be bound once + if (this._containerResultsHandlersBound) { + return; + } + + var self = this; + + container.on('results:all', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('results:append', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('results:message', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('select', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('unselect', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + this._containerResultsHandlersBound = true; + }; + AttachBody.prototype._attachPositioningHandler = function (decorated, container) { var self = this; @@ -4224,14 +4439,14 @@ S2.define('select2/dropdown/attachBody',[ var $watchers = this.$container.parents().filter(Utils.hasScroll); $watchers.each(function () { - $(this).data('select2-scroll-position', { + Utils.StoreData(this, 'select2-scroll-position', { x: $(this).scrollLeft(), y: $(this).scrollTop() }); }); $watchers.on(scrollEvent, function (ev) { - var position = $(this).data('select2-scroll-position'); + var position = Utils.GetData(this, 'select2-scroll-position'); $(this).scrollTop(position.y); }); @@ -4290,16 +4505,26 @@ S2.define('select2/dropdown/attachBody',[ top: container.bottom }; - // Determine what the parent element is to use for calciulating the offset + // Determine what the parent element is to use for calculating the offset var $offsetParent = this.$dropdownParent; - // For statically positoned elements, we need to get the element + // For statically positioned elements, we need to get the element // that is determining the offset if ($offsetParent.css('position') === 'static') { $offsetParent = $offsetParent.offsetParent(); } - var parentOffset = $offsetParent.offset(); + var parentOffset = { + top: 0, + left: 0 + }; + + if ( + $.contains(document.body, $offsetParent[0]) || + $offsetParent[0].isConnected + ) { + parentOffset = $offsetParent.offset(); + } css.top -= parentOffset.top; css.left -= parentOffset.left; @@ -4396,8 +4621,8 @@ S2.define('select2/dropdown/minimumResultsForSearch',[ }); S2.define('select2/dropdown/selectOnClose',[ - -], function () { + '../utils' +], function (Utils) { function SelectOnClose () { } SelectOnClose.prototype.bind = function (decorated, container, $container) { @@ -4428,7 +4653,7 @@ S2.define('select2/dropdown/selectOnClose',[ return; } - var data = $highlightedResults.data('data'); + var data = Utils.GetData($highlightedResults[0], 'data'); // Don't re-select already selected resulte if ( @@ -4469,7 +4694,7 @@ S2.define('select2/dropdown/closeOnSelect',[ var originalEvent = evt.originalEvent; // Don't close if the control key is being held - if (originalEvent && originalEvent.ctrlKey) { + if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) { return; } @@ -4523,6 +4748,9 @@ S2.define('select2/i18n/en',[],function () { }, searching: function () { return 'Searching…'; + }, + removeAllItems: function () { + return 'Remove all items'; } }; }); @@ -4761,66 +4989,29 @@ S2.define('select2/defaults',[ ); } - if (typeof options.language === 'string') { - // Check if the language is specified with a region - if (options.language.indexOf('-') > 0) { - // Extract the region information if it is included - var languageParts = options.language.split('-'); - var baseLanguage = languageParts[0]; + // If the defaults were not previously applied from an element, it is + // possible for the language option to have not been resolved + options.language = this._resolveLanguage(options.language); - options.language = [options.language, baseLanguage]; - } else { - options.language = [options.language]; + // Always fall back to English since it will always be complete + options.language.push('en'); + + var uniqueLanguages = []; + + for (var l = 0; l < options.language.length; l++) { + var language = options.language[l]; + + if (uniqueLanguages.indexOf(language) === -1) { + uniqueLanguages.push(language); } } - if ($.isArray(options.language)) { - var languages = new Translation(); - options.language.push('en'); + options.language = uniqueLanguages; - var languageNames = options.language; - - for (var l = 0; l < languageNames.length; l++) { - var name = languageNames[l]; - var language = {}; - - try { - // Try to load it with the original name - language = Translation.loadPath(name); - } catch (e) { - try { - // If we couldn't load it, check if it wasn't the full path - name = this.defaults.amdLanguageBase + name; - language = Translation.loadPath(name); - } catch (ex) { - // The translation could not be loaded at all. Sometimes this is - // because of a configuration problem, other times this can be - // because of how Select2 helps load all possible translation files. - if (options.debug && window.console && console.warn) { - console.warn( - 'Select2: The language file for "' + name + '" could not be ' + - 'automatically loaded. A fallback will be used instead.' - ); - } - - continue; - } - } - - languages.extend(language); - } - - options.translations = languages; - } else { - var baseTranslation = Translation.loadPath( - this.defaults.amdLanguageBase + 'en' - ); - var customTranslation = new Translation(options.language); - - customTranslation.extend(baseTranslation); - - options.translations = customTranslation; - } + options.translations = this._processTranslations( + options.language, + options.debug + ); return options; }; @@ -4887,13 +5078,14 @@ S2.define('select2/defaults',[ debug: false, dropdownAutoWidth: false, escapeMarkup: Utils.escapeMarkup, - language: EnglishTranslation, + language: {}, matcher: matcher, minimumInputLength: 0, maximumInputLength: 0, maximumSelectionLength: 0, minimumResultsForSearch: 0, selectOnClose: false, + scrollAfterSelect: false, sorter: function (data) { return data; }, @@ -4908,6 +5100,103 @@ S2.define('select2/defaults',[ }; }; + Defaults.prototype.applyFromElement = function (options, $element) { + var optionLanguage = options.language; + var defaultLanguage = this.defaults.language; + var elementLanguage = $element.prop('lang'); + var parentLanguage = $element.closest('[lang]').prop('lang'); + + var languages = Array.prototype.concat.call( + this._resolveLanguage(elementLanguage), + this._resolveLanguage(optionLanguage), + this._resolveLanguage(defaultLanguage), + this._resolveLanguage(parentLanguage) + ); + + options.language = languages; + + return options; + }; + + Defaults.prototype._resolveLanguage = function (language) { + if (!language) { + return []; + } + + if ($.isEmptyObject(language)) { + return []; + } + + if ($.isPlainObject(language)) { + return [language]; + } + + var languages; + + if (!$.isArray(language)) { + languages = [language]; + } else { + languages = language; + } + + var resolvedLanguages = []; + + for (var l = 0; l < languages.length; l++) { + resolvedLanguages.push(languages[l]); + + if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) { + // Extract the region information if it is included + var languageParts = languages[l].split('-'); + var baseLanguage = languageParts[0]; + + resolvedLanguages.push(baseLanguage); + } + } + + return resolvedLanguages; + }; + + Defaults.prototype._processTranslations = function (languages, debug) { + var translations = new Translation(); + + for (var l = 0; l < languages.length; l++) { + var languageData = new Translation(); + + var language = languages[l]; + + if (typeof language === 'string') { + try { + // Try to load it with the original name + languageData = Translation.loadPath(language); + } catch (e) { + try { + // If we couldn't load it, check if it wasn't the full path + language = this.defaults.amdLanguageBase + language; + languageData = Translation.loadPath(language); + } catch (ex) { + // The translation could not be loaded at all. Sometimes this is + // because of a configuration problem, other times this can be + // because of how Select2 helps load all possible translation files + if (debug && window.console && console.warn) { + console.warn( + 'Select2: The language file for "' + language + '" could ' + + 'not be automatically loaded. A fallback will be used instead.' + ); + } + } + } + } else if ($.isPlainObject(language)) { + languageData = new Translation(language); + } else { + languageData = language; + } + + translations.extend(languageData); + } + + return translations; + }; + Defaults.prototype.set = function (key, value) { var camelKey = $.camelCase(key); @@ -4916,7 +5205,7 @@ S2.define('select2/defaults',[ var convertedData = Utils._convertData(data); - $.extend(this.defaults, convertedData); + $.extend(true, this.defaults, convertedData); }; var defaults = new Defaults(); @@ -4937,6 +5226,10 @@ S2.define('select2/options',[ this.fromElement($element); } + if ($element != null) { + this.options = Defaults.applyFromElement(this.options, $element); + } + this.options = Defaults.apply(this.options); if ($element && $element.is('input')) { @@ -4960,14 +5253,6 @@ S2.define('select2/options',[ this.options.disabled = $e.prop('disabled'); } - if (this.options.language == null) { - if ($e.prop('lang')) { - this.options.language = $e.prop('lang').toLowerCase(); - } else if ($e.closest('[lang]').prop('lang')) { - this.options.language = $e.closest('[lang]').prop('lang'); - } - } - if (this.options.dir == null) { if ($e.prop('dir')) { this.options.dir = $e.prop('dir'); @@ -4981,7 +5266,7 @@ S2.define('select2/options',[ $e.prop('disabled', this.options.disabled); $e.prop('multiple', this.options.multiple); - if ($e.data('select2Tags')) { + if (Utils.GetData($e[0], 'select2Tags')) { if (this.options.debug && window.console && console.warn) { console.warn( 'Select2: The `data-select2-tags` attribute has been changed to ' + @@ -4990,11 +5275,11 @@ S2.define('select2/options',[ ); } - $e.data('data', $e.data('select2Tags')); - $e.data('tags', true); + Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags')); + Utils.StoreData($e[0], 'tags', true); } - if ($e.data('ajaxUrl')) { + if (Utils.GetData($e[0], 'ajaxUrl')) { if (this.options.debug && window.console && console.warn) { console.warn( 'Select2: The `data-ajax-url` attribute has been changed to ' + @@ -5003,21 +5288,45 @@ S2.define('select2/options',[ ); } - $e.attr('ajax--url', $e.data('ajaxUrl')); - $e.data('ajax--url', $e.data('ajaxUrl')); + $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl')); + Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl')); } var dataset = {}; + function upperCaseLetter(_, letter) { + return letter.toUpperCase(); + } + + // Pre-load all of the attributes which are prefixed with `data-` + for (var attr = 0; attr < $e[0].attributes.length; attr++) { + var attributeName = $e[0].attributes[attr].name; + var prefix = 'data-'; + + if (attributeName.substr(0, prefix.length) == prefix) { + // Get the contents of the attribute after `data-` + var dataName = attributeName.substring(prefix.length); + + // Get the data contents from the consistent source + // This is more than likely the jQuery data helper + var dataValue = Utils.GetData($e[0], dataName); + + // camelCase the attribute name to match the spec + var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter); + + // Store the data attribute contents into the dataset since + dataset[camelDataName] = dataValue; + } + } + // Prefer the element's `dataset` attribute if it exists // jQuery 1.x does not correctly handle data attributes with multiple dashes if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) { - dataset = $.extend(true, {}, $e[0].dataset, $e.data()); - } else { - dataset = $e.data(); + dataset = $.extend(true, {}, $e[0].dataset, dataset); } - var data = $.extend(true, {}, dataset); + // Prefer our internal data cache if it exists + var data = $.extend(true, {}, Utils.GetData($e[0]), dataset); data = Utils._convertData(data); @@ -5054,8 +5363,8 @@ S2.define('select2/core',[ './keys' ], function ($, Options, Utils, KEYS) { var Select2 = function ($element, options) { - if ($element.data('select2') != null) { - $element.data('select2').destroy(); + if (Utils.GetData($element[0], 'select2') != null) { + Utils.GetData($element[0], 'select2').destroy(); } this.$element = $element; @@ -5071,7 +5380,7 @@ S2.define('select2/core',[ // Set up the tabindex var tabindex = $element.attr('tabindex') || 0; - $element.data('old-tabindex', tabindex); + Utils.StoreData($element[0], 'old-tabindex', tabindex); $element.attr('tabindex', '-1'); // Set up containers and adapters @@ -5132,6 +5441,9 @@ S2.define('select2/core',[ // Synchronize any monitored attributes this._syncAttributes(); + Utils.StoreData($element[0], 'select2', this); + + // Ensure backwards compatibility with $element.data('select2'). $element.data('select2', this); }; @@ -5208,6 +5520,12 @@ S2.define('select2/core',[ return null; } + if (method == 'computedstyle') { + var computedStyle = window.getComputedStyle($element[0]); + + return computedStyle.width; + } + return method; }; @@ -5248,8 +5566,8 @@ S2.define('select2/core',[ if (observer != null) { this._observer = new observer(function (mutations) { - $.each(mutations, self._syncA); - $.each(mutations, self._syncS); + self._syncA(); + self._syncS(null, mutations); }); this._observer.observe(this.$element[0], { attributes: true, @@ -5371,7 +5689,7 @@ S2.define('select2/core',[ if (self.isOpen()) { if (key === KEYS.ESC || key === KEYS.TAB || (key === KEYS.UP && evt.altKey)) { - self.close(); + self.close(evt); evt.preventDefault(); } else if (key === KEYS.ENTER) { @@ -5405,7 +5723,7 @@ S2.define('select2/core',[ Select2.prototype._syncAttributes = function () { this.options.set('disabled', this.$element.prop('disabled')); - if (this.options.get('disabled')) { + if (this.isDisabled()) { if (this.isOpen()) { this.close(); } @@ -5416,7 +5734,7 @@ S2.define('select2/core',[ } }; - Select2.prototype._syncSubtree = function (evt, mutations) { + Select2.prototype._isChangeMutation = function (evt, mutations) { var changed = false; var self = this; @@ -5444,7 +5762,22 @@ S2.define('select2/core',[ } } else if (mutations.removedNodes && mutations.removedNodes.length > 0) { changed = true; + } else if ($.isArray(mutations)) { + $.each(mutations, function(evt, mutation) { + if (self._isChangeMutation(evt, mutation)) { + // We've found a change mutation. + // Let's escape from the loop and continue + changed = true; + return false; + } + }); } + return changed; + }; + + Select2.prototype._syncSubtree = function (evt, mutations) { + var changed = this._isChangeMutation(evt, mutations); + var self = this; // Only re-pull the data if we think there is a change if (changed) { @@ -5466,7 +5799,8 @@ S2.define('select2/core',[ 'open': 'opening', 'close': 'closing', 'select': 'selecting', - 'unselect': 'unselecting' + 'unselect': 'unselecting', + 'clear': 'clearing' }; if (args === undefined) { @@ -5494,7 +5828,7 @@ S2.define('select2/core',[ }; Select2.prototype.toggleDropdown = function () { - if (this.options.get('disabled')) { + if (this.isDisabled()) { return; } @@ -5510,15 +5844,40 @@ S2.define('select2/core',[ return; } + if (this.isDisabled()) { + return; + } + this.trigger('query', {}); }; - Select2.prototype.close = function () { + Select2.prototype.close = function (evt) { if (!this.isOpen()) { return; } - this.trigger('close', {}); + this.trigger('close', { originalEvent : evt }); + }; + + /** + * Helper method to abstract the "enabled" (not "disabled") state of this + * object. + * + * @return {true} if the instance is not disabled. + * @return {false} if the instance is disabled. + */ + Select2.prototype.isEnabled = function () { + return !this.isDisabled(); + }; + + /** + * Helper method to abstract the "disabled" state of this object. + * + * @return {true} if the disabled option is true. + * @return {false} if the disabled option is false. + */ + Select2.prototype.isDisabled = function () { + return this.options.get('disabled'); }; Select2.prototype.isOpen = function () { @@ -5595,7 +5954,7 @@ S2.define('select2/core',[ }); } - this.$element.val(newVal).trigger('change'); + this.$element.val(newVal).trigger('input').trigger('change'); }; Select2.prototype.destroy = function () { @@ -5621,10 +5980,12 @@ S2.define('select2/core',[ this._syncS = null; this.$element.off('.select2'); - this.$element.attr('tabindex', this.$element.data('old-tabindex')); + this.$element.attr('tabindex', + Utils.GetData(this.$element[0], 'old-tabindex')); this.$element.removeClass('select2-hidden-accessible'); this.$element.attr('aria-hidden', 'false'); + Utils.RemoveData(this.$element[0]); this.$element.removeData('select2'); this.dataAdapter.destroy(); @@ -5652,7 +6013,7 @@ S2.define('select2/core',[ this.$container.addClass('select2-container--' + this.options.get('theme')); - $container.data('element', this.$element); + Utils.StoreData($container[0], 'element', this.$element); return $container; }; @@ -5862,8 +6223,9 @@ S2.define('select2/compat/initSelection',[ }); S2.define('select2/compat/inputData',[ - 'jquery' -], function ($) { + 'jquery', + '../utils' +], function ($, Utils) { function InputData (decorated, $element, options) { this._currentData = []; this._valueSeparator = options.get('valueSeparator') || ','; @@ -5927,13 +6289,13 @@ S2.define('select2/compat/inputData',[ }); this.$element.val(data.id); - this.$element.trigger('change'); + this.$element.trigger('input').trigger('change'); } else { var value = this.$element.val(); value += this._valueSeparator + data.id; this.$element.val(value); - this.$element.trigger('change'); + this.$element.trigger('input').trigger('change'); } }; @@ -5956,7 +6318,7 @@ S2.define('select2/compat/inputData',[ } self.$element.val(values.join(self._valueSeparator)); - self.$element.trigger('change'); + self.$element.trigger('input').trigger('change'); }); }; @@ -5980,7 +6342,7 @@ S2.define('select2/compat/inputData',[ InputData.prototype.addOptions = function (_, $options) { var options = $.map($options, function ($option) { - return $.data($option[0], 'data'); + return Utils.GetData($option[0], 'data'); }); this._currentData.push.apply(this._currentData, options); @@ -6383,8 +6745,9 @@ S2.define('jquery.select2',[ 'jquery-mousewheel', './select2/core', - './select2/defaults' -], function ($, _, Select2, Defaults) { + './select2/defaults', + './select2/utils' +], function ($, _, Select2, Defaults, Utils) { if ($.fn.select2 == null) { // All methods that should return the element var thisMethods = ['open', 'close', 'destroy']; @@ -6405,7 +6768,7 @@ S2.define('jquery.select2',[ var args = Array.prototype.slice.call(arguments, 1); this.each(function () { - var instance = $(this).data('select2'); + var instance = Utils.GetData(this, 'select2'); if (instance == null && window.console && console.error) { console.error( diff --git a/InvenTree/InvenTree/static/select2/js/select2.full.min.js b/InvenTree/InvenTree/static/select2/js/select2.full.min.js new file mode 100644 index 0000000000..fa781916e8 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/select2.full.min.js @@ -0,0 +1,2 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ +!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(d){var e=function(){if(d&&d.fn&&d.fn.select2&&d.fn.select2.amd)var e=d.fn.select2.amd;var t,n,i,h,o,s,f,g,m,v,y,_,r,a,w,l;function b(e,t){return r.call(e,t)}function c(e,t){var n,i,r,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"]||{};if(e){for(s=(e=e.split("/")).length-1,y.nodeIdCompat&&w.test(e[s])&&(e[s]=e[s].replace(w,"")),"."===e[0].charAt(0)&&h&&(e=h.slice(0,h.length-1).concat(e)),u=0;u":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},r.appendMany=function(e,t){if("1.7"===o.fn.jquery.substr(0,3)){var n=o();o.map(t,function(e){n=n.add(e)}),t=n}e.append(t)},r.__cache={};var n=0;return r.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null==t&&(e.id?(t=e.id,e.setAttribute("data-select2-id",t)):(e.setAttribute("data-select2-id",++n),t=n.toString())),t},r.StoreData=function(e,t,n){var i=r.GetUniqueElementId(e);r.__cache[i]||(r.__cache[i]={}),r.__cache[i][t]=n},r.GetData=function(e,t){var n=r.GetUniqueElementId(e);return t?r.__cache[n]&&null!=r.__cache[n][t]?r.__cache[n][t]:o(e).data(t):r.__cache[n]},r.RemoveData=function(e){var t=r.GetUniqueElementId(e);null!=r.__cache[t]&&delete r.__cache[t],e.removeAttribute("data-select2-id")},r}),e.define("select2/results",["jquery","./utils"],function(h,f){function i(e,t,n){this.$element=e,this.data=n,this.options=t,i.__super__.constructor.call(this)}return f.Extend(i,f.Observable),i.prototype.render=function(){var e=h('
            ');return this.options.get("multiple")&&e.attr("aria-multiselectable","true"),this.$results=e},i.prototype.clear=function(){this.$results.empty()},i.prototype.displayMessage=function(e){var t=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var n=h(''),i=this.options.get("translations").get(e.message);n.append(t(i(e.args))),n[0].className+=" select2-results__message",this.$results.append(n)},i.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},i.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n",{class:"select2-results__options select2-results__options--nested"});p.append(l),s.append(a),s.append(p)}else this.template(e,t);return f.StoreData(t,"data",e),t},i.prototype.bind=function(t,e){var l=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on("results:append",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on("query",function(e){l.hideMessages(),l.showLoading(e)}),t.on("select",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("open",function(){l.$results.attr("aria-expanded","true"),l.$results.attr("aria-hidden","false"),l.setClasses(),l.ensureHighlightVisible()}),t.on("close",function(){l.$results.attr("aria-expanded","false"),l.$results.attr("aria-hidden","true"),l.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=f.GetData(e[0],"data");"true"==e.attr("aria-selected")?l.trigger("close",{}):l.trigger("select",{data:t})}}),t.on("results:previous",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e);if(!(n<=0)){var i=n-1;0===e.length&&(i=0);var r=t.eq(i);r.trigger("mouseenter");var o=l.$results.offset().top,s=r.offset().top,a=l.$results.scrollTop()+(s-o);0===i?l.$results.scrollTop(0):s-o<0&&l.$results.scrollTop(a)}}),t.on("results:next",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e)+1;if(!(n>=t.length)){var i=t.eq(n);i.trigger("mouseenter");var r=l.$results.offset().top+l.$results.outerHeight(!1),o=i.offset().top+i.outerHeight(!1),s=l.$results.scrollTop()+o-r;0===n?l.$results.scrollTop(0):rthis.$results.outerHeight()||o<0)&&this.$results.scrollTop(r)}},i.prototype.template=function(e,t){var n=this.options.get("templateResult"),i=this.options.get("escapeMarkup"),r=n(e,t);null==r?t.style.display="none":"string"==typeof r?t.innerHTML=i(r):h(t).append(r)},i}),e.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),e.define("select2/selection/base",["jquery","../utils","../keys"],function(n,i,r){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return i.Extend(o,i.Observable),o.prototype.render=function(){var e=n('');return this._tabindex=0,null!=i.GetData(this.$element[0],"old-tabindex")?this._tabindex=i.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),e.attr("title",this.$element.attr("title")),e.attr("tabindex",this._tabindex),e.attr("aria-disabled","false"),this.$selection=e},o.prototype.bind=function(e,t){var n=this,i=e.id+"-results";this.container=e,this.$selection.on("focus",function(e){n.trigger("focus",e)}),this.$selection.on("blur",function(e){n._handleBlur(e)}),this.$selection.on("keydown",function(e){n.trigger("keypress",e),e.which===r.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){n.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){n.update(e.data)}),e.on("open",function(){n.$selection.attr("aria-expanded","true"),n.$selection.attr("aria-owns",i),n._attachCloseHandler(e)}),e.on("close",function(){n.$selection.attr("aria-expanded","false"),n.$selection.removeAttr("aria-activedescendant"),n.$selection.removeAttr("aria-owns"),n.$selection.trigger("focus"),n._detachCloseHandler(e)}),e.on("enable",function(){n.$selection.attr("tabindex",n._tabindex),n.$selection.attr("aria-disabled","false")}),e.on("disable",function(){n.$selection.attr("tabindex","-1"),n.$selection.attr("aria-disabled","true")})},o.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger("blur",e)},1)},o.prototype._attachCloseHandler=function(e){n(document.body).on("mousedown.select2."+e.id,function(e){var t=n(e.target).closest(".select2");n(".select2.select2-container--open").each(function(){this!=t[0]&&i.GetData(this,"element").select2("close")})})},o.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},o.prototype.position=function(e,t){t.find(".selection").append(e)},o.prototype.destroy=function(){this._detachCloseHandler(this.container)},o.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},o.prototype.isEnabled=function(){return!this.isDisabled()},o.prototype.isDisabled=function(){return this.options.get("disabled")},o}),e.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,i){function r(){r.__super__.constructor.apply(this,arguments)}return n.Extend(r,t),r.prototype.render=function(){var e=r.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html(''),e},r.prototype.bind=function(t,e){var n=this;r.__super__.bind.apply(this,arguments);var i=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",i).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",i),this.$selection.on("mousedown",function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(e){}),this.$selection.on("blur",function(e){}),t.on("focus",function(e){t.isOpen()||n.$selection.trigger("focus")})},r.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},r.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},r.prototype.selectionContainer=function(){return e("")},r.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),i=this.display(t,n);n.empty().append(i);var r=t.title||t.text;r?n.attr("title",r):n.removeAttr("title")}else this.clear()},r}),e.define("select2/selection/multiple",["jquery","./base","../utils"],function(r,e,l){function n(e,t){n.__super__.constructor.apply(this,arguments)}return l.Extend(n,e),n.prototype.render=function(){var e=n.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html('
              '),e},n.prototype.bind=function(e,t){var i=this;n.__super__.bind.apply(this,arguments),this.$selection.on("click",function(e){i.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){if(!i.isDisabled()){var t=r(this).parent(),n=l.GetData(t[0],"data");i.trigger("unselect",{originalEvent:e,data:n})}})},n.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},n.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},n.prototype.selectionContainer=function(){return r('
            • ×
            • ')},n.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=0;n×
              ');a.StoreData(i[0],"data",t),this.$selection.find(".select2-selection__rendered").prepend(i)}},e}),e.define("select2/selection/search",["jquery","../utils","../keys"],function(i,a,l){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=i('');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),t.on("open",function(){i.$search.attr("aria-controls",r),i.$search.trigger("focus")}),t.on("close",function(){i.$search.val(""),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.trigger("focus")}),t.on("enable",function(){i.$search.prop("disabled",!1),i._transferTabIndex()}),t.on("disable",function(){i.$search.prop("disabled",!0)}),t.on("focus",function(e){i.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){i.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){i._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented(),e.which===l.BACKSPACE&&""===i.$search.val()){var t=i.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("select",function(){i._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var i=this;this._checkIfMaximumSelected(function(){e.call(i,t,n)})},e.prototype._checkIfMaximumSelected=function(e,n){var i=this;this.current(function(e){var t=null!=e?e.length:0;0=i.maximumSelectionLength?i.trigger("results:message",{message:"maximumSelected",args:{maximum:i.maximumSelectionLength}}):n&&n()})},e}),e.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t('');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define("select2/dropdown/search",["jquery","../utils"],function(o,e){function t(){}return t.prototype.render=function(e){var t=e.call(this),n=o('');return this.$searchContainer=n,this.$search=n.find("input"),t.prepend(n),t},t.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),this.$search.on("keydown",function(e){i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){o(this).off("keyup")}),this.$search.on("keyup input",function(e){i.handleSearch(e)}),t.on("open",function(){i.$search.attr("tabindex",0),i.$search.attr("aria-controls",r),i.$search.trigger("focus"),window.setTimeout(function(){i.$search.trigger("focus")},0)}),t.on("close",function(){i.$search.attr("tabindex",-1),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.val(""),i.$search.trigger("blur")}),t.on("focus",function(){t.isOpen()||i.$search.trigger("focus")}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(i.showSearch(e)?i.$searchContainer.removeClass("select2-search--hide"):i.$searchContainer.addClass("select2-search--hide"))}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")})},t.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},t.prototype.showSearch=function(e,t){return!0},t}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,i){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,i)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),i=t.length-1;0<=i;i--){var r=t[i];this.placeholder.id===r.id&&n.splice(i,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(n){function e(e,t,n,i){this.lastParams={},e.call(this,t,n,i),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("query",function(e){i.lastParams=e,i.loading=!0}),t.on("query:append",function(e){i.lastParams=e,i.loading=!0}),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);if(!this.loading&&e){var t=this.$results.offset().top+this.$results.outerHeight(!1);this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=t+50&&this.loadMore()}},e.prototype.loadMore=function(){this.loading=!0;var e=n.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=n('
            • '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=f(n.get("dropdownParent")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("open",function(){i._showDropdown(),i._attachPositioningHandler(t),i._bindContainerResultHandlers(t)}),t.on("close",function(){i._hideDropdown(),i._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(""),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var n=this;t.on("results:all",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:append",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:message",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("select",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("unselect",function(){n._positionDropdown(),n._resizeDropdown()}),this._containerResultsHandlersBound=!0}},e.prototype._attachPositioningHandler=function(e,t){var n=this,i="scroll.select2."+t.id,r="resize.select2."+t.id,o="orientationchange.select2."+t.id,s=this.$container.parents().filter(a.hasScroll);s.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),s.on(i,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(i+" "+r+" "+o,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,i="resize.select2."+t.id,r="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+i+" "+r)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown.hasClass("select2-dropdown--above"),n=this.$dropdown.hasClass("select2-dropdown--below"),i=null,r=this.$container.offset();r.bottom=r.top+this.$container.outerHeight(!1);var o={height:this.$container.outerHeight(!1)};o.top=r.top,o.bottom=r.top+o.height;var s=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ar.bottom+s,d={left:r.left,top:o.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h={top:0,left:0};(f.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),d.top-=h.top,d.left-=h.left,t||n||(i="below"),u||!c||t?!c&&u&&t&&(i="below"):i="above",("above"==i||t&&"below"!==i)&&(d.top=o.top-h.top-s),null!=i&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+i),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+i)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,i){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,i)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,i=0;i');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container.addClass("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("select2/compat/utils",["jquery"],function(s){return{syncCssClasses:function(e,t,n){var i,r,o=[];(i=s.trim(e.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0===this.indexOf("select2-")&&o.push(this)}),(i=s.trim(t.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(r=n(this))&&o.push(r)}),e.attr("class",o.join(" "))}}}),e.define("select2/compat/containerCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("containerCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptContainerCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("containerCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/dropdownCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("dropdownCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptDropdownCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("dropdownCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/initSelection",["jquery"],function(i){function e(e,t,n){n.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=n.get("initSelection"),this._isInitialized=!1,e.call(this,t,n)}return e.prototype.current=function(e,t){var n=this;this._isInitialized?e.call(this,t):this.initSelection.call(null,this.$element,function(e){n._isInitialized=!0,i.isArray(e)||(e=[e]),t(e)})},e}),e.define("select2/compat/inputData",["jquery","../utils"],function(s,i){function e(e,t,n){this._currentData=[],this._valueSeparator=n.get("valueSeparator")||",","hidden"===t.prop("type")&&n.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `' + + ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' + '' ); @@ -1873,14 +2000,18 @@ S2.define('select2/selection/search',[ Search.prototype.bind = function (decorated, container, $container) { var self = this; + var resultsId = container.id + '-results'; + decorated.call(this, container, $container); container.on('open', function () { + self.$search.attr('aria-controls', resultsId); self.$search.trigger('focus'); }); container.on('close', function () { self.$search.val(''); + self.$search.removeAttr('aria-controls'); self.$search.removeAttr('aria-activedescendant'); self.$search.trigger('focus'); }); @@ -1900,7 +2031,11 @@ S2.define('select2/selection/search',[ }); container.on('results:focus', function (params) { - self.$search.attr('aria-activedescendant', params.id); + if (params.data._resultId) { + self.$search.attr('aria-activedescendant', params.data._resultId); + } else { + self.$search.removeAttr('aria-activedescendant'); + } }); this.$selection.on('focusin', '.select2-search--inline', function (evt) { @@ -1925,7 +2060,7 @@ S2.define('select2/selection/search',[ .prev('.select2-selection__choice'); if ($previousChoice.length > 0) { - var item = $previousChoice.data('data'); + var item = Utils.GetData($previousChoice[0], 'data'); self.searchRemoveChoice(item); @@ -1934,6 +2069,12 @@ S2.define('select2/selection/search',[ } }); + this.$selection.on('click', '.select2-search--inline', function (evt) { + if (self.$search.val()) { + evt.stopPropagation(); + } + }); + // Try to detect the IE version should the `documentMode` property that // is stored on the document. This is only implemented in IE and is // slightly cleaner than doing a user agent check. @@ -2019,7 +2160,7 @@ S2.define('select2/selection/search',[ this.resizeSearch(); if (searchHadFocus) { - this.$search.focus(); + this.$search.trigger('focus'); } }; @@ -2052,7 +2193,7 @@ S2.define('select2/selection/search',[ var width = ''; if (this.$search.attr('placeholder') !== '') { - width = this.$selection.find('.select2-selection__rendered').innerWidth(); + width = this.$selection.find('.select2-selection__rendered').width(); } else { var minimumWidth = this.$search.val().length + 1; @@ -2076,10 +2217,13 @@ S2.define('select2/selection/eventRelay',[ 'open', 'opening', 'close', 'closing', 'select', 'selecting', - 'unselect', 'unselecting' + 'unselect', 'unselecting', + 'clear', 'clearing' ]; - var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting']; + var preventableEvents = [ + 'opening', 'closing', 'selecting', 'unselecting', 'clearing' + ]; decorated.call(this, container, $container); @@ -2412,6 +2556,7 @@ S2.define('select2/diacritics',[ '\u019F': 'O', '\uA74A': 'O', '\uA74C': 'O', + '\u0152': 'OE', '\u01A2': 'OI', '\uA74E': 'OO', '\u0222': 'OU', @@ -2821,6 +2966,7 @@ S2.define('select2/diacritics',[ '\uA74B': 'o', '\uA74D': 'o', '\u0275': 'o', + '\u0153': 'oe', '\u01A3': 'oi', '\u0223': 'ou', '\uA74F': 'oo', @@ -2989,8 +3135,9 @@ S2.define('select2/diacritics',[ '\u03CD': '\u03C5', '\u03CB': '\u03C5', '\u03B0': '\u03C5', - '\u03C9': '\u03C9', - '\u03C2': '\u03C3' + '\u03CE': '\u03C9', + '\u03C2': '\u03C3', + '\u2019': '\'' }; return diacritics; @@ -3075,7 +3222,7 @@ S2.define('select2/data/select',[ if ($(data.element).is('option')) { data.element.selected = true; - this.$element.trigger('change'); + this.$element.trigger('input').trigger('change'); return; } @@ -3096,13 +3243,13 @@ S2.define('select2/data/select',[ } self.$element.val(val); - self.$element.trigger('change'); + self.$element.trigger('input').trigger('change'); }); } else { var val = data.id; this.$element.val(val); - this.$element.trigger('change'); + this.$element.trigger('input').trigger('change'); } }; @@ -3118,7 +3265,7 @@ S2.define('select2/data/select',[ if ($(data.element).is('option')) { data.element.selected = false; - this.$element.trigger('change'); + this.$element.trigger('input').trigger('change'); return; } @@ -3136,7 +3283,7 @@ S2.define('select2/data/select',[ self.$element.val(val); - self.$element.trigger('change'); + self.$element.trigger('input').trigger('change'); }); }; @@ -3158,7 +3305,7 @@ S2.define('select2/data/select',[ // Remove anything added to child elements this.$element.find('*').each(function () { // Remove any custom data set by Select2 - $.removeData(this, 'data'); + Utils.RemoveData(this); }); }; @@ -3231,7 +3378,7 @@ S2.define('select2/data/select',[ normalizedData.element = option; // Override the option's data with the combined data - $.data(option, 'data', normalizedData); + Utils.StoreData(option, 'data', normalizedData); return $option; }; @@ -3239,7 +3386,7 @@ S2.define('select2/data/select',[ SelectAdapter.prototype.item = function ($option) { var data = {}; - data = $.data($option[0], 'data'); + data = Utils.GetData($option[0], 'data'); if (data != null) { return data; @@ -3277,13 +3424,13 @@ S2.define('select2/data/select',[ data = this._normalizeItem(data); data.element = $option[0]; - $.data($option[0], 'data', data); + Utils.StoreData($option[0], 'data', data); return data; }; SelectAdapter.prototype._normalizeItem = function (item) { - if (!$.isPlainObject(item)) { + if (item !== Object(item)) { item = { id: item, text: item @@ -3329,15 +3476,19 @@ S2.define('select2/data/array',[ 'jquery' ], function (SelectAdapter, Utils, $) { function ArrayAdapter ($element, options) { - var data = options.get('data') || []; + this._dataToConvert = options.get('data') || []; ArrayAdapter.__super__.constructor.call(this, $element, options); - - this.addOptions(this.convertToOptions(data)); } Utils.Extend(ArrayAdapter, SelectAdapter); + ArrayAdapter.prototype.bind = function (container, $container) { + ArrayAdapter.__super__.bind.call(this, container, $container); + + this.addOptions(this.convertToOptions(this._dataToConvert)); + }; + ArrayAdapter.prototype.select = function (data) { var $option = this.$element.find('option').filter(function (i, elm) { return elm.value == data.id.toString(); @@ -3487,7 +3638,8 @@ S2.define('select2/data/ajax',[ }, function () { // Attempt to detect if a request was aborted // Only works if the transport exposes a status property - if ($request.status && $request.status === '0') { + if ('status' in $request && + ($request.status === 0 || $request.status === '0')) { return; } @@ -3626,8 +3778,6 @@ S2.define('select2/data/tags',[ }; Tags.prototype._removeOldTags = function (_) { - var tag = this._lastTag; - var $options = this.$element.find('option[data-select2-tag]'); $options.each(function () { @@ -3702,7 +3852,7 @@ S2.define('select2/data/tokenizer',[ // Replace the search term if we have the search box if (this.$search.length) { this.$search.val(tokenData.term); - this.$search.focus(); + this.$search.trigger('focus'); } params.term = tokenData.term; @@ -3831,10 +3981,30 @@ S2.define('select2/data/maximumSelectionLength',[ decorated.call(this, $e, options); } + MaximumSelectionLength.prototype.bind = + function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('select', function () { + self._checkIfMaximumSelected(); + }); + }; + MaximumSelectionLength.prototype.query = function (decorated, params, callback) { var self = this; + this._checkIfMaximumSelected(function () { + decorated.call(self, params, callback); + }); + }; + + MaximumSelectionLength.prototype._checkIfMaximumSelected = + function (_, successCallback) { + var self = this; + this.current(function (currentData) { var count = currentData != null ? currentData.length : 0; if (self.maximumSelectionLength > 0 && @@ -3847,7 +4017,10 @@ S2.define('select2/data/maximumSelectionLength',[ }); return; } - decorated.call(self, params, callback); + + if (successCallback) { + successCallback(); + } }); }; @@ -3886,7 +4059,7 @@ S2.define('select2/dropdown',[ }; Dropdown.prototype.position = function ($dropdown, $container) { - // Should be implmented in subclasses + // Should be implemented in subclasses }; Dropdown.prototype.destroy = function () { @@ -3910,7 +4083,7 @@ S2.define('select2/dropdown/search',[ '' + '' + + ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' + '' ); @@ -3925,6 +4098,8 @@ S2.define('select2/dropdown/search',[ Search.prototype.bind = function (decorated, container, $container) { var self = this; + var resultsId = container.id + '-results'; + decorated.call(this, container, $container); this.$search.on('keydown', function (evt) { @@ -3947,23 +4122,27 @@ S2.define('select2/dropdown/search',[ container.on('open', function () { self.$search.attr('tabindex', 0); + self.$search.attr('aria-controls', resultsId); - self.$search.focus(); + self.$search.trigger('focus'); window.setTimeout(function () { - self.$search.focus(); + self.$search.trigger('focus'); }, 0); }); container.on('close', function () { self.$search.attr('tabindex', -1); + self.$search.removeAttr('aria-controls'); + self.$search.removeAttr('aria-activedescendant'); self.$search.val(''); + self.$search.trigger('blur'); }); container.on('focus', function () { if (!container.isOpen()) { - self.$search.focus(); + self.$search.trigger('focus'); } }); @@ -3978,6 +4157,14 @@ S2.define('select2/dropdown/search',[ } } }); + + container.on('results:focus', function (params) { + if (params.data._resultId) { + self.$search.attr('aria-activedescendant', params.data._resultId); + } else { + self.$search.removeAttr('aria-activedescendant'); + } + }); }; Search.prototype.handleSearch = function (evt) { @@ -4062,6 +4249,7 @@ S2.define('select2/dropdown/infiniteScroll',[ if (this.showLoadingMore(data)) { this.$results.append(this.$loadingMore); + this.loadMoreIfNeeded(); } }; @@ -4080,25 +4268,27 @@ S2.define('select2/dropdown/infiniteScroll',[ self.loading = true; }); - this.$results.on('scroll', function () { - var isLoadMoreVisible = $.contains( - document.documentElement, - self.$loadingMore[0] - ); + this.$results.on('scroll', this.loadMoreIfNeeded.bind(this)); + }; - if (self.loading || !isLoadMoreVisible) { - return; - } + InfiniteScroll.prototype.loadMoreIfNeeded = function () { + var isLoadMoreVisible = $.contains( + document.documentElement, + this.$loadingMore[0] + ); - var currentOffset = self.$results.offset().top + - self.$results.outerHeight(false); - var loadingMoreOffset = self.$loadingMore.offset().top + - self.$loadingMore.outerHeight(false); + if (this.loading || !isLoadMoreVisible) { + return; + } - if (currentOffset + 50 >= loadingMoreOffset) { - self.loadMore(); - } - }); + var currentOffset = this.$results.offset().top + + this.$results.outerHeight(false); + var loadingMoreOffset = this.$loadingMore.offset().top + + this.$loadingMore.outerHeight(false); + + if (currentOffset + 50 >= loadingMoreOffset) { + this.loadMore(); + } }; InfiniteScroll.prototype.loadMore = function () { @@ -4119,7 +4309,7 @@ S2.define('select2/dropdown/infiniteScroll',[ var $option = $( '
            • ' + 'role="option" aria-disabled="true">' ); var message = this.options.get('translations').get('loadingMore'); @@ -4137,7 +4327,7 @@ S2.define('select2/dropdown/attachBody',[ '../utils' ], function ($, Utils) { function AttachBody (decorated, $element, options) { - this.$dropdownParent = options.get('dropdownParent') || $(document.body); + this.$dropdownParent = $(options.get('dropdownParent') || document.body); decorated.call(this, $element, options); } @@ -4145,27 +4335,14 @@ S2.define('select2/dropdown/attachBody',[ AttachBody.prototype.bind = function (decorated, container, $container) { var self = this; - var setupResultsEvents = false; - decorated.call(this, container, $container); container.on('open', function () { self._showDropdown(); self._attachPositioningHandler(container); - if (!setupResultsEvents) { - setupResultsEvents = true; - - container.on('results:all', function () { - self._positionDropdown(); - self._resizeDropdown(); - }); - - container.on('results:append', function () { - self._positionDropdown(); - self._resizeDropdown(); - }); - } + // Must bind after the results handlers to ensure correct sizing + self._bindContainerResultHandlers(container); }); container.on('close', function () { @@ -4214,6 +4391,44 @@ S2.define('select2/dropdown/attachBody',[ this.$dropdownContainer.detach(); }; + AttachBody.prototype._bindContainerResultHandlers = + function (decorated, container) { + + // These should only be bound once + if (this._containerResultsHandlersBound) { + return; + } + + var self = this; + + container.on('results:all', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('results:append', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('results:message', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('select', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('unselect', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + this._containerResultsHandlersBound = true; + }; + AttachBody.prototype._attachPositioningHandler = function (decorated, container) { var self = this; @@ -4224,14 +4439,14 @@ S2.define('select2/dropdown/attachBody',[ var $watchers = this.$container.parents().filter(Utils.hasScroll); $watchers.each(function () { - $(this).data('select2-scroll-position', { + Utils.StoreData(this, 'select2-scroll-position', { x: $(this).scrollLeft(), y: $(this).scrollTop() }); }); $watchers.on(scrollEvent, function (ev) { - var position = $(this).data('select2-scroll-position'); + var position = Utils.GetData(this, 'select2-scroll-position'); $(this).scrollTop(position.y); }); @@ -4290,16 +4505,26 @@ S2.define('select2/dropdown/attachBody',[ top: container.bottom }; - // Determine what the parent element is to use for calciulating the offset + // Determine what the parent element is to use for calculating the offset var $offsetParent = this.$dropdownParent; - // For statically positoned elements, we need to get the element + // For statically positioned elements, we need to get the element // that is determining the offset if ($offsetParent.css('position') === 'static') { $offsetParent = $offsetParent.offsetParent(); } - var parentOffset = $offsetParent.offset(); + var parentOffset = { + top: 0, + left: 0 + }; + + if ( + $.contains(document.body, $offsetParent[0]) || + $offsetParent[0].isConnected + ) { + parentOffset = $offsetParent.offset(); + } css.top -= parentOffset.top; css.left -= parentOffset.left; @@ -4396,8 +4621,8 @@ S2.define('select2/dropdown/minimumResultsForSearch',[ }); S2.define('select2/dropdown/selectOnClose',[ - -], function () { + '../utils' +], function (Utils) { function SelectOnClose () { } SelectOnClose.prototype.bind = function (decorated, container, $container) { @@ -4428,7 +4653,7 @@ S2.define('select2/dropdown/selectOnClose',[ return; } - var data = $highlightedResults.data('data'); + var data = Utils.GetData($highlightedResults[0], 'data'); // Don't re-select already selected resulte if ( @@ -4469,7 +4694,7 @@ S2.define('select2/dropdown/closeOnSelect',[ var originalEvent = evt.originalEvent; // Don't close if the control key is being held - if (originalEvent && originalEvent.ctrlKey) { + if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) { return; } @@ -4523,6 +4748,9 @@ S2.define('select2/i18n/en',[],function () { }, searching: function () { return 'Searching…'; + }, + removeAllItems: function () { + return 'Remove all items'; } }; }); @@ -4761,66 +4989,29 @@ S2.define('select2/defaults',[ ); } - if (typeof options.language === 'string') { - // Check if the language is specified with a region - if (options.language.indexOf('-') > 0) { - // Extract the region information if it is included - var languageParts = options.language.split('-'); - var baseLanguage = languageParts[0]; + // If the defaults were not previously applied from an element, it is + // possible for the language option to have not been resolved + options.language = this._resolveLanguage(options.language); - options.language = [options.language, baseLanguage]; - } else { - options.language = [options.language]; + // Always fall back to English since it will always be complete + options.language.push('en'); + + var uniqueLanguages = []; + + for (var l = 0; l < options.language.length; l++) { + var language = options.language[l]; + + if (uniqueLanguages.indexOf(language) === -1) { + uniqueLanguages.push(language); } } - if ($.isArray(options.language)) { - var languages = new Translation(); - options.language.push('en'); + options.language = uniqueLanguages; - var languageNames = options.language; - - for (var l = 0; l < languageNames.length; l++) { - var name = languageNames[l]; - var language = {}; - - try { - // Try to load it with the original name - language = Translation.loadPath(name); - } catch (e) { - try { - // If we couldn't load it, check if it wasn't the full path - name = this.defaults.amdLanguageBase + name; - language = Translation.loadPath(name); - } catch (ex) { - // The translation could not be loaded at all. Sometimes this is - // because of a configuration problem, other times this can be - // because of how Select2 helps load all possible translation files. - if (options.debug && window.console && console.warn) { - console.warn( - 'Select2: The language file for "' + name + '" could not be ' + - 'automatically loaded. A fallback will be used instead.' - ); - } - - continue; - } - } - - languages.extend(language); - } - - options.translations = languages; - } else { - var baseTranslation = Translation.loadPath( - this.defaults.amdLanguageBase + 'en' - ); - var customTranslation = new Translation(options.language); - - customTranslation.extend(baseTranslation); - - options.translations = customTranslation; - } + options.translations = this._processTranslations( + options.language, + options.debug + ); return options; }; @@ -4887,13 +5078,14 @@ S2.define('select2/defaults',[ debug: false, dropdownAutoWidth: false, escapeMarkup: Utils.escapeMarkup, - language: EnglishTranslation, + language: {}, matcher: matcher, minimumInputLength: 0, maximumInputLength: 0, maximumSelectionLength: 0, minimumResultsForSearch: 0, selectOnClose: false, + scrollAfterSelect: false, sorter: function (data) { return data; }, @@ -4908,6 +5100,103 @@ S2.define('select2/defaults',[ }; }; + Defaults.prototype.applyFromElement = function (options, $element) { + var optionLanguage = options.language; + var defaultLanguage = this.defaults.language; + var elementLanguage = $element.prop('lang'); + var parentLanguage = $element.closest('[lang]').prop('lang'); + + var languages = Array.prototype.concat.call( + this._resolveLanguage(elementLanguage), + this._resolveLanguage(optionLanguage), + this._resolveLanguage(defaultLanguage), + this._resolveLanguage(parentLanguage) + ); + + options.language = languages; + + return options; + }; + + Defaults.prototype._resolveLanguage = function (language) { + if (!language) { + return []; + } + + if ($.isEmptyObject(language)) { + return []; + } + + if ($.isPlainObject(language)) { + return [language]; + } + + var languages; + + if (!$.isArray(language)) { + languages = [language]; + } else { + languages = language; + } + + var resolvedLanguages = []; + + for (var l = 0; l < languages.length; l++) { + resolvedLanguages.push(languages[l]); + + if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) { + // Extract the region information if it is included + var languageParts = languages[l].split('-'); + var baseLanguage = languageParts[0]; + + resolvedLanguages.push(baseLanguage); + } + } + + return resolvedLanguages; + }; + + Defaults.prototype._processTranslations = function (languages, debug) { + var translations = new Translation(); + + for (var l = 0; l < languages.length; l++) { + var languageData = new Translation(); + + var language = languages[l]; + + if (typeof language === 'string') { + try { + // Try to load it with the original name + languageData = Translation.loadPath(language); + } catch (e) { + try { + // If we couldn't load it, check if it wasn't the full path + language = this.defaults.amdLanguageBase + language; + languageData = Translation.loadPath(language); + } catch (ex) { + // The translation could not be loaded at all. Sometimes this is + // because of a configuration problem, other times this can be + // because of how Select2 helps load all possible translation files + if (debug && window.console && console.warn) { + console.warn( + 'Select2: The language file for "' + language + '" could ' + + 'not be automatically loaded. A fallback will be used instead.' + ); + } + } + } + } else if ($.isPlainObject(language)) { + languageData = new Translation(language); + } else { + languageData = language; + } + + translations.extend(languageData); + } + + return translations; + }; + Defaults.prototype.set = function (key, value) { var camelKey = $.camelCase(key); @@ -4916,7 +5205,7 @@ S2.define('select2/defaults',[ var convertedData = Utils._convertData(data); - $.extend(this.defaults, convertedData); + $.extend(true, this.defaults, convertedData); }; var defaults = new Defaults(); @@ -4937,6 +5226,10 @@ S2.define('select2/options',[ this.fromElement($element); } + if ($element != null) { + this.options = Defaults.applyFromElement(this.options, $element); + } + this.options = Defaults.apply(this.options); if ($element && $element.is('input')) { @@ -4960,14 +5253,6 @@ S2.define('select2/options',[ this.options.disabled = $e.prop('disabled'); } - if (this.options.language == null) { - if ($e.prop('lang')) { - this.options.language = $e.prop('lang').toLowerCase(); - } else if ($e.closest('[lang]').prop('lang')) { - this.options.language = $e.closest('[lang]').prop('lang'); - } - } - if (this.options.dir == null) { if ($e.prop('dir')) { this.options.dir = $e.prop('dir'); @@ -4981,7 +5266,7 @@ S2.define('select2/options',[ $e.prop('disabled', this.options.disabled); $e.prop('multiple', this.options.multiple); - if ($e.data('select2Tags')) { + if (Utils.GetData($e[0], 'select2Tags')) { if (this.options.debug && window.console && console.warn) { console.warn( 'Select2: The `data-select2-tags` attribute has been changed to ' + @@ -4990,11 +5275,11 @@ S2.define('select2/options',[ ); } - $e.data('data', $e.data('select2Tags')); - $e.data('tags', true); + Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags')); + Utils.StoreData($e[0], 'tags', true); } - if ($e.data('ajaxUrl')) { + if (Utils.GetData($e[0], 'ajaxUrl')) { if (this.options.debug && window.console && console.warn) { console.warn( 'Select2: The `data-ajax-url` attribute has been changed to ' + @@ -5003,21 +5288,45 @@ S2.define('select2/options',[ ); } - $e.attr('ajax--url', $e.data('ajaxUrl')); - $e.data('ajax--url', $e.data('ajaxUrl')); + $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl')); + Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl')); } var dataset = {}; + function upperCaseLetter(_, letter) { + return letter.toUpperCase(); + } + + // Pre-load all of the attributes which are prefixed with `data-` + for (var attr = 0; attr < $e[0].attributes.length; attr++) { + var attributeName = $e[0].attributes[attr].name; + var prefix = 'data-'; + + if (attributeName.substr(0, prefix.length) == prefix) { + // Get the contents of the attribute after `data-` + var dataName = attributeName.substring(prefix.length); + + // Get the data contents from the consistent source + // This is more than likely the jQuery data helper + var dataValue = Utils.GetData($e[0], dataName); + + // camelCase the attribute name to match the spec + var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter); + + // Store the data attribute contents into the dataset since + dataset[camelDataName] = dataValue; + } + } + // Prefer the element's `dataset` attribute if it exists // jQuery 1.x does not correctly handle data attributes with multiple dashes if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) { - dataset = $.extend(true, {}, $e[0].dataset, $e.data()); - } else { - dataset = $e.data(); + dataset = $.extend(true, {}, $e[0].dataset, dataset); } - var data = $.extend(true, {}, dataset); + // Prefer our internal data cache if it exists + var data = $.extend(true, {}, Utils.GetData($e[0]), dataset); data = Utils._convertData(data); @@ -5054,8 +5363,8 @@ S2.define('select2/core',[ './keys' ], function ($, Options, Utils, KEYS) { var Select2 = function ($element, options) { - if ($element.data('select2') != null) { - $element.data('select2').destroy(); + if (Utils.GetData($element[0], 'select2') != null) { + Utils.GetData($element[0], 'select2').destroy(); } this.$element = $element; @@ -5071,7 +5380,7 @@ S2.define('select2/core',[ // Set up the tabindex var tabindex = $element.attr('tabindex') || 0; - $element.data('old-tabindex', tabindex); + Utils.StoreData($element[0], 'old-tabindex', tabindex); $element.attr('tabindex', '-1'); // Set up containers and adapters @@ -5132,6 +5441,9 @@ S2.define('select2/core',[ // Synchronize any monitored attributes this._syncAttributes(); + Utils.StoreData($element[0], 'select2', this); + + // Ensure backwards compatibility with $element.data('select2'). $element.data('select2', this); }; @@ -5208,6 +5520,12 @@ S2.define('select2/core',[ return null; } + if (method == 'computedstyle') { + var computedStyle = window.getComputedStyle($element[0]); + + return computedStyle.width; + } + return method; }; @@ -5248,8 +5566,8 @@ S2.define('select2/core',[ if (observer != null) { this._observer = new observer(function (mutations) { - $.each(mutations, self._syncA); - $.each(mutations, self._syncS); + self._syncA(); + self._syncS(null, mutations); }); this._observer.observe(this.$element[0], { attributes: true, @@ -5371,7 +5689,7 @@ S2.define('select2/core',[ if (self.isOpen()) { if (key === KEYS.ESC || key === KEYS.TAB || (key === KEYS.UP && evt.altKey)) { - self.close(); + self.close(evt); evt.preventDefault(); } else if (key === KEYS.ENTER) { @@ -5405,7 +5723,7 @@ S2.define('select2/core',[ Select2.prototype._syncAttributes = function () { this.options.set('disabled', this.$element.prop('disabled')); - if (this.options.get('disabled')) { + if (this.isDisabled()) { if (this.isOpen()) { this.close(); } @@ -5416,7 +5734,7 @@ S2.define('select2/core',[ } }; - Select2.prototype._syncSubtree = function (evt, mutations) { + Select2.prototype._isChangeMutation = function (evt, mutations) { var changed = false; var self = this; @@ -5444,7 +5762,22 @@ S2.define('select2/core',[ } } else if (mutations.removedNodes && mutations.removedNodes.length > 0) { changed = true; + } else if ($.isArray(mutations)) { + $.each(mutations, function(evt, mutation) { + if (self._isChangeMutation(evt, mutation)) { + // We've found a change mutation. + // Let's escape from the loop and continue + changed = true; + return false; + } + }); } + return changed; + }; + + Select2.prototype._syncSubtree = function (evt, mutations) { + var changed = this._isChangeMutation(evt, mutations); + var self = this; // Only re-pull the data if we think there is a change if (changed) { @@ -5466,7 +5799,8 @@ S2.define('select2/core',[ 'open': 'opening', 'close': 'closing', 'select': 'selecting', - 'unselect': 'unselecting' + 'unselect': 'unselecting', + 'clear': 'clearing' }; if (args === undefined) { @@ -5494,7 +5828,7 @@ S2.define('select2/core',[ }; Select2.prototype.toggleDropdown = function () { - if (this.options.get('disabled')) { + if (this.isDisabled()) { return; } @@ -5510,15 +5844,40 @@ S2.define('select2/core',[ return; } + if (this.isDisabled()) { + return; + } + this.trigger('query', {}); }; - Select2.prototype.close = function () { + Select2.prototype.close = function (evt) { if (!this.isOpen()) { return; } - this.trigger('close', {}); + this.trigger('close', { originalEvent : evt }); + }; + + /** + * Helper method to abstract the "enabled" (not "disabled") state of this + * object. + * + * @return {true} if the instance is not disabled. + * @return {false} if the instance is disabled. + */ + Select2.prototype.isEnabled = function () { + return !this.isDisabled(); + }; + + /** + * Helper method to abstract the "disabled" state of this object. + * + * @return {true} if the disabled option is true. + * @return {false} if the disabled option is false. + */ + Select2.prototype.isDisabled = function () { + return this.options.get('disabled'); }; Select2.prototype.isOpen = function () { @@ -5595,7 +5954,7 @@ S2.define('select2/core',[ }); } - this.$element.val(newVal).trigger('change'); + this.$element.val(newVal).trigger('input').trigger('change'); }; Select2.prototype.destroy = function () { @@ -5621,10 +5980,12 @@ S2.define('select2/core',[ this._syncS = null; this.$element.off('.select2'); - this.$element.attr('tabindex', this.$element.data('old-tabindex')); + this.$element.attr('tabindex', + Utils.GetData(this.$element[0], 'old-tabindex')); this.$element.removeClass('select2-hidden-accessible'); this.$element.attr('aria-hidden', 'false'); + Utils.RemoveData(this.$element[0]); this.$element.removeData('select2'); this.dataAdapter.destroy(); @@ -5652,7 +6013,7 @@ S2.define('select2/core',[ this.$container.addClass('select2-container--' + this.options.get('theme')); - $container.data('element', this.$element); + Utils.StoreData($container[0], 'element', this.$element); return $container; }; @@ -5672,8 +6033,9 @@ S2.define('jquery.select2',[ 'jquery-mousewheel', './select2/core', - './select2/defaults' -], function ($, _, Select2, Defaults) { + './select2/defaults', + './select2/utils' +], function ($, _, Select2, Defaults, Utils) { if ($.fn.select2 == null) { // All methods that should return the element var thisMethods = ['open', 'close', 'destroy']; @@ -5694,7 +6056,7 @@ S2.define('jquery.select2',[ var args = Array.prototype.slice.call(arguments, 1); this.each(function () { - var instance = $(this).data('select2'); + var instance = Utils.GetData(this, 'select2'); if (instance == null && window.console && console.error) { console.error( diff --git a/InvenTree/InvenTree/static/select2/js/select2.min.js b/InvenTree/InvenTree/static/select2/js/select2.min.js new file mode 100644 index 0000000000..e421426434 --- /dev/null +++ b/InvenTree/InvenTree/static/select2/js/select2.min.js @@ -0,0 +1,2 @@ +/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ +!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(u){var e=function(){if(u&&u.fn&&u.fn.select2&&u.fn.select2.amd)var e=u.fn.select2.amd;var t,n,r,h,o,s,f,g,m,v,y,_,i,a,b;function w(e,t){return i.call(e,t)}function l(e,t){var n,r,i,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"]||{};if(e){for(s=(e=e.split("/")).length-1,y.nodeIdCompat&&b.test(e[s])&&(e[s]=e[s].replace(b,"")),"."===e[0].charAt(0)&&h&&(e=h.slice(0,h.length-1).concat(e)),u=0;u":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},i.appendMany=function(e,t){if("1.7"===o.fn.jquery.substr(0,3)){var n=o();o.map(t,function(e){n=n.add(e)}),t=n}e.append(t)},i.__cache={};var n=0;return i.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null==t&&(e.id?(t=e.id,e.setAttribute("data-select2-id",t)):(e.setAttribute("data-select2-id",++n),t=n.toString())),t},i.StoreData=function(e,t,n){var r=i.GetUniqueElementId(e);i.__cache[r]||(i.__cache[r]={}),i.__cache[r][t]=n},i.GetData=function(e,t){var n=i.GetUniqueElementId(e);return t?i.__cache[n]&&null!=i.__cache[n][t]?i.__cache[n][t]:o(e).data(t):i.__cache[n]},i.RemoveData=function(e){var t=i.GetUniqueElementId(e);null!=i.__cache[t]&&delete i.__cache[t],e.removeAttribute("data-select2-id")},i}),e.define("select2/results",["jquery","./utils"],function(h,f){function r(e,t,n){this.$element=e,this.data=n,this.options=t,r.__super__.constructor.call(this)}return f.Extend(r,f.Observable),r.prototype.render=function(){var e=h('
                ');return this.options.get("multiple")&&e.attr("aria-multiselectable","true"),this.$results=e},r.prototype.clear=function(){this.$results.empty()},r.prototype.displayMessage=function(e){var t=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var n=h(''),r=this.options.get("translations").get(e.message);n.append(t(r(e.args))),n[0].className+=" select2-results__message",this.$results.append(n)},r.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},r.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n",{class:"select2-results__options select2-results__options--nested"});p.append(l),s.append(a),s.append(p)}else this.template(e,t);return f.StoreData(t,"data",e),t},r.prototype.bind=function(t,e){var l=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on("results:append",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on("query",function(e){l.hideMessages(),l.showLoading(e)}),t.on("select",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("open",function(){l.$results.attr("aria-expanded","true"),l.$results.attr("aria-hidden","false"),l.setClasses(),l.ensureHighlightVisible()}),t.on("close",function(){l.$results.attr("aria-expanded","false"),l.$results.attr("aria-hidden","true"),l.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=f.GetData(e[0],"data");"true"==e.attr("aria-selected")?l.trigger("close",{}):l.trigger("select",{data:t})}}),t.on("results:previous",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e);if(!(n<=0)){var r=n-1;0===e.length&&(r=0);var i=t.eq(r);i.trigger("mouseenter");var o=l.$results.offset().top,s=i.offset().top,a=l.$results.scrollTop()+(s-o);0===r?l.$results.scrollTop(0):s-o<0&&l.$results.scrollTop(a)}}),t.on("results:next",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e)+1;if(!(n>=t.length)){var r=t.eq(n);r.trigger("mouseenter");var i=l.$results.offset().top+l.$results.outerHeight(!1),o=r.offset().top+r.outerHeight(!1),s=l.$results.scrollTop()+o-i;0===n?l.$results.scrollTop(0):ithis.$results.outerHeight()||o<0)&&this.$results.scrollTop(i)}},r.prototype.template=function(e,t){var n=this.options.get("templateResult"),r=this.options.get("escapeMarkup"),i=n(e,t);null==i?t.style.display="none":"string"==typeof i?t.innerHTML=r(i):h(t).append(i)},r}),e.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),e.define("select2/selection/base",["jquery","../utils","../keys"],function(n,r,i){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return r.Extend(o,r.Observable),o.prototype.render=function(){var e=n('');return this._tabindex=0,null!=r.GetData(this.$element[0],"old-tabindex")?this._tabindex=r.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),e.attr("title",this.$element.attr("title")),e.attr("tabindex",this._tabindex),e.attr("aria-disabled","false"),this.$selection=e},o.prototype.bind=function(e,t){var n=this,r=e.id+"-results";this.container=e,this.$selection.on("focus",function(e){n.trigger("focus",e)}),this.$selection.on("blur",function(e){n._handleBlur(e)}),this.$selection.on("keydown",function(e){n.trigger("keypress",e),e.which===i.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){n.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){n.update(e.data)}),e.on("open",function(){n.$selection.attr("aria-expanded","true"),n.$selection.attr("aria-owns",r),n._attachCloseHandler(e)}),e.on("close",function(){n.$selection.attr("aria-expanded","false"),n.$selection.removeAttr("aria-activedescendant"),n.$selection.removeAttr("aria-owns"),n.$selection.trigger("focus"),n._detachCloseHandler(e)}),e.on("enable",function(){n.$selection.attr("tabindex",n._tabindex),n.$selection.attr("aria-disabled","false")}),e.on("disable",function(){n.$selection.attr("tabindex","-1"),n.$selection.attr("aria-disabled","true")})},o.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger("blur",e)},1)},o.prototype._attachCloseHandler=function(e){n(document.body).on("mousedown.select2."+e.id,function(e){var t=n(e.target).closest(".select2");n(".select2.select2-container--open").each(function(){this!=t[0]&&r.GetData(this,"element").select2("close")})})},o.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},o.prototype.position=function(e,t){t.find(".selection").append(e)},o.prototype.destroy=function(){this._detachCloseHandler(this.container)},o.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},o.prototype.isEnabled=function(){return!this.isDisabled()},o.prototype.isDisabled=function(){return this.options.get("disabled")},o}),e.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,r){function i(){i.__super__.constructor.apply(this,arguments)}return n.Extend(i,t),i.prototype.render=function(){var e=i.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html(''),e},i.prototype.bind=function(t,e){var n=this;i.__super__.bind.apply(this,arguments);var r=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",r).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",r),this.$selection.on("mousedown",function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(e){}),this.$selection.on("blur",function(e){}),t.on("focus",function(e){t.isOpen()||n.$selection.trigger("focus")})},i.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},i.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},i.prototype.selectionContainer=function(){return e("")},i.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),r=this.display(t,n);n.empty().append(r);var i=t.title||t.text;i?n.attr("title",i):n.removeAttr("title")}else this.clear()},i}),e.define("select2/selection/multiple",["jquery","./base","../utils"],function(i,e,l){function n(e,t){n.__super__.constructor.apply(this,arguments)}return l.Extend(n,e),n.prototype.render=function(){var e=n.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html('
                  '),e},n.prototype.bind=function(e,t){var r=this;n.__super__.bind.apply(this,arguments),this.$selection.on("click",function(e){r.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){if(!r.isDisabled()){var t=i(this).parent(),n=l.GetData(t[0],"data");r.trigger("unselect",{originalEvent:e,data:n})}})},n.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},n.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},n.prototype.selectionContainer=function(){return i('
                • ×
                • ')},n.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=0;n×');a.StoreData(r[0],"data",t),this.$selection.find(".select2-selection__rendered").prepend(r)}},e}),e.define("select2/selection/search",["jquery","../utils","../keys"],function(r,a,l){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=r('');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var r=this,i=t.id+"-results";e.call(this,t,n),t.on("open",function(){r.$search.attr("aria-controls",i),r.$search.trigger("focus")}),t.on("close",function(){r.$search.val(""),r.$search.removeAttr("aria-controls"),r.$search.removeAttr("aria-activedescendant"),r.$search.trigger("focus")}),t.on("enable",function(){r.$search.prop("disabled",!1),r._transferTabIndex()}),t.on("disable",function(){r.$search.prop("disabled",!0)}),t.on("focus",function(e){r.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?r.$search.attr("aria-activedescendant",e.data._resultId):r.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){r.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){r._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),r.trigger("keypress",e),r._keyUpPrevented=e.isDefaultPrevented(),e.which===l.BACKSPACE&&""===r.$search.val()){var t=r.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("select",function(){r._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var r=this;this._checkIfMaximumSelected(function(){e.call(r,t,n)})},e.prototype._checkIfMaximumSelected=function(e,n){var r=this;this.current(function(e){var t=null!=e?e.length:0;0=r.maximumSelectionLength?r.trigger("results:message",{message:"maximumSelected",args:{maximum:r.maximumSelectionLength}}):n&&n()})},e}),e.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t('');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define("select2/dropdown/search",["jquery","../utils"],function(o,e){function t(){}return t.prototype.render=function(e){var t=e.call(this),n=o('');return this.$searchContainer=n,this.$search=n.find("input"),t.prepend(n),t},t.prototype.bind=function(e,t,n){var r=this,i=t.id+"-results";e.call(this,t,n),this.$search.on("keydown",function(e){r.trigger("keypress",e),r._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){o(this).off("keyup")}),this.$search.on("keyup input",function(e){r.handleSearch(e)}),t.on("open",function(){r.$search.attr("tabindex",0),r.$search.attr("aria-controls",i),r.$search.trigger("focus"),window.setTimeout(function(){r.$search.trigger("focus")},0)}),t.on("close",function(){r.$search.attr("tabindex",-1),r.$search.removeAttr("aria-controls"),r.$search.removeAttr("aria-activedescendant"),r.$search.val(""),r.$search.trigger("blur")}),t.on("focus",function(){t.isOpen()||r.$search.trigger("focus")}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(r.showSearch(e)?r.$searchContainer.removeClass("select2-search--hide"):r.$searchContainer.addClass("select2-search--hide"))}),t.on("results:focus",function(e){e.data._resultId?r.$search.attr("aria-activedescendant",e.data._resultId):r.$search.removeAttr("aria-activedescendant")})},t.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},t.prototype.showSearch=function(e,t){return!0},t}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,r){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,r)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),r=t.length-1;0<=r;r--){var i=t[r];this.placeholder.id===i.id&&n.splice(r,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(n){function e(e,t,n,r){this.lastParams={},e.call(this,t,n,r),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("query",function(e){r.lastParams=e,r.loading=!0}),t.on("query:append",function(e){r.lastParams=e,r.loading=!0}),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);if(!this.loading&&e){var t=this.$results.offset().top+this.$results.outerHeight(!1);this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=t+50&&this.loadMore()}},e.prototype.loadMore=function(){this.loading=!0;var e=n.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=n('
                • '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=f(n.get("dropdownParent")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("open",function(){r._showDropdown(),r._attachPositioningHandler(t),r._bindContainerResultHandlers(t)}),t.on("close",function(){r._hideDropdown(),r._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(""),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var n=this;t.on("results:all",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:append",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:message",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("select",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("unselect",function(){n._positionDropdown(),n._resizeDropdown()}),this._containerResultsHandlersBound=!0}},e.prototype._attachPositioningHandler=function(e,t){var n=this,r="scroll.select2."+t.id,i="resize.select2."+t.id,o="orientationchange.select2."+t.id,s=this.$container.parents().filter(a.hasScroll);s.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),s.on(r,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(r+" "+i+" "+o,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,r="resize.select2."+t.id,i="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+r+" "+i)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown.hasClass("select2-dropdown--above"),n=this.$dropdown.hasClass("select2-dropdown--below"),r=null,i=this.$container.offset();i.bottom=i.top+this.$container.outerHeight(!1);var o={height:this.$container.outerHeight(!1)};o.top=i.top,o.bottom=i.top+o.height;var s=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ai.bottom+s,d={left:i.left,top:o.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h={top:0,left:0};(f.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),d.top-=h.top,d.left-=h.left,t||n||(r="below"),u||!c||t?!c&&u&&t&&(r="below"):r="above",("above"==r||t&&"below"!==r)&&(d.top=o.top-h.top-s),null!=r&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+r),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+r)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,r){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,r)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,r=0;r');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container.addClass("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("jquery-mousewheel",["jquery"],function(e){return e}),e.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(i,e,o,t,s){if(null==i.fn.select2){var a=["open","close","destroy"];i.fn.select2=function(t){if("object"==typeof(t=t||{}))return this.each(function(){var e=i.extend(!0,{},t);new o(i(this),e)}),this;if("string"!=typeof t)throw new Error("Invalid arguments for Select2: "+t);var n,r=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=s.GetData(this,"select2");null==e&&window.console&&console.error&&console.error("The select2('"+t+"') method was called on an element that is not using Select2."),n=e[t].apply(e,r)}),-1 2021-07-03 + - Introduced the concept of "API forms" in https://github.com/inventree/InvenTree/pull/1716 + - API OPTIONS endpoints provide comprehensive field metedata + - Multiple new API endpoints added for database models + v6 -> 2021-06-23 - Part and Company images can now be directly uploaded via the REST API diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py index 1cb973fe05..779c248fe5 100644 --- a/InvenTree/build/api.py +++ b/InvenTree/build/api.py @@ -11,11 +11,12 @@ from rest_framework import generics from django.conf.urls import url, include +from InvenTree.api import AttachmentMixin from InvenTree.helpers import str2bool, isNull from InvenTree.status_codes import BuildStatus -from .models import Build, BuildItem -from .serializers import BuildSerializer, BuildItemSerializer +from .models import Build, BuildItem, BuildOrderAttachment +from .serializers import BuildAttachmentSerializer, BuildSerializer, BuildItemSerializer class BuildList(generics.ListCreateAPIView): @@ -226,14 +227,40 @@ class BuildItemList(generics.ListCreateAPIView): ] -build_item_api_urls = [ - url('^.*$', BuildItemList.as_view(), name='api-build-item-list'), -] +class BuildAttachmentList(generics.ListCreateAPIView, AttachmentMixin): + """ + API endpoint for listing (and creating) BuildOrderAttachment objects + """ + + queryset = BuildOrderAttachment.objects.all() + serializer_class = BuildAttachmentSerializer + + +class BuildAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, AttachmentMixin): + """ + Detail endpoint for a BuildOrderAttachment object + """ + + queryset = BuildOrderAttachment.objects.all() + serializer_class = BuildAttachmentSerializer + build_api_urls = [ - url(r'^item/', include(build_item_api_urls)), + # Attachments + url(r'^attachment/', include([ + url(r'^(?P\d+)/', BuildAttachmentDetail.as_view(), name='api-build-attachment-detail'), + url('^.*$', BuildAttachmentList.as_view(), name='api-build-attachment-list'), + ])), + + # Build Items + url(r'^item/', include([ + url('^.*$', BuildItemList.as_view(), name='api-build-item-list') + ])), + + # Build Detail url(r'^(?P\d+)/', BuildDetail.as_view(), name='api-build-detail'), + # Build List url(r'^.*$', BuildList.as_view(), name='api-build-list'), ] diff --git a/InvenTree/build/forms.py b/InvenTree/build/forms.py index e60df22c21..e2ca7c3f75 100644 --- a/InvenTree/build/forms.py +++ b/InvenTree/build/forms.py @@ -15,7 +15,7 @@ from InvenTree.fields import DatePickerFormField from InvenTree.status_codes import StockStatus -from .models import Build, BuildItem, BuildOrderAttachment +from .models import Build, BuildItem from stock.models import StockLocation, StockItem @@ -275,17 +275,3 @@ class EditBuildItemForm(HelperForm): 'quantity', 'install_into', ] - - -class EditBuildAttachmentForm(HelperForm): - """ - Form for creating / editing a BuildAttachment object - """ - - class Meta: - model = BuildOrderAttachment - fields = [ - 'build', - 'attachment', - 'comment' - ] diff --git a/InvenTree/build/migrations/0029_auto_20210601_1525.py b/InvenTree/build/migrations/0029_auto_20210601_1525.py index e8b2d58947..fa6bab6b26 100644 --- a/InvenTree/build/migrations/0029_auto_20210601_1525.py +++ b/InvenTree/build/migrations/0029_auto_20210601_1525.py @@ -1,8 +1,13 @@ # Generated by Django 3.2 on 2021-06-01 05:25 +import logging + from django.db import migrations +logger = logging.getLogger('inventree') + + def assign_bom_items(apps, schema_editor): """ Run through existing BuildItem objects, @@ -13,7 +18,7 @@ def assign_bom_items(apps, schema_editor): BomItem = apps.get_model('part', 'bomitem') Part = apps.get_model('part', 'part') - print("Assigning BomItems to existing BuildItem objects") + logger.info("Assigning BomItems to existing BuildItem objects") count_valid = 0 count_total = 0 @@ -41,7 +46,7 @@ def assign_bom_items(apps, schema_editor): pass if count_total > 0: - print(f"Assigned BomItem for {count_valid}/{count_total} entries") + logger.info(f"Assigned BomItem for {count_valid}/{count_total} entries") def unassign_bom_items(apps, schema_editor): diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index fad5a2934d..848d774d1c 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -60,6 +60,10 @@ class Build(MPTTModel): responsible: User (or group) responsible for completing the build """ + @staticmethod + def get_api_url(): + return reverse('api-build-list') + OVERDUE_FILTER = Q(status__in=BuildStatus.ACTIVE_CODES) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date()) class Meta: @@ -1117,6 +1121,10 @@ class BuildItem(models.Model): quantity: Number of units allocated """ + @staticmethod + def get_api_url(): + return reverse('api-build-item-list') + def get_absolute_url(self): # TODO - Fix! return '/build/item/{pk}/'.format(pk=self.id) diff --git a/InvenTree/build/serializers.py b/InvenTree/build/serializers.py index d8573cfa70..e33fcb6c7f 100644 --- a/InvenTree/build/serializers.py +++ b/InvenTree/build/serializers.py @@ -10,13 +10,13 @@ from django.db.models import BooleanField from rest_framework import serializers -from InvenTree.serializers import InvenTreeModelSerializer +from InvenTree.serializers import InvenTreeModelSerializer, InvenTreeAttachmentSerializerField from stock.serializers import StockItemSerializerBrief from stock.serializers import LocationSerializer from part.serializers import PartSerializer, PartBriefSerializer -from .models import Build, BuildItem +from .models import Build, BuildItem, BuildOrderAttachment class BuildSerializer(InvenTreeModelSerializer): @@ -143,3 +143,26 @@ class BuildItemSerializer(InvenTreeModelSerializer): 'stock_item_detail', 'quantity' ] + + +class BuildAttachmentSerializer(InvenTreeModelSerializer): + """ + Serializer for a BuildAttachment + """ + + attachment = InvenTreeAttachmentSerializerField(required=True) + + class Meta: + model = BuildOrderAttachment + + fields = [ + 'pk', + 'build', + 'attachment', + 'comment', + 'upload_date', + ] + + read_only_fields = [ + 'upload_date', + ] diff --git a/InvenTree/build/templates/build/attachments.html b/InvenTree/build/templates/build/attachments.html index 8546ab42f5..e969756b81 100644 --- a/InvenTree/build/templates/build/attachments.html +++ b/InvenTree/build/templates/build/attachments.html @@ -22,7 +22,7 @@ enableDragAndDrop( '#attachment-dropzone', - '{% url "build-attachment-create" %}', + '{% url "api-build-attachment-list" %}', { data: { build: {{ build.id }}, @@ -36,45 +36,49 @@ enableDragAndDrop( // Callback for creating a new attachment $('#new-attachment').click(function() { - launchModalForm( - '{% url "build-attachment-create" %}', - { - reload: true, - data: { - build: {{ build.pk }}, + + constructForm('{% url "api-build-attachment-list" %}', { + fields: { + attachment: {}, + comment: {}, + build: { + value: {{ build.pk }}, + hidden: true, } - } - ); + }, + method: 'POST', + onSuccess: reloadAttachmentTable, + title: '{% trans "Add Attachment" %}', + }); }); -// Callback for editing an attachment -$("#attachment-table").on('click', '.attachment-edit-button', function() { - var pk = $(this).attr('pk'); +loadAttachmentTable( + '{% url "api-build-attachment-list" %}', + { + filters: { + build: {{ build.pk }}, + }, + onEdit: function(pk) { + var url = `/api/build/attachment/${pk}/`; - var url = `/build/attachment/${pk}/edit/`; + constructForm(url, { + fields: { + comment: {}, + }, + onSuccess: reloadAttachmentTable, + title: '{% trans "Edit Attachment" %}', + }); + }, + onDelete: function(pk) { - launchModalForm( - url, - { - reload: true, + constructForm(`/api/build/attachment/${pk}/`, { + method: 'DELETE', + confirmMessage: '{% trans "Confirm Delete Operation" %}', + title: '{% trans "Delete Attachment" %}', + onSuccess: reloadAttachmentTable, + }); } - ); -}); - -// Callback for deleting an attachment -$("#attachment-table").on('click', '.attachment-delete-button', function() { - var pk = $(this).attr('pk'); - - var url = `/build/attachment/${pk}/delete/`; - - launchModalForm( - url, - { - reload: true, - } - ); -}); - -$("#attachment-table").inventreeTable({}); + } +); {% endblock %} diff --git a/InvenTree/build/urls.py b/InvenTree/build/urls.py index 99b6b72818..549a20ee7e 100644 --- a/InvenTree/build/urls.py +++ b/InvenTree/build/urls.py @@ -36,12 +36,6 @@ build_urls = [ url('^new/', views.BuildItemCreate.as_view(), name='build-item-create'), ])), - url('^attachment/', include([ - url('^new/', views.BuildAttachmentCreate.as_view(), name='build-attachment-create'), - url(r'^(?P\d+)/edit/', views.BuildAttachmentEdit.as_view(), name='build-attachment-edit'), - url(r'^(?P\d+)/delete/', views.BuildAttachmentDelete.as_view(), name='build-attachment-delete'), - ])), - url(r'new/', views.BuildCreate.as_view(), name='build-create'), url(r'^(?P\d+)/', include(build_detail_urls)), diff --git a/InvenTree/build/views.py b/InvenTree/build/views.py index 6e72f7f3e6..16004dacc1 100644 --- a/InvenTree/build/views.py +++ b/InvenTree/build/views.py @@ -12,7 +12,7 @@ from django.forms import HiddenInput from django.urls import reverse from part.models import Part -from .models import Build, BuildItem, BuildOrderAttachment +from .models import Build, BuildItem from . import forms from stock.models import StockLocation, StockItem @@ -1058,88 +1058,3 @@ class BuildItemEdit(AjaxUpdateView): form.fields['install_into'].widget = HiddenInput() return form - - -class BuildAttachmentCreate(AjaxCreateView): - """ - View for creating a BuildAttachment - """ - - model = BuildOrderAttachment - form_class = forms.EditBuildAttachmentForm - ajax_form_title = _('Add Build Order Attachment') - - def save(self, form, **kwargs): - """ - Add information on the user that uploaded the attachment - """ - - attachment = form.save(commit=False) - attachment.user = self.request.user - attachment.save() - - def get_data(self): - return { - 'success': _('Added attachment') - } - - def get_initial(self): - """ - Get initial data for creating an attachment - """ - - initials = super().get_initial() - - try: - initials['build'] = Build.objects.get(pk=self.request.GET.get('build', -1)) - except (ValueError, Build.DoesNotExist): - pass - - return initials - - def get_form(self): - """ - Hide the 'build' field if specified - """ - - form = super().get_form() - - form.fields['build'].widget = HiddenInput() - - return form - - -class BuildAttachmentEdit(AjaxUpdateView): - """ - View for editing a BuildAttachment object - """ - - model = BuildOrderAttachment - form_class = forms.EditBuildAttachmentForm - ajax_form_title = _('Edit Attachment') - - def get_form(self): - form = super().get_form() - form.fields['build'].widget = HiddenInput() - - return form - - def get_data(self): - return { - 'success': _('Attachment updated') - } - - -class BuildAttachmentDelete(AjaxDeleteView): - """ - View for deleting a BuildAttachment - """ - - model = BuildOrderAttachment - ajax_form_title = _('Delete Attachment') - context_object_name = 'attachment' - - def get_data(self): - return { - 'danger': _('Deleted attachment') - } diff --git a/InvenTree/common/settings.py b/InvenTree/common/settings.py index e255ed0904..b34cf0b785 100644 --- a/InvenTree/common/settings.py +++ b/InvenTree/common/settings.py @@ -28,7 +28,7 @@ def currency_code_mappings(): """ Returns the current currency choices """ - return [(a, a) for a in settings.CURRENCIES] + return [(a, CURRENCIES[a].name) for a in settings.CURRENCIES] def currency_codes(): diff --git a/InvenTree/company/api.py b/InvenTree/company/api.py index 6cd1e83dfa..999e4e4039 100644 --- a/InvenTree/company/api.py +++ b/InvenTree/company/api.py @@ -394,6 +394,15 @@ class SupplierPriceBreakList(generics.ListCreateAPIView): ] +class SupplierPriceBreakDetail(generics.RetrieveUpdateDestroyAPIView): + """ + Detail endpoint for SupplierPriceBreak object + """ + + queryset = SupplierPriceBreak.objects.all() + serializer_class = SupplierPriceBreakSerializer + + manufacturer_part_api_urls = [ url(r'^parameter/', include([ @@ -424,7 +433,12 @@ company_api_urls = [ url(r'^part/', include(supplier_part_api_urls)), - url(r'^price-break/', SupplierPriceBreakList.as_view(), name='api-part-supplier-price'), + # Supplier price breaks + url(r'^price-break/', include([ + + url(r'^(?P\d+)/?', SupplierPriceBreakDetail.as_view(), name='api-part-supplier-price-detail'), + url(r'^.*$', SupplierPriceBreakList.as_view(), name='api-part-supplier-price-list'), + ])), url(r'^(?P\d+)/?', CompanyDetail.as_view(), name='api-company-detail'), diff --git a/InvenTree/company/forms.py b/InvenTree/company/forms.py index 564b5fab53..15f380ae44 100644 --- a/InvenTree/company/forms.py +++ b/InvenTree/company/forms.py @@ -11,62 +11,12 @@ from InvenTree.fields import InvenTreeMoneyField, RoundingDecimalFormField from django.utils.translation import ugettext_lazy as _ import django.forms -import djmoney.settings - -from common.settings import currency_code_default - -from .models import Company, ManufacturerPartParameter +from .models import Company from .models import ManufacturerPart from .models import SupplierPart from .models import SupplierPriceBreak -class EditCompanyForm(HelperForm): - """ Form for editing a Company object """ - - field_prefix = { - 'website': 'fa-globe-asia', - 'email': 'fa-at', - 'address': 'fa-envelope', - 'contact': 'fa-user-tie', - 'phone': 'fa-phone', - } - - currency = django.forms.ChoiceField( - required=False, - label=_('Currency'), - help_text=_('Default currency used for this company'), - choices=[('', '----------')] + djmoney.settings.CURRENCY_CHOICES, - initial=currency_code_default, - ) - - class Meta: - model = Company - fields = [ - 'name', - 'description', - 'website', - 'address', - 'currency', - 'phone', - 'email', - 'contact', - 'is_supplier', - 'is_manufacturer', - 'is_customer', - ] - - -class CompanyImageForm(HelperForm): - """ Form for uploading a Company image """ - - class Meta: - model = Company - fields = [ - 'image' - ] - - class CompanyImageDownloadForm(HelperForm): """ Form for downloading an image from a URL @@ -104,21 +54,6 @@ class EditManufacturerPartForm(HelperForm): ] -class EditManufacturerPartParameterForm(HelperForm): - """ - Form for creating / editing a ManufacturerPartParameter object - """ - - class Meta: - model = ManufacturerPartParameter - fields = [ - 'manufacturer_part', - 'name', - 'value', - 'units', - ] - - class EditSupplierPartForm(HelperForm): """ Form for editing a SupplierPart object """ diff --git a/InvenTree/company/migrations/0026_auto_20201110_1011.py b/InvenTree/company/migrations/0026_auto_20201110_1011.py index 20ec7d2f6f..29a5099c3a 100644 --- a/InvenTree/company/migrations/0026_auto_20201110_1011.py +++ b/InvenTree/company/migrations/0026_auto_20201110_1011.py @@ -1,5 +1,6 @@ # Generated by Django 3.0.7 on 2020-11-10 10:11 +import logging import sys from moneyed import CURRENCIES @@ -7,6 +8,9 @@ from django.db import migrations, connection from company.models import SupplierPriceBreak +logger = logging.getLogger('inventree') + + def migrate_currencies(apps, schema_editor): """ Migrate from the 'old' method of handling currencies, @@ -19,7 +23,7 @@ def migrate_currencies(apps, schema_editor): for the SupplierPriceBreak model, to a new django-money compatible currency. """ - print("Updating currency references for SupplierPriceBreak model...") + logger.info("Updating currency references for SupplierPriceBreak model...") # A list of available currency codes currency_codes = CURRENCIES.keys() @@ -39,7 +43,7 @@ def migrate_currencies(apps, schema_editor): suffix = suffix.strip().upper() if suffix not in currency_codes: - print("Missing suffix:", suffix) + logger.warning(f"Missing suffix: '{suffix}'") while suffix not in currency_codes: # Ask the user to input a valid currency @@ -72,7 +76,7 @@ def migrate_currencies(apps, schema_editor): count += 1 if count > 0: - print(f"Updated {count} SupplierPriceBreak rows") + logger.info(f"Updated {count} SupplierPriceBreak rows") def reverse_currencies(apps, schema_editor): """ diff --git a/InvenTree/company/migrations/0040_alter_company_currency.py b/InvenTree/company/migrations/0040_alter_company_currency.py new file mode 100644 index 0000000000..f26f470191 --- /dev/null +++ b/InvenTree/company/migrations/0040_alter_company_currency.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.4 on 2021-07-02 13:21 + +import InvenTree.validators +import common.settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('company', '0039_auto_20210701_0509'), + ] + + operations = [ + migrations.AlterField( + model_name='company', + name='currency', + field=models.CharField(blank=True, default=common.settings.currency_code_default, help_text='Default currency used for this company', max_length=3, validators=[InvenTree.validators.validate_currency_code], verbose_name='Currency'), + ), + ] diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 093d545f78..3786531311 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -31,6 +31,7 @@ import InvenTree.validators import common.models import common.settings +from common.settings import currency_code_default def rename_company_image(instance, filename): @@ -84,6 +85,10 @@ class Company(models.Model): currency_code: Specifies the default currency for the company """ + @staticmethod + def get_api_url(): + return reverse('api-company-list') + class Meta: ordering = ['name', ] constraints = [ @@ -101,7 +106,11 @@ class Company(models.Model): blank=True, ) - website = models.URLField(blank=True, verbose_name=_('Website'), help_text=_('Company website URL')) + website = models.URLField( + blank=True, + verbose_name=_('Website'), + help_text=_('Company website URL') + ) address = models.CharField(max_length=200, verbose_name=_('Address'), @@ -141,6 +150,7 @@ class Company(models.Model): max_length=3, verbose_name=_('Currency'), blank=True, + default=currency_code_default, help_text=_('Default currency used for this company'), validators=[InvenTree.validators.validate_currency_code], ) @@ -297,6 +307,10 @@ class ManufacturerPart(models.Model): description: Descriptive notes field """ + @staticmethod + def get_api_url(): + return reverse('api-manufacturer-part-list') + class Meta: unique_together = ('part', 'manufacturer', 'MPN') @@ -380,6 +394,10 @@ class ManufacturerPartParameter(models.Model): Each parameter is a simple string (text) value. """ + @staticmethod + def get_api_url(): + return reverse('api-manufacturer-part-parameter-list') + class Meta: unique_together = ('manufacturer_part', 'name') @@ -432,6 +450,10 @@ class SupplierPart(models.Model): packaging: packaging that the part is supplied in, e.g. "Reel" """ + @staticmethod + def get_api_url(): + return reverse('api-supplier-part-list') + def get_absolute_url(self): return reverse('supplier-part-detail', kwargs={'pk': self.id}) @@ -660,6 +682,10 @@ class SupplierPriceBreak(common.models.PriceBreak): currency: Reference to the currency of this pricebreak (leave empty for base currency) """ + @staticmethod + def get_api_url(): + return reverse('api-part-supplier-price-list') + part = models.ForeignKey(SupplierPart, on_delete=models.CASCADE, related_name='pricebreaks', verbose_name=_('Part'),) class Meta: diff --git a/InvenTree/company/serializers.py b/InvenTree/company/serializers.py index 1e97756987..276225624f 100644 --- a/InvenTree/company/serializers.py +++ b/InvenTree/company/serializers.py @@ -2,6 +2,8 @@ JSON serializers for Company app """ +from django.utils.translation import ugettext_lazy as _ + from rest_framework import serializers from sql_util.utils import SubqueryCount @@ -15,6 +17,8 @@ from .models import Company from .models import ManufacturerPart, ManufacturerPartParameter from .models import SupplierPart, SupplierPriceBreak +from common.settings import currency_code_default, currency_code_mappings + class CompanyBriefSerializer(InvenTreeModelSerializer): """ Serializer for Company object (limited detail) """ @@ -58,6 +62,14 @@ class CompanySerializer(InvenTreeModelSerializer): parts_supplied = serializers.IntegerField(read_only=True) parts_manufactured = serializers.IntegerField(read_only=True) + currency = serializers.ChoiceField( + choices=currency_code_mappings(), + initial=currency_code_default, + help_text=_('Default currency used for this supplier'), + label=_('Currency Code'), + required=True, + ) + class Meta: model = Company fields = [ @@ -70,6 +82,7 @@ class CompanySerializer(InvenTreeModelSerializer): 'phone', 'address', 'email', + 'currency', 'contact', 'link', 'image', @@ -167,9 +180,10 @@ class SupplierPartSerializer(InvenTreeModelSerializer): def __init__(self, *args, **kwargs): - part_detail = kwargs.pop('part_detail', False) - supplier_detail = kwargs.pop('supplier_detail', False) - manufacturer_detail = kwargs.pop('manufacturer_detail', False) + part_detail = kwargs.pop('part_detail', True) + supplier_detail = kwargs.pop('supplier_detail', True) + manufacturer_detail = kwargs.pop('manufacturer_detail', True) + prettify = kwargs.pop('pretty', False) super(SupplierPartSerializer, self).__init__(*args, **kwargs) @@ -239,6 +253,12 @@ class SupplierPriceBreakSerializer(InvenTreeModelSerializer): price = serializers.CharField() + price_currency = serializers.ChoiceField( + choices=currency_code_mappings(), + default=currency_code_default, + label=_('Currency'), + ) + class Meta: model = SupplierPriceBreak fields = [ @@ -246,4 +266,5 @@ class SupplierPriceBreakSerializer(InvenTreeModelSerializer): 'part', 'quantity', 'price', + 'price_currency', ] diff --git a/InvenTree/company/templates/company/company_base.html b/InvenTree/company/templates/company/company_base.html index a276f5df4f..8c6b077137 100644 --- a/InvenTree/company/templates/company/company_base.html +++ b/InvenTree/company/templates/company/company_base.html @@ -111,32 +111,31 @@ }); $('#company-edit').click(function() { - launchModalForm( - "{% url 'company-edit' company.id %}", - { - reload: true - }); + editCompany({{ company.id }}); }); $("#company-order-2").click(function() { - launchModalForm("{% url 'po-create' %}", - { - data: { - supplier: {{ company.id }}, - }, - follow: true, + createPurchaseOrder({ + supplier: {{ company.pk }}, }); }); - $('#company-delete').click(function() { - launchModalForm( - "{% url 'company-delete' company.id %}", - { - redirect: "{% url 'company-index' %}" - }); + constructForm('{% url "api-company-detail" company.pk %}', { + method: 'DELETE', + title: '{% trans "Delete Company" %}', + redirect: '{% url "company-index" %}', + }); }); + function reloadImage(data) { + if (data.image) { + $('#company-image').attr('src', data.image); + } else { + location.reload(); + } + } + enableDragAndDrop( "#company-thumb", "{% url 'api-company-detail' company.id %}", @@ -144,12 +143,7 @@ label: 'image', method: 'PATCH', success: function(data, status, xhr) { - - if (data.image) { - $('#company-image').attr('src', data.image); - } else { - location.reload(); - } + reloadImage(data); } } ); @@ -161,10 +155,18 @@ {% endif %} $("#company-image-upload").click(function() { - launchModalForm( - "{% url 'company-image' company.id %}", + + constructForm( + '{% url "api-company-detail" company.pk %}', { - reload: true + method: 'PATCH', + fields: { + image: {}, + }, + title: '{% trans "Upload Image" %}', + onSuccess: function(data) { + reloadImage(data); + } } ); }); diff --git a/InvenTree/company/templates/company/delete.html b/InvenTree/company/templates/company/delete.html deleted file mode 100644 index 3236a7a58d..0000000000 --- a/InvenTree/company/templates/company/delete.html +++ /dev/null @@ -1,21 +0,0 @@ -{% extends "modal_delete_form.html" %} - -{% load i18n %} - -{% block pre_form_content %} - -{% blocktrans with company.name as name %}Are you sure you want to delete company '{{ name }}'?{% endblocktrans %} - -
                  - -{% if company.supplied_part_count > 0 %} -

                  {% blocktrans with company.supplied_part_count as count %}There are {{ count }} parts sourced from this company.
                  -If this supplier is deleted, these supplier part entries will also be deleted.{% endblocktrans %}

                  -
                    -{% for part in company.parts.all %} -
                  • {{ part.SKU }} - {{ part.part.full_name }}
                  • -{% endfor %} -
                  -{% endif %} - -{% endblock %} \ No newline at end of file diff --git a/InvenTree/company/templates/company/detail_manufacturer_part.html b/InvenTree/company/templates/company/detail_manufacturer_part.html index 902d456eaf..992753e97b 100644 --- a/InvenTree/company/templates/company/detail_manufacturer_part.html +++ b/InvenTree/company/templates/company/detail_manufacturer_part.html @@ -25,7 +25,7 @@ {% endif %}
                  @@ -57,15 +60,26 @@ {% block js_ready %} {{ block.super }} +function reloadParameters() { + $("#parameter-table").bootstrapTable("refresh"); +} + $('#parameter-create').click(function() { - launchModalForm( - "{% url 'manufacturer-part-parameter-create' %}", - { - data: { - manufacturer_part: {{ part.id }}, + + constructForm('{% url "api-manufacturer-part-parameter-list" %}', { + method: 'POST', + fields: { + name: {}, + value: {}, + units: {}, + manufacturer_part: { + value: {{ part.pk }}, + hidden: true, } - } - ); + }, + title: '{% trans "Add Parameter" %}', + onSuccess: reloadParameters + }); }); $('#supplier-create').click(function () { @@ -81,7 +95,6 @@ $('#supplier-create').click(function () { field: 'supplier', label: '{% trans "New Supplier" %}', title: '{% trans "Create new supplier" %}', - url: "{% url 'supplier-create' %}" }, ] }); @@ -105,6 +118,46 @@ $("#supplier-part-delete").click(function() { }); }); +$("#multi-parameter-delete").click(function() { + + var selections = $("#parameter-table").bootstrapTable("getSelections"); + + var text = ` +
                  +

                  {% trans "Selected parameters will be deleted" %}:

                  +
                    `; + + selections.forEach(function(item) { + text += `
                  • ${item.name} - ${item.value}
                  • `; + }); + + text += ` +
                  +
                  `; + + showQuestionDialog( + '{% trans "Delete Parameters" %}', + text, + { + accept_text: '{% trans "Delete" %}', + accept: function() { + // Delete each parameter via the API + var requests = []; + + selections.forEach(function(item) { + var url = `/api/company/part/manufacturer/parameter/${item.pk}/`; + + requests.push(inventreeDelete(url)); + }); + + $.when.apply($, requests).then(function() { + $('#parameter-table').bootstrapTable('refresh'); + }); + } + } + ); +}); + loadSupplierPartTable( "#supplier-table", "{% url 'api-supplier-part-list' %}", @@ -130,5 +183,5 @@ loadManufacturerPartParameterTable( ); linkButtonsToSelection($("#supplier-table"), ['#supplier-part-options']) - +linkButtonsToSelection($("#parameter-table"), ['#parameter-options']) {% endblock %} \ No newline at end of file diff --git a/InvenTree/company/templates/company/purchase_orders.html b/InvenTree/company/templates/company/purchase_orders.html index 0403c8cc59..f23d360a8f 100644 --- a/InvenTree/company/templates/company/purchase_orders.html +++ b/InvenTree/company/templates/company/purchase_orders.html @@ -39,14 +39,9 @@ } }); - function newOrder() { - launchModalForm("{% url 'po-create' %}", - { - data: { - supplier: {{ company.id }}, - }, - follow: true, + createPurchaseOrder({ + supplier: {{ company.pk }}, }); } diff --git a/InvenTree/company/templates/company/sales_orders.html b/InvenTree/company/templates/company/sales_orders.html index e8585e2caa..c21a9afc21 100644 --- a/InvenTree/company/templates/company/sales_orders.html +++ b/InvenTree/company/templates/company/sales_orders.html @@ -42,15 +42,10 @@ }); $("#new-sales-order").click(function() { - launchModalForm( - "{% url 'so-create' %}", - { - data: { - customer: {{ company.id }}, - }, - follow: true, - }, - ); + + createSalesOrder({ + customer: {{ company.pk }}, + }); }); {% endblock %} \ No newline at end of file diff --git a/InvenTree/company/templates/company/supplier_part_pricing.html b/InvenTree/company/templates/company/supplier_part_pricing.html index 9da3f3df7e..a476b53a13 100644 --- a/InvenTree/company/templates/company/supplier_part_pricing.html +++ b/InvenTree/company/templates/company/supplier_part_pricing.html @@ -39,30 +39,32 @@ $('#price-break-table').inventreeTable({ queryParams: { part: {{ part.id }}, }, - url: "{% url 'api-part-supplier-price' %}", + url: "{% url 'api-part-supplier-price-list' %}", onPostBody: function() { var table = $('#price-break-table'); table.find('.button-price-break-delete').click(function() { var pk = $(this).attr('pk'); - launchModalForm( - `/price-break/${pk}/delete/`, - { - success: reloadPriceBreaks - } - ); + constructForm(`/api/company/price-break/${pk}/`, { + method: 'DELETE', + onSuccess: reloadPriceBreaks, + title: '{% trans "Delete Price Break" %}', + }); }); table.find('.button-price-break-edit').click(function() { var pk = $(this).attr('pk'); - launchModalForm( - `/price-break/${pk}/edit/`, - { - success: reloadPriceBreaks - } - ); + constructForm(`/api/company/price-break/${pk}/`, { + fields: { + quantity: {}, + price: {}, + price_currency: {}, + }, + onSuccess: reloadPriceBreaks, + title: '{% trans "Edit Price Break" %}', + }); }); }, columns: [ @@ -98,12 +100,23 @@ $('#price-break-table').inventreeTable({ }); $('#new-price-break').click(function() { - launchModalForm("{% url 'price-break-create' %}", + + constructForm( + '{% url "api-part-supplier-price-list" %}', { - reload: true, - data: { - part: {{ part.id }}, - } + method: 'POST', + fields: { + quantity: {}, + part: { + value: {{ part.pk }}, + hidden: true, + }, + price: {}, + price_currency: { + }, + }, + title: '{% trans "Add Price Break" %}', + onSuccess: reloadPriceBreaks, } ); }); diff --git a/InvenTree/company/test_api.py b/InvenTree/company/test_api.py index dd42b97801..40176c7634 100644 --- a/InvenTree/company/test_api.py +++ b/InvenTree/company/test_api.py @@ -20,7 +20,7 @@ class CompanyTest(InvenTreeAPITestCase): super().setUp() - Company.objects.create(name='ACME', description='Supplier', is_customer=False, is_supplier=True) + self.acme = Company.objects.create(name='ACME', description='Supplier', is_customer=False, is_supplier=True) Company.objects.create(name='Drippy Cup Co.', description='Customer', is_customer=True, is_supplier=False) Company.objects.create(name='Sippy Cup Emporium', description='Another supplier') @@ -44,7 +44,11 @@ class CompanyTest(InvenTreeAPITestCase): self.assertEqual(len(response.data), 2) def test_company_detail(self): - url = reverse('api-company-detail', kwargs={'pk': 1}) + """ + Tests for the Company detail endpoint + """ + + url = reverse('api-company-detail', kwargs={'pk': self.acme.pk}) response = self.get(url) self.assertEqual(response.data['name'], 'ACME') @@ -52,22 +56,93 @@ class CompanyTest(InvenTreeAPITestCase): # Change the name of the company # Note we should not have the correct permissions (yet) data = response.data - data['name'] = 'ACMOO' response = self.client.patch(url, data, format='json', expected_code=400) self.assignRole('company.change') + # Update the name and set the currency to a valid value + data['name'] = 'ACMOO' + data['currency'] = 'NZD' + response = self.client.patch(url, data, format='json', expected_code=200) self.assertEqual(response.data['name'], 'ACMOO') + self.assertEqual(response.data['currency'], 'NZD') def test_company_search(self): - # Test search functionality in company list + """ + Test search functionality in company list + """ + url = reverse('api-company-list') data = {'search': 'cup'} response = self.get(url, data) self.assertEqual(len(response.data), 2) + def test_company_create(self): + """ + Test that we can create a company via the API! + """ + + url = reverse('api-company-list') + + # Name is required + response = self.post( + url, + { + 'description': 'A description!', + }, + expected_code=400 + ) + + # Minimal example, checking default values + response = self.post( + url, + { + 'name': 'My API Company', + 'description': 'A company created via the API', + }, + expected_code=201 + ) + + self.assertTrue(response.data['is_supplier']) + self.assertFalse(response.data['is_customer']) + self.assertFalse(response.data['is_manufacturer']) + + self.assertEqual(response.data['currency'], 'USD') + + # Maximal example, specify values + response = self.post( + url, + { + 'name': "Another Company", + 'description': "Also created via the API!", + 'currency': 'AUD', + 'is_supplier': False, + 'is_manufacturer': True, + 'is_customer': True, + }, + expected_code=201 + ) + + self.assertEqual(response.data['currency'], 'AUD') + self.assertFalse(response.data['is_supplier']) + self.assertTrue(response.data['is_customer']) + self.assertTrue(response.data['is_manufacturer']) + + # Attempt to create with invalid currency + response = self.post( + url, + { + 'name': "A name", + 'description': 'A description', + 'currency': 'POQD', + }, + expected_code=400 + ) + + self.assertTrue('currency' in response.data) + class ManufacturerTest(InvenTreeAPITestCase): """ @@ -115,6 +190,9 @@ class ManufacturerTest(InvenTreeAPITestCase): self.assertEqual(len(response.data), 2) def test_manufacturer_part_detail(self): + """ + Tests for the ManufacturerPart detail endpoint + """ url = reverse('api-manufacturer-part-detail', kwargs={'pk': 1}) response = self.get(url) diff --git a/InvenTree/company/test_views.py b/InvenTree/company/test_views.py index cdb2d32af9..4c53bbb8c4 100644 --- a/InvenTree/company/test_views.py +++ b/InvenTree/company/test_views.py @@ -188,21 +188,6 @@ class CompanyViewTest(CompanyViewTestBase): response = self.client.get(reverse('company-index')) self.assertEqual(response.status_code, 200) - def test_company_create(self): - """ - Test the view for creating a company - """ - - # Check that different company types return different form titles - response = self.client.get(reverse('supplier-create'), HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertContains(response, 'Create new Supplier') - - response = self.client.get(reverse('manufacturer-create'), HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertContains(response, 'Create new Manufacturer') - - response = self.client.get(reverse('customer-create'), HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertContains(response, 'Create new Customer') - class ManufacturerPartViewTests(CompanyViewTestBase): """ @@ -274,33 +259,3 @@ class ManufacturerPartViewTests(CompanyViewTestBase): # Check that the ManufacturerPart was created! self.assertEqual(n + 1, ManufacturerPart.objects.all().count()) - - def test_manufacturer_part_delete(self): - """ - Test the ManufacturerPartDelete view - """ - - url = reverse('manufacturer-part-delete') - - # Get form using 'part' argument - response = self.client.get(url, {'part': '2'}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - - # POST to delete manufacturer part - n = ManufacturerPart.objects.count() - m = SupplierPart.objects.count() - - response = self.client.post( - url, - { - 'manufacturer-part-2': 'manufacturer-part-2', - 'confirm_delete': True - }, - HTTP_X_REQUESTED_WITH='XMLHttpRequest') - - self.assertEqual(response.status_code, 200) - - # Check that the ManufacturerPart was deleted - self.assertEqual(n - 1, ManufacturerPart.objects.count()) - # Check that the SupplierParts were deleted - self.assertEqual(m - 2, SupplierPart.objects.count()) diff --git a/InvenTree/company/urls.py b/InvenTree/company/urls.py index 51aa81f1c7..4fe0519ea9 100644 --- a/InvenTree/company/urls.py +++ b/InvenTree/company/urls.py @@ -8,9 +8,6 @@ from . import views company_detail_urls = [ - url(r'edit/?', views.CompanyEdit.as_view(), name='company-edit'), - url(r'delete/?', views.CompanyDelete.as_view(), name='company-delete'), - # url(r'orders/?', views.CompanyDetail.as_view(template_name='company/orders.html'), name='company-detail-orders'), url(r'^supplier-parts/', views.CompanyDetail.as_view(template_name='company/detail_supplier_part.html'), name='company-detail-supplier-parts'), @@ -21,7 +18,6 @@ company_detail_urls = [ url(r'^sales-orders/', views.CompanyDetail.as_view(template_name='company/sales_orders.html'), name='company-detail-sales-orders'), url(r'^notes/', views.CompanyNotes.as_view(), name='company-notes'), - url(r'^thumbnail/', views.CompanyImage.as_view(), name='company-image'), url(r'^thumb-download/', views.CompanyImageDownloadFromURL.as_view(), name='company-image-download'), # Any other URL @@ -31,11 +27,6 @@ company_detail_urls = [ company_urls = [ - url(r'new/supplier/', views.CompanyCreate.as_view(), name='supplier-create'), - url(r'new/manufacturer/', views.CompanyCreate.as_view(), name='manufacturer-create'), - url(r'new/customer/', views.CompanyCreate.as_view(), name='customer-create'), - url(r'new/?', views.CompanyCreate.as_view(), name='company-create'), - url(r'^(?P\d+)/', include(company_detail_urls)), url(r'suppliers/', views.CompanyIndex.as_view(), name='supplier-index'), @@ -46,29 +37,10 @@ company_urls = [ url(r'^.*$', views.CompanyIndex.as_view(), name='company-index'), ] -price_break_urls = [ - url('^new/', views.PriceBreakCreate.as_view(), name='price-break-create'), - - url(r'^(?P\d+)/edit/', views.PriceBreakEdit.as_view(), name='price-break-edit'), - url(r'^(?P\d+)/delete/', views.PriceBreakDelete.as_view(), name='price-break-delete'), -] - manufacturer_part_urls = [ url(r'^new/?', views.ManufacturerPartCreate.as_view(), name='manufacturer-part-create'), - url(r'^delete/', views.ManufacturerPartDelete.as_view(), name='manufacturer-part-delete'), - - # URLs for ManufacturerPartParameter views (create / edit / delete) - url(r'^parameter/', include([ - url(r'^new/', views.ManufacturerPartParameterCreate.as_view(), name='manufacturer-part-parameter-create'), - url(r'^(?P\d)/', include([ - url(r'^edit/', views.ManufacturerPartParameterEdit.as_view(), name='manufacturer-part-parameter-edit'), - url(r'^delete/', views.ManufacturerPartParameterDelete.as_view(), name='manufacturer-part-parameter-delete'), - ])), - ])), - url(r'^(?P\d+)/', include([ - url(r'^edit/?', views.ManufacturerPartEdit.as_view(), name='manufacturer-part-edit'), url(r'^suppliers/', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part_suppliers.html'), name='manufacturer-part-suppliers'), url('^.*$', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part_suppliers.html'), name='manufacturer-part-detail'), ])), diff --git a/InvenTree/company/views.py b/InvenTree/company/views.py index 74a583710a..60c37a392a 100644 --- a/InvenTree/company/views.py +++ b/InvenTree/company/views.py @@ -23,18 +23,14 @@ from InvenTree.views import AjaxCreateView, AjaxUpdateView, AjaxDeleteView from InvenTree.helpers import str2bool from InvenTree.views import InvenTreeRoleMixin -from .models import Company, ManufacturerPartParameter +from .models import Company from .models import ManufacturerPart from .models import SupplierPart -from .models import SupplierPriceBreak from part.models import Part -from .forms import EditCompanyForm, EditManufacturerPartParameterForm -from .forms import CompanyImageForm from .forms import EditManufacturerPartForm from .forms import EditSupplierPartForm -from .forms import EditPriceBreakForm from .forms import CompanyImageDownloadForm import common.models @@ -63,21 +59,18 @@ class CompanyIndex(InvenTreeRoleMixin, ListView): 'title': _('Suppliers'), 'button_text': _('New Supplier'), 'filters': {'is_supplier': 'true'}, - 'create_url': reverse('supplier-create'), 'pagetype': 'suppliers', }, reverse('manufacturer-index'): { 'title': _('Manufacturers'), 'button_text': _('New Manufacturer'), 'filters': {'is_manufacturer': 'true'}, - 'create_url': reverse('manufacturer-create'), 'pagetype': 'manufacturers', }, reverse('customer-index'): { 'title': _('Customers'), 'button_text': _('New Customer'), 'filters': {'is_customer': 'true'}, - 'create_url': reverse('customer-create'), 'pagetype': 'customers', } } @@ -86,7 +79,6 @@ class CompanyIndex(InvenTreeRoleMixin, ListView): 'title': _('Companies'), 'button_text': _('New Company'), 'filters': {}, - 'create_url': reverse('company-create'), 'pagetype': 'companies' } @@ -236,103 +228,6 @@ class CompanyImageDownloadFromURL(AjaxUpdateView): ) -class CompanyImage(AjaxUpdateView): - """ View for uploading an image for the Company """ - model = Company - ajax_template_name = 'modal_form.html' - ajax_form_title = _('Update Company Image') - form_class = CompanyImageForm - permission_required = 'company.change_company' - - def get_data(self): - return { - 'success': _('Updated company image'), - } - - -class CompanyEdit(AjaxUpdateView): - """ View for editing a Company object """ - model = Company - form_class = EditCompanyForm - context_object_name = 'company' - ajax_template_name = 'modal_form.html' - ajax_form_title = _('Edit Company') - permission_required = 'company.change_company' - - def get_data(self): - return { - 'info': _('Edited company information'), - } - - -class CompanyCreate(AjaxCreateView): - """ View for creating a new Company object """ - model = Company - context_object_name = 'company' - form_class = EditCompanyForm - ajax_template_name = 'modal_form.html' - permission_required = 'company.add_company' - - def get_form_title(self): - - url = self.request.path - - if url == reverse('supplier-create'): - return _("Create new Supplier") - - if url == reverse('manufacturer-create'): - return _('Create new Manufacturer') - - if url == reverse('customer-create'): - return _('Create new Customer') - - return _('Create new Company') - - def get_initial(self): - """ Initial values for the form data """ - initials = super().get_initial().copy() - - url = self.request.path - - if url == reverse('supplier-create'): - initials['is_supplier'] = True - initials['is_customer'] = False - initials['is_manufacturer'] = False - - elif url == reverse('manufacturer-create'): - initials['is_manufacturer'] = True - initials['is_supplier'] = True - initials['is_customer'] = False - - elif url == reverse('customer-create'): - initials['is_customer'] = True - initials['is_manufacturer'] = False - initials['is_supplier'] = False - - return initials - - def get_data(self): - return { - 'success': _("Created new company"), - } - - -class CompanyDelete(AjaxDeleteView): - """ View for deleting a Company object """ - - model = Company - success_url = '/company/' - ajax_template_name = 'company/delete.html' - ajax_form_title = _('Delete Company') - context_object_name = 'company' - permission_required = 'company.delete_company' - - def get_data(self): - return { - 'danger': _('Company was deleted'), - } - - class ManufacturerPartDetail(DetailView): """ Detail view for ManufacturerPart """ model = ManufacturerPart @@ -347,16 +242,6 @@ class ManufacturerPartDetail(DetailView): return ctx -class ManufacturerPartEdit(AjaxUpdateView): - """ Update view for editing ManufacturerPart """ - - model = ManufacturerPart - context_object_name = 'part' - form_class = EditManufacturerPartForm - ajax_template_name = 'modal_form.html' - ajax_form_title = _('Edit Manufacturer Part') - - class ManufacturerPartCreate(AjaxCreateView): """ Create view for making new ManufacturerPart """ @@ -425,145 +310,6 @@ class ManufacturerPartCreate(AjaxCreateView): return initials -class ManufacturerPartDelete(AjaxDeleteView): - """ Delete view for removing a ManufacturerPart. - - ManufacturerParts can be deleted using a variety of 'selectors'. - - - ?part= -> Delete a single ManufacturerPart object - - ?parts=[] -> Delete a list of ManufacturerPart objects - - """ - - success_url = '/manufacturer/' - ajax_template_name = 'company/manufacturer_part_delete.html' - ajax_form_title = _('Delete Manufacturer Part') - - role_required = 'purchase_order.delete' - - parts = [] - - def get_context_data(self): - ctx = {} - - ctx['parts'] = self.parts - - return ctx - - def get_parts(self): - """ Determine which ManufacturerPart object(s) the user wishes to delete. - """ - - self.parts = [] - - # User passes a single ManufacturerPart ID - if 'part' in self.request.GET: - try: - self.parts.append(ManufacturerPart.objects.get(pk=self.request.GET.get('part'))) - except (ValueError, ManufacturerPart.DoesNotExist): - pass - - elif 'parts[]' in self.request.GET: - - part_id_list = self.request.GET.getlist('parts[]') - - self.parts = ManufacturerPart.objects.filter(id__in=part_id_list) - - def get(self, request, *args, **kwargs): - self.request = request - self.get_parts() - - return self.renderJsonResponse(request, form=self.get_form()) - - def post(self, request, *args, **kwargs): - """ Handle the POST action for deleting ManufacturerPart object. - """ - - self.request = request - self.parts = [] - - for item in self.request.POST: - if item.startswith('manufacturer-part-'): - pk = item.replace('manufacturer-part-', '') - - try: - self.parts.append(ManufacturerPart.objects.get(pk=pk)) - except (ValueError, ManufacturerPart.DoesNotExist): - pass - - confirm = str2bool(self.request.POST.get('confirm_delete', False)) - - data = { - 'form_valid': confirm, - } - - if confirm: - for part in self.parts: - part.delete() - - return self.renderJsonResponse(self.request, data=data, form=self.get_form()) - - -class ManufacturerPartParameterCreate(AjaxCreateView): - """ - View for creating a new ManufacturerPartParameter object - """ - - model = ManufacturerPartParameter - form_class = EditManufacturerPartParameterForm - ajax_form_title = _('Add Manufacturer Part Parameter') - - def get_form(self): - - form = super().get_form() - - # Hide the manufacturer_part field if specified - if form.initial.get('manufacturer_part', None): - form.fields['manufacturer_part'].widget = HiddenInput() - - return form - - def get_initial(self): - - initials = super().get_initial().copy() - - manufacturer_part = self.get_param('manufacturer_part') - - if manufacturer_part: - try: - initials['manufacturer_part'] = ManufacturerPartParameter.objects.get(pk=manufacturer_part) - except (ValueError, ManufacturerPartParameter.DoesNotExist): - pass - - return initials - - -class ManufacturerPartParameterEdit(AjaxUpdateView): - """ - View for editing a ManufacturerPartParameter object - """ - - model = ManufacturerPartParameter - form_class = EditManufacturerPartParameterForm - ajax_form_title = _('Edit Manufacturer Part Parameter') - - def get_form(self): - - form = super().get_form() - - form.fields['manufacturer_part'].widget = HiddenInput() - - return form - - -class ManufacturerPartParameterDelete(AjaxDeleteView): - """ - View for deleting a ManufacturerPartParameter object - """ - - model = ManufacturerPartParameter - - class SupplierPartDetail(DetailView): """ Detail view for SupplierPart """ model = SupplierPart @@ -845,88 +591,3 @@ class SupplierPartDelete(AjaxDeleteView): part.delete() return self.renderJsonResponse(self.request, data=data, form=self.get_form()) - - -class PriceBreakCreate(AjaxCreateView): - """ View for creating a supplier price break """ - - model = SupplierPriceBreak - form_class = EditPriceBreakForm - ajax_form_title = _('Add Price Break') - ajax_template_name = 'modal_form.html' - - def get_data(self): - return { - 'success': _('Added new price break') - } - - def get_part(self): - """ - Attempt to extract SupplierPart object from the supplied data. - """ - - try: - supplier_part = SupplierPart.objects.get(pk=self.request.GET.get('part')) - return supplier_part - except (ValueError, SupplierPart.DoesNotExist): - pass - - try: - supplier_part = SupplierPart.objects.get(pk=self.request.POST.get('part')) - return supplier_part - except (ValueError, SupplierPart.DoesNotExist): - pass - - return None - - def get_form(self): - - form = super(AjaxCreateView, self).get_form() - form.fields['part'].widget = HiddenInput() - - return form - - def get_initial(self): - - initials = super(AjaxCreateView, self).get_initial() - - supplier_part = self.get_part() - - initials['part'] = self.get_part() - - if supplier_part is not None: - currency_code = supplier_part.supplier.currency_code - else: - currency_code = common.settings.currency_code_default() - - # Extract the currency object associated with the code - currency = CURRENCIES.get(currency_code, None) - - if currency: - initials['price'] = [1.0, currency] - - return initials - - -class PriceBreakEdit(AjaxUpdateView): - """ View for editing a supplier price break """ - - model = SupplierPriceBreak - form_class = EditPriceBreakForm - ajax_form_title = _('Edit Price Break') - ajax_template_name = 'modal_form.html' - - def get_form(self): - - form = super(AjaxUpdateView, self).get_form() - form.fields['part'].widget = HiddenInput() - - return form - - -class PriceBreakDelete(AjaxDeleteView): - """ View for deleting a supplier price break """ - - model = SupplierPriceBreak - ajax_form_title = _("Delete Price Break") - ajax_template_name = 'modal_delete_form.html' diff --git a/InvenTree/label/models.py b/InvenTree/label/models.py index a5d8314193..8a6684d7e3 100644 --- a/InvenTree/label/models.py +++ b/InvenTree/label/models.py @@ -12,6 +12,7 @@ import datetime from django.conf import settings from django.db import models +from django.urls import reverse from django.core.validators import FileExtensionValidator, MinValueValidator from django.core.exceptions import ValidationError, FieldError @@ -237,6 +238,10 @@ class StockItemLabel(LabelTemplate): Template for printing StockItem labels """ + @staticmethod + def get_api_url(): + return reverse('api-stockitem-label-list') + SUBDIR = "stockitem" filters = models.CharField( @@ -290,6 +295,10 @@ class StockLocationLabel(LabelTemplate): Template for printing StockLocation labels """ + @staticmethod + def get_api_url(): + return reverse('api-stocklocation-label-list') + SUBDIR = "stocklocation" filters = models.CharField( diff --git a/InvenTree/locale/de/LC_MESSAGES/django.po b/InvenTree/locale/de/LC_MESSAGES/django.po index 3ce90dc928..e1e9574e65 100644 --- a/InvenTree/locale/de/LC_MESSAGES/django.po +++ b/InvenTree/locale/de/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" -"PO-Revision-Date: 2021-06-24 21:40\n" +"POT-Creation-Date: 2021-07-01 22:35+0000\n" +"PO-Revision-Date: 2021-07-01 22:38\n" "Last-Translator: \n" "Language-Team: German\n" "Language: de_DE\n" @@ -29,14 +29,14 @@ msgstr "Keine Aktion angegeben" msgid "No matching action found" msgstr "Keine passende Aktion gefunden" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "Datum eingeben" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "Bestätigen" @@ -72,41 +72,41 @@ msgstr "Thema anwenden" msgid "Select Category" msgstr "Kategorie auswählen" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Doppelte Seriennummer: {n}" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "Keine gültige Menge" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "Keine Seriennummer angegeben" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "Ungültige Gruppe: {g}" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "Doppelte Seriennummer: {g}" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "Keine Seriennummern gefunden" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, 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" -#: InvenTree/models.py:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "Anhang" @@ -147,7 +147,7 @@ msgstr "Name" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -155,7 +155,7 @@ msgstr "Name" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -172,23 +172,23 @@ msgstr "Beschreibung (optional)" msgid "parent" msgstr "Eltern" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "Englisch" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "Französisch" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "Deutsch" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "Polnisch" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "Türkisch" @@ -446,11 +446,11 @@ msgid "Order target date" msgstr "geplantes Bestelldatum" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "Zieldatum" @@ -463,11 +463,11 @@ msgstr "Zieldatum für Bauauftrag-Fertigstellung." #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -476,7 +476,7 @@ msgstr "Zieldatum für Bauauftrag-Fertigstellung." #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -486,8 +486,8 @@ msgstr "Zieldatum für Bauauftrag-Fertigstellung." #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -501,7 +501,7 @@ msgstr "Anzahl der zu bauenden Teile" msgid "Enter quantity for build output" msgstr "Menge der Endprodukte angeben" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "Seriennummer" @@ -534,7 +534,7 @@ msgstr "Bauauftrag als vollständig markieren" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "Lagerort" @@ -544,10 +544,10 @@ msgid "Location of completed parts" msgstr "Lagerort der Endprodukte" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -592,8 +592,8 @@ msgstr "Bauauftrag" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -603,12 +603,12 @@ msgstr "Bauaufträge" msgid "Build Order Reference" msgstr "Bauauftragsreferenz" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "Referenz" @@ -628,7 +628,7 @@ msgstr "Bauauftrag, zu dem dieser Bauauftrag zugwiesen ist" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -643,8 +643,8 @@ msgstr "Bauauftrag, zu dem dieser Bauauftrag zugwiesen ist" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -703,7 +703,7 @@ msgstr "Bauauftrags-Status" msgid "Build status code" msgstr "Bau-Statuscode" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "Losnummer" @@ -711,16 +711,16 @@ msgstr "Losnummer" msgid "Batch code for this build output" msgstr "Losnummer für dieses Endprodukt" -#: build/models.py:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "Erstelldatum" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "geplantes Fertigstellungsdatum" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "Fertigstellungsdatum" @@ -737,7 +737,7 @@ msgid "User who issued this build order" msgstr "Nutzer der diesen Bauauftrag erstellt hat" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -754,30 +754,30 @@ msgstr "Nutzer der für diesen Bauauftrag zuständig ist" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "Externer Link" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "Link zu einer externen URL" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "Notizen" @@ -810,11 +810,11 @@ msgstr "Bauauftragsposition muss ein Endprodukt festlegen, da der übergeordnete msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "Reserviermenge ({n}) muss kleiner Bestandsmenge ({q}) sein. Zugewiesene Anzahl ({n}) darf nicht die verfügbare ({q}) Anzahl überschreiten" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "Zu viele BestandsObjekt zugewiesen" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "Reserviermenge muss größer null sein" @@ -828,7 +828,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "Ausgewähltes BestandsObjekt nicht Stückliste für Teil '{p}' gefunden" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "Bauauftrag" @@ -841,7 +841,7 @@ msgstr "Bauauftrag starten um Teile zuzuweisen" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -879,7 +879,7 @@ msgstr "Lagerbestand Bauauftrag zuweisen" msgid "Auto Allocate" msgstr "Automatisch zuweisen" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "Bestandszuordnung aufheben" @@ -893,8 +893,8 @@ msgstr "Benötigte Teile bestellen" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "Teile bestellen" @@ -915,16 +915,16 @@ msgstr "Dieser Bauauftrag hat keine zugeordneten Stücklisten-Einträge" #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "Seriennummer" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "Anhänge" @@ -977,7 +977,7 @@ msgstr "Lagerbestand wurde Bauauftrag noch nicht vollständig zugewiesen" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1036,7 +1036,7 @@ msgid "Progress" msgstr "Fortschritt" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1183,7 +1183,7 @@ msgstr "Ausgangs-Lager" msgid "Stock can be taken from any available location." msgstr "Bestand kann jedem verfügbaren Lagerort entnommen werden." -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1203,7 +1203,7 @@ msgstr "Losnummer" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "Erstellt" @@ -1211,7 +1211,7 @@ msgstr "Erstellt" msgid "No target date set" msgstr "Kein Ziel-Datum gesetzt" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "Fertig" @@ -1250,7 +1250,7 @@ msgstr "Bauauftrag-details" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "Details" @@ -1412,8 +1412,8 @@ msgstr "Teil muss aktuell im Bestand sein" msgid "Stock item is over-allocated" msgstr "BestandObjekt ist zu oft zugewiesen" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "Verfügbar" @@ -1433,56 +1433,56 @@ msgstr "Bauobjekt aktualisiert" msgid "Add Build Order Attachment" msgstr "Bauauftrags-Anhang hinzufügen" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "Anhang hinzugefügt" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "Anhang bearbeiten" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "Anhang aktualisiert" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "Anhang löschen" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "Anhang gelöscht" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "Dateiformat nicht unterstützt: {ext.upper()}" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "Fehler beim Lesen der Datei (ungültiges Format)" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "Fehler beim Lesen der Datei (falsche Größe)" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "Fehler beim Lesen der Datei (Daten könnten beschädigt sein)" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "Datei" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "Datei zum Hochladen auswählen" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "{name.title()} Datei" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "{name} Datei zum Hochladen auswählen" @@ -1520,335 +1520,359 @@ msgid "Base URL for server instance" msgstr "Basis-URL für dieses Instanz" #: common/models.py:85 +msgid "Default Currency" +msgstr "" + +#: common/models.py:86 +msgid "Default currency" +msgstr "" + +#: common/models.py:92 msgid "Download from URL" msgstr "Von URL herunterladen" -#: common/models.py:86 +#: common/models.py:93 msgid "Allow download of remote images and files from external URL" msgstr "Herunterladen von externen Bildern und Dateien von URLs erlaubt" -#: common/models.py:92 +#: common/models.py:99 msgid "Barcode Support" msgstr "Bacode-Feature verwenden" -#: common/models.py:93 +#: common/models.py:100 msgid "Enable barcode scanner support" msgstr "Barcode-Scanner Unterstützung" -#: common/models.py:99 +#: common/models.py:106 msgid "IPN Regex" msgstr "IPN Regex" -#: common/models.py:100 +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "RegEx Muster für die Zuordnung von Teil-IPN" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "Mehrere Artikel mit gleicher IPN erlaubt" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "Mehrere Artikel mit gleicher IPN erlaubt" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "Ändern von IPN erlaubt" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "Ändern der IPN während des Bearbeiten eines Teils erlaubt" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "Teil-Stückliste kopieren" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "Stückliste von Teil kopieren wenn das Teil dupliziert wird " -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "Teil-Parameter kopieren" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "Parameter-Daten für dieses Teil kopieren wenn das Teil dupliziert wird" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "Teil-Testdaten kopieren" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "Test-Daten für dieses Teil kopieren wenn das Teil dupliziert wird" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "Kategorie-Parametervorlage kopieren" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "Kategorie-Parameter Vorlagen kopieren wenn ein Teil angelegt wird" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "Aktuelle Teile-Stände" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "Anzahl der neusten Teile auf der Startseite" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "Vorlage" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "Teile sind standardmäßig Vorlagen" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "Baugruppe" -#: common/models.py:161 +#: common/models.py:168 msgid "Parts can be assembled from other components by default" msgstr "Teile können standardmäßig aus anderen Teilen angefertigt werden" -#: common/models.py:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "Komponente" -#: common/models.py:168 +#: common/models.py:175 msgid "Parts can be used as sub-components by default" msgstr "Teile können standardmäßig in Baugruppen benutzt werden" -#: common/models.py:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "Kaufbar" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "Artikel sind grundsätzlich kaufbar" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "Verkäuflich" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "Artikel sind grundsätzlich verkaufbar" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "Nachverfolgbar" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "Artikel sind grundsätzlich verfolgbar" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "Virtuell" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "Teile sind grundsätzlich virtuell" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "zeige Bestand in Eingabemasken" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "Zeige den verfügbaren Bestand in einigen Eingabemasken" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 +msgid "Display part price in some forms" +msgstr "" + +#: common/models.py:230 +msgid "Show related parts" +msgstr "" + +#: common/models.py:231 +msgid "Display related parts for a part" +msgstr "" + +#: common/models.py:237 +msgid "Internal Prices" +msgstr "" + +#: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 msgid "Use the internal price (if set) in BOM-price calculations" msgstr "" -#: common/models.py:230 templates/stats.html:25 +#: common/models.py:251 templates/stats.html:25 msgid "Debug Mode" msgstr "Entwickler-Modus" -#: common/models.py:231 +#: common/models.py:252 msgid "Generate reports in debug mode (HTML output)" msgstr "Berichte im Entwickler-Modus generieren (als HTML)" -#: common/models.py:237 +#: common/models.py:258 msgid "Page Size" msgstr "Seitengröße" -#: common/models.py:238 +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "Standardseitenformat für PDF-Bericht" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "Test-Berichte" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "Erstellung von Test-Berichten aktivieren" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "Bestands-Ablauf" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "Ablaufen von Bestand ermöglichen" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "Abgelaufenen Bestand verkaufen" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "Verkauf von abgelaufenem Bestand erlaubt" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "Bestands-Stehzeit" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "Anzahl an Tagen, an denen Bestand als abgestanden markiert wird, bevor sie ablaufen" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "Tage" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "Abgelaufenen Bestand verbauen" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "Verbauen von abgelaufenen Bestand erlaubt" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "Bestands-Eigentümerkontrolle" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "Eigentümerkontrolle für Lagerorte und Teile aktivieren" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "Gruppieren nach Teil" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "Bestand in Tabellen anhand von Teil-Referenz gruppieren" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "aktueller Bestand" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "Anzahl des geänderten Bestands auf der Startseite" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "Bauauftrag-Referenz Präfix" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "Präfix für Bauauftrag-Referenz" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "Bauauftrag-Referenz RegEx" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "RegEx Muster für die Zuordnung von Bauauftrag-Referenzen" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "Auftrags-Referenz Präfix" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "Präfix für Auftrags-Referenz" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "Bestellungs-Referenz Präfix" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "Präfix für Bestellungs-Referenz" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "Einstellungs-Schlüssel (muss einzigartig sein, Groß-/ Kleinschreibung wird nicht beachtet)" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "Einstellungs-Wert" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "Nur Ganzzahl eingeben" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "Wahrheitswert erforderlich" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "Nur Ganzzahl eingeben" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "Schlüsseltext muss eindeutig sein" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "Preisstaffelungs Anzahl" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "Preis" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "Stückpreis für die angegebene Anzahl" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "Standard" @@ -1856,27 +1880,30 @@ msgstr "Standard" msgid "Current value" msgstr "Aktueller Wert" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "Einstellungen ändern" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "Angegebener Wert nicht erlaubt" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "Angegebener Wert muss ein Wahrheitswert sein" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "Datei hochgeladen" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "Übereinstimmende Felder" @@ -1884,44 +1911,57 @@ msgstr "Übereinstimmende Felder" msgid "Match Items" msgstr "Positionen zuordnen" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "Felder zuteilen fehlgeschlagen" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "Vorheriger Schritt" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "Währung" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "Standard-Währung für diese Firma" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "URL" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "Bild-URL" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "Einzelpreis" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "Preis für eine Einheit" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "Hersteller auswählen" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "Hersteller-Teilenummer" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1981,7 +2021,7 @@ msgid "Point of contact" msgstr "Anlaufstelle" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2020,12 +2060,12 @@ msgstr "ist Hersteller" msgid "Does this company manufacture parts?" msgstr "Produziert diese Firma Teile?" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "Basisteil" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "Teil auswählen" @@ -2061,7 +2101,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "Wert" @@ -2082,7 +2122,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2134,7 +2174,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "Mindestpreis" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "Verpackungen" @@ -2153,7 +2193,7 @@ msgstr "Mehrere bestellen" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "Zugeordneter Bestand" @@ -2173,7 +2213,7 @@ msgstr "Neues Bild hochladen" msgid "Download image from URL" msgstr "Bild von URL herunterladen" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "Bestellung anlegen" @@ -2219,9 +2259,9 @@ msgstr "Keine Website angegeben" msgid "Uses default currency" msgstr "verwendet Standard-Währung" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2244,7 +2284,7 @@ msgstr "Neues Herstellerteil" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2252,7 +2292,7 @@ msgstr "Optionen" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "Teile bestellen" @@ -2268,7 +2308,7 @@ msgstr "Teile löschen" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "Neues Teil" @@ -2295,7 +2335,7 @@ msgstr "Zulieferer-Bestand" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "Exportieren" @@ -2373,8 +2413,8 @@ msgstr "Für dieses Herstellerteil sind %(count)s Lieferanten definiert. Wenn Si #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "Zulieferer" @@ -2386,7 +2426,7 @@ msgstr "Herstellerteil-Bestand" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2419,16 +2459,16 @@ msgid "Delete" msgstr "Löschen" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "Parameter" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "Neuer Parameter" @@ -2447,7 +2487,7 @@ msgstr "Hergestellte Teile" msgid "Supplied Parts" msgstr "Zuliefererteile" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2464,7 +2504,7 @@ msgstr "Teilbestand" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2476,7 +2516,7 @@ msgstr "Aufträge" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2509,7 +2549,7 @@ msgid "New Sales Order" msgstr "Neuer Auftrag" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "Zuliefererteil" @@ -2559,7 +2599,7 @@ msgid "Pricing Information" msgstr "Preisinformationen ansehen" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "Preisstaffel hinzufügen" @@ -2578,8 +2618,8 @@ msgstr "Preisstaffel bearbeiten" msgid "Delete price break" msgstr "Preisstaffel löschen" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "Hersteller" @@ -2601,20 +2641,20 @@ msgstr "Firmen" msgid "New Company" msgstr "Neue Firma" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "Bild herunterladen" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "Bildgröße überschreitet maximal-erlaubte Größe für Downloads" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "Ungültige Antwort {code}" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "Angegebene URL ist kein gültiges Bild" @@ -2682,15 +2722,15 @@ msgstr "Neues Zuliefererteil anlegen" msgid "Delete Supplier Part" msgstr "Zuliefererteil entfernen" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "neue Preisstaffel hinzufügt" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "Preisstaffel bearbeiten" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "Preisstaffel löschen" @@ -2755,178 +2795,178 @@ msgstr "Abfragefilter (kommagetrennte Liste mit Schlüssel=Wert-Paaren)" msgid "Filters" msgstr "Filter" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "Bestellung aufgeben" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "Bestellung als vollständig markieren" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "Bestellung stornieren" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "Bestellung versenden" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "Teile in diesen Lagerort empfangen" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "Bestellungs-Referenz" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "Zieldatum für Auftrags-Lieferung." -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "Auftrag-Nummer eingeben" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "Zieldatum für Auftrags-Fertigstellung." -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "Seriennummern für BestandsObjekt eingeben" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "Menge der BestandsObjekt eingeben" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "Bestell-Referenz" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "Bestellungs-Beschreibung" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "Link auf externe Seite" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "Erstellt von" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "Nutzer oder Gruppe der/die für diesen Auftrag zuständig ist/sind" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "Bestell-Notizen" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "Bestellungs-Status" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "Firma bei der die Teile bestellt werden" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "Zulieferer-Referenz" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "Zulieferer Bestellreferenz" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "Empfangen von" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "Aufgabedatum" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "Datum an dem die Bestellung aufgegeben wurde" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "Ziel-Versanddatum" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Geplantes Lieferdatum für Auftrag." -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "Datum an dem der Auftrag fertigstellt wurde" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "Anzahl muss größer Null sein" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "Teile-Zulieferer muss dem Zulieferer der Bestellung entsprechen" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "Nur Teile aufgegebener Bestllungen können empfangen werden" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "Anzahl muss eine Ganzzahl sein" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "Anzahl muss eine positive Zahl sein" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "Firma an die die Teile verkauft werden" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "Kundenreferenz" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "Bestellreferenz" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "Versanddatum" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "Versand von" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "Bestellung kann nicht versendet werden weil er nicht anhängig ist" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "Anzahl" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "Position - Referenz" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "Position - Notizen" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "Bestellung" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2934,77 +2974,77 @@ msgstr "Bestellung" msgid "Purchase Order" msgstr "Bestellung" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "Zuliefererteil" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "Empfangen" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "Empfangene Objekt-Anzahl" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "Preis" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "Preis pro Einheit" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "Wo möchte der Käufer diesen Artikel gelagert haben?" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "Verkaufspreis" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "Stückverkaufspreis" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "BestandsObjekt wurde nicht zugewiesen" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "Kann BestandsObjekt keiner Zeile mit einem anderen Teil hinzufügen" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "Kann BestandsObjekt keiner Zeile ohne Teil hinzufügen" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Die zugeordnete Anzahl darf nicht die verfügbare Anzahl überschreiten" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "Anzahl für BestandsObjekt mit Seriennummer muss 1 sein" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "Position" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "Position" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "BestandsObjekt für Zuordnung auswählen" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "Anzahl für Bestandszuordnung eingeben" @@ -3054,7 +3094,7 @@ msgstr "Aufgegeben" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3092,57 +3132,71 @@ msgstr "Notizen zur Bestellung" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "Es fehlt eine Auswahl für die folgende benötigte Spalte" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "Doppelte Auswahlen gefunden, siehe unten. Reparieren und erneut versuchen." -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "Vorheriger Schritt" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "Auswahl übertragen" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "Datei-Felder" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "Spalte entfernen" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "Auswahl duplizieren" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "Zeile entfernen" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "Fehler in den übermittelten Daten" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "Zeile" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "Zulieferer-Teil auswählen" @@ -3151,6 +3205,8 @@ msgid "Upload File for Purchase Order" msgstr "Datei zur Bestellung hochladen" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "Schritt %(step)s von %(count)s" @@ -3240,8 +3296,8 @@ msgid "Purchase Order Items" msgstr "Bestellungs-Positionen" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "Position hinzufügen" @@ -3289,9 +3345,9 @@ msgstr "Ausstehende Teile für %(order)s - %(desc)s empfangen" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3357,18 +3413,18 @@ msgstr "Abbruch dieser Bestellung bedeutet, dass sie nicht länger bearbeitbar i msgid "Sales Order Items" msgstr "Auftrags-Positionen" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "Aktionen" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "Bestands-Zuordnung bearbeiten" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "Bestands-Zuordnung löschen" @@ -3380,8 +3436,8 @@ msgstr "Keine passenden Positionen gefunden" msgid "ID" msgstr "ID" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "Zugeordnet" @@ -3397,7 +3453,7 @@ msgstr "PO" msgid "Allocate serial numbers" msgstr "Seriennummern zuweisen" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "Lagerbestand zuweisen" @@ -3405,8 +3461,8 @@ msgstr "Lagerbestand zuweisen" msgid "Purchase stock" msgstr "Lagerbestand kaufen" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "Lagerbestand bauen" @@ -3460,195 +3516,195 @@ msgstr "Diese Aktion wird die folgenden BestandsObjekt vom Auftrag entfernen" msgid "Sales Order Attachments" msgstr "Auftrags-Anhänge" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "Bestellungs-Anhang hinzufügen" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "Auftrags-Anhang hinzufügen" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "Auftrag anlegen" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "Bestellung bearbeiten" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "Auftrag bearbeiten" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "Bestellung stornieren" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "Bestellstornierung bestätigen" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "Bestellung kann nicht verworfen werden" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "Auftrag stornieren" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "Bestellung aufgeben" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "Bestellungstätigung bestätigen" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "Bestellung plaziert" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "Auftrag fertigstellen" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "Fertigstellung bestätigen" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "Bestellung als vollständig markieren" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "Versenden" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "Versand bestätigen" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "Versand fehlgeschlagen" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "Zuliefererteile zuordnen" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "Teile empfangen" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "Anzahl empfangener Positionen" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "Kein Ziel gesetzt" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "Fehler beim Konvertieren zu Zahl" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "Anzahl kleiner null empfangen" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "Keine Zeilen angegeben" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "{n} Teile bestellt" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "Zuliefererteil muss ausgewählt werden" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "Zulieferer muss zu Teil und Bestellung passen" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "Position bearbeiten" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "Position löschen" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "Position gelöscht" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "Seriennummern zuweisen" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "{n} Positionen zugeordnet" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "Position auswählen" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "Kein passends Teil für Seriennummer {serial} gefunden" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "{serial} ist nicht auf Lager" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "{serial} bereits einem Auftrag zugeordnet" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "Lagerbestand dem Auftrag zuweisen" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "Zuordnung bearbeiten" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "Zuordnung entfernen" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "Auftrag nicht gefunden" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "Preis nicht gefunden" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "Stückpreis für {part} auf {price} aktualisiert" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "{part} Stückpreis auf {price} und Menge auf {qty} aktualisiert" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "Standard-Lagerort" @@ -3826,8 +3882,8 @@ msgstr "Standard-Stichworte für Teile dieser Kategorie" msgid "Part Category" msgstr "Teil-Kategorie" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "Teil-Kategorien" @@ -3877,7 +3933,7 @@ msgstr "Variante von" msgid "Part description" msgstr "Beschreibung des Teils" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "Schlüsselwörter" @@ -4102,7 +4158,7 @@ msgstr "Teil für die Nutzung in der Stückliste auswählen" msgid "BOM quantity for this BOM item" msgstr "Stücklisten-Anzahl für dieses Stücklisten-Teil" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "Optional" @@ -4134,7 +4190,7 @@ msgstr "Prüfsumme" msgid "BOM line checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "Geerbt" @@ -4143,7 +4199,7 @@ msgstr "Geerbt" 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:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "Varianten zulassen" @@ -4151,8 +4207,8 @@ msgstr "Varianten zulassen" msgid "Stock items for variant parts can be used for this BOM item" msgstr "Lagerbestand von Varianten kann für diese Stücklisten-Position verwendet werden" -#: part/models.py:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "Menge muss eine Ganzzahl sein" @@ -4200,8 +4256,8 @@ msgstr "Sind Sie sicher, dass Sie diese Stücklisten-Position löschen wollen?" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "Die Löschung dieses Eintrags wird das Stücklisten-Position vom folgenden Teil entfernen" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "Stückliste" @@ -4248,7 +4304,7 @@ msgstr "Stückliste bearbeiten" msgid "Validate Bill of Materials" msgstr "Stückliste kontrollieren" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "Stückliste exportieren" @@ -4264,7 +4320,7 @@ msgstr "Ausgewählte Stücklistenpositionen löschen?" msgid "All selected BOM items will be deleted" msgstr "Alle ausgewählte Stücklistenpositionen werden gelöscht" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "Neues Teil anlegen" @@ -4301,7 +4357,7 @@ msgid "Select Part" msgstr "Teil auswählen" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "Neues Teil anlegen" @@ -4342,87 +4398,87 @@ msgstr "Gefertigte Teile" msgid "Start New Build" msgstr "Neuen Bauauftrag beginnen" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "Alle Teile" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "Teil-Kategorie anlegen" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "Teil-Kategorie bearbeiten" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "Teil-Kategorie löschen" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "Kategorie-Details" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "Pfad zur Kategorie" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "Kategorie-Beschreibung" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "Unter-Kategorien" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "Teile (inklusive Unter-Kategorien)" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "Teile-Daten exportieren" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "Teil-Kategorie auswählen" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "Teil-Kategorie auswählen" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "Exportieren" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "Listenansicht anzeigen" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "Rasteransicht anzeigen" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "Neuen Lagerort anlegen" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "Neue Kategorie" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "Teil-Kategorie anlegen" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "Neue Teil-Kategorie anlegen" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "Neuen Lagerort erstellen" @@ -4461,12 +4517,17 @@ msgstr "Wenn diese Kat. gelöscht wird, werden diese Teile in die übergeordnete msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "Wenn diese Kat. gelöscht wird, werden diese Teile in die oberste Kat. verschoben" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "Teilparameter" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "Teil duplizieren" @@ -4490,7 +4551,7 @@ msgstr "Teil evtl. Duplikat dieser Teile" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "%(full_name)s - %(desc)s (%(match_per)s%% übereinstimmend)" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "Teil Details" @@ -4570,12 +4631,21 @@ msgstr "Teil ist aktiv" msgid "Part is not active" msgstr "Teil ist nicht aktiv" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4613,78 +4683,78 @@ msgstr "Herstellerteile löschen" msgid "Create new manufacturer" msgstr "Neuen Hersteller anlegen" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "Teil Varianten" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "Varianten" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "Lagerbestand zuweisen" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "Zuweisungen" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "Benutzt in" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "Bestellpreisinformationen" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "Bestellpreis" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "Interner Preis" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "Preisinformationen ansehen" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "Teil Test-Vorlagen" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "Tests" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "Verknüpfte Teile" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "Teil-Bemerkungen" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "Berechnen" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "Preisspannen" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "Zulieferer-Preise" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4692,10 +4762,10 @@ msgstr "Zulieferer-Preise" msgid "Unit Cost" msgstr "Stückpreis" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4703,51 +4773,51 @@ msgstr "Stückpreis" msgid "Total Cost" msgstr "Gesamtkosten" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "Keine Zulieferer-Preise verfügbar" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "Stücklistenpreise" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "Anmerkung: Stücklistenbepreisung für dieses Teil ist unvollständig" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "Keine Stücklisten-Preise verfügbar" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "Keine Preise für dieses Teil verfügbar" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "Bestandspreise" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "Für dieses Teil sind keine Bestandspreise verfügbar." -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "Einzelpreis - %(currency)s" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "Einzelpreisdifferenz - %(currency)s" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "Einzelpreis für Zuliefererteil- %(currency)s" @@ -4848,7 +4918,7 @@ msgstr "Benötigt für Aufträge" msgid "Allocated to Orders" msgstr "Zu Bauaufträgen zugeordnet" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "Herstellbar" @@ -4966,220 +5036,224 @@ msgstr "neue Variante anlegen" msgid "Unknown database" msgstr "Unbekannte Datenbank" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "verknüpftes Teil hinzufügen" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "verknüpftes Teil entfernen" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "Teilanhang hinzufügen" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "Anhang bearbeiten" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "Teilanhang aktualisiert" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "Teilanhang löschen" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "Teilanhang gelöscht" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "Testvorlage anlegen" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "Testvorlage bearbeiten" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "Testvorlage löschen" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "Teil-Kategorie auswählen" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "Kategorie für {n} Teile setzen" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "Variante anlegen" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "Teil kopiert" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "Übereinstimmung gefunden - Teil trotzdem anlegen" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "Neues Teil angelegt" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "Teil-QR-Code" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "Teilbild hochladen" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "Teilbild aktualisiert" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "Teilbild auswählen" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "Teilbild nicht gefunden" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "Teileigenschaften bearbeiten" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "Stückliste duplizieren" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "bestätige Duplizierung Stückliste von übergeordneter Stückliste" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "Stückliste überprüfen" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "Bestätigen, dass Stückliste korrekt ist" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "überprüfte Stückliste" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "Keine Stückliste angegeben" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "Bitte eine gültige Anzahl eingeben" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "Bitte ein gültiges Teil auswählen" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "Teil doppelt ausgewählt" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "Teil auswählen" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "gewähltes Teil erzeugt rekursive Stückliste" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "Anzahl angeben" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "Löschen des Teils bestätigen" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "Teil wurde gelöscht" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "Teilbepreisung" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "Teilparametervorlage anlegen" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "Teilparametervorlage bearbeiten" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "Teilparametervorlage löschen" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "Teilparameter anlegen" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "Teilparameter bearbeiten" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "Teilparameter löschen" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "Teil-Kategorie bearbeiten" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "Teil-Kategorie löschen" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "Teil-Kategorie wurde gelöscht" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "Kategorieparametervorlage anlegen" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "Kategorieparametervorlage bearbeiten" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "Kategorieparametervorlage löschen" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "Stücklisten-Position anlegen" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "Stücklisten-Position bearbeiten" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "löschen von Stücklisten-Position bestätigen" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5285,12 +5359,12 @@ msgid "Test Results" msgstr "Testergebnisse" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "Test" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "Ergebnis" @@ -5317,7 +5391,7 @@ msgstr "Bestand für {n} Objekte geändert" msgid "Moved {n} parts to {loc}" msgstr "{n} Teile nach {loc} bewegt" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "Ablaufdatum" @@ -5407,187 +5481,187 @@ msgstr "Standard-Lagerort ändern" msgid "Set the destination as the default location for selected parts" msgstr "Setze das Ziel als Standard-Lagerort für ausgewählte Teile" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "Besitzer" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "Besitzer auswählen" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "Ein BestandsObjekt mit dieser Seriennummer existiert bereits" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "Teile-Typ ('{pf}') muss {pe} sein" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "Anzahl muss für Objekte mit Seriennummer 1 sein" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Seriennummer kann nicht gesetzt werden wenn die Anzahl größer als 1 ist" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "Teil kann nicht zu sich selbst gehören" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "Teil muss eine Referenz haben wenn is_building wahr ist" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "Referenz verweist nicht auf das gleiche Teil" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "Eltern-BestandsObjekt" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "Basis-Teil" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "Passendes Zuliefererteil für dieses BestandsObjekt auswählen" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "Bestand-Lagerort" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "Die Verpackung dieses BestandsObjekt ist gelagert in" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "verbaut in" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "Ist dieses Teil in einem anderen verbaut?" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "Seriennummer für dieses Teil" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "Losnummer für dieses BestandsObjekt" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "Bestand" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "Quellbau" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "Bauauftrag für dieses BestandsObjekt" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "Quelle Bestellung" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "Bestellung für dieses BestandsObjekt" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "Ziel-Auftrag" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Ablaufdatum für BestandsObjekt. Bestand wird danach als abgelaufen gekennzeichnet" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "Löschen wenn leer" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "Dieses BestandsObjekt löschen wenn Bestand aufgebraucht" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "BestandsObjekt-Notizen" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "Preis für eine Einheit bei Einkauf" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "Teil ist nicht verfolgbar" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "Anzahl muss eine Ganzzahl sein" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "Anzahl darf nicht die verfügbare Anzahl überschreiten ({n})" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "Seriennummern muss eine Liste von Ganzzahlen sein" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "Anzahl stimmt nicht mit den Seriennummern überein" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "Seriennummern {exists} existieren bereits" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "BestandsObjekt kann nicht bewegt werden, da kein Bestand vorhanden ist" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "Eintrags-Notizen" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "Wert muss für diesen Test angegeben werden" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "Anhang muss für diesen Test hochgeladen werden" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "Name des Tests" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "Testergebnis" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "Test Ausgabe Wert" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "Test Ergebnis Anhang" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "Test Notizen" @@ -5739,7 +5813,7 @@ msgstr "Dieses BestandsObjekt wird automatisch gelöscht wenn der Lagerbestand a msgid "Stock Item Details" msgstr "BestandsObjekt-Details" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "Kein Lagerort gesetzt" @@ -6136,7 +6210,7 @@ msgstr "BestandsObjekt bearbeiten" msgid "Serialize Stock" msgstr "Lagerbestand erfassen" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "Neues BestandsObjekt hinzufügen" @@ -6288,12 +6362,12 @@ msgid "No category parameter templates found" msgstr "Keine Kategorie-Parametervorlagen gefunden" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "Vorlage bearbeiten" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "Vorlage löschen" @@ -6301,23 +6375,23 @@ msgstr "Vorlage löschen" msgid "Currency Settings" msgstr "Währungseinstellungen" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "Basiswährung" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "Wechselkurse" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "Letzte Aktualisierung" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "Nie" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "Jetzt aktualisieren" @@ -6341,11 +6415,19 @@ msgstr "Teil-Einstellungen" msgid "Part Options" msgstr "Teil-Optionen" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "Teil-Parametervorlage" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "Keine Teilparametervorlagen gefunden" @@ -6630,7 +6712,7 @@ msgstr "In Lagerorten buchen" msgid "Barcode does not match a valid location" msgstr "Barcode entspricht keinem Lagerort" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "Unterbaugruppe öffnen" @@ -6642,31 +6724,35 @@ msgstr "Kaufpreisspanne" msgid "Purchase Price Average" msgstr "Durchschnittlicher Kaufpreis" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "Keine Preisinformation verfügbar" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "Stückliste anzeigen" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "Stücklisten-Position kontrollieren" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "Diese Position wurde kontrolliert" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "Stücklisten-Position bearbeiten" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "Stücklisten-Position löschen" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "Keine Stücklisten-Position(en) gefunden" @@ -6694,37 +6780,37 @@ msgstr "" msgid "Location not specified" msgstr "Standort nicht angegeben" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "Neues BestandsObjekt" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "benötigtes Teil" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "Anzahl pro" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "Bestand bestellen" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "Keine Bauaufträge passen zur Anfrage" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "Auswählen" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "Bauauftrag ist überfällig" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "Keine Teile zugeordnet zu" diff --git a/InvenTree/locale/en/LC_MESSAGES/django.po b/InvenTree/locale/en/LC_MESSAGES/django.po index 792cf22fc2..b7f022a199 100644 --- a/InvenTree/locale/en/LC_MESSAGES/django.po +++ b/InvenTree/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" +"POT-Creation-Date: 2021-07-02 04:52+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -30,14 +30,14 @@ msgstr "" msgid "No matching action found" msgstr "" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "" @@ -73,41 +73,41 @@ msgstr "" msgid "Select Category" msgstr "" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" -#: InvenTree/models.py:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "" @@ -148,7 +148,7 @@ msgstr "" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -156,7 +156,7 @@ msgstr "" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -173,23 +173,23 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "" @@ -447,11 +447,11 @@ msgid "Order target date" msgstr "" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "" @@ -464,11 +464,11 @@ msgstr "" #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -477,7 +477,7 @@ msgstr "" #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -487,8 +487,8 @@ msgstr "" #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -502,7 +502,7 @@ msgstr "" msgid "Enter quantity for build output" msgstr "" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "" @@ -535,7 +535,7 @@ msgstr "" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "" @@ -545,10 +545,10 @@ msgid "Location of completed parts" msgstr "" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -593,8 +593,8 @@ msgstr "" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -604,12 +604,12 @@ msgstr "" msgid "Build Order Reference" msgstr "" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "" @@ -629,7 +629,7 @@ msgstr "" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -644,8 +644,8 @@ msgstr "" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -704,7 +704,7 @@ msgstr "" msgid "Build status code" msgstr "" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "" @@ -712,16 +712,16 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "" @@ -738,7 +738,7 @@ msgid "User who issued this build order" msgstr "" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -755,30 +755,30 @@ msgstr "" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "" @@ -811,11 +811,11 @@ msgstr "" msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -829,7 +829,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "" @@ -842,7 +842,7 @@ msgstr "" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -880,7 +880,7 @@ msgstr "" msgid "Auto Allocate" msgstr "" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "" @@ -894,8 +894,8 @@ msgstr "" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "" @@ -916,16 +916,16 @@ msgstr "" #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "" @@ -978,7 +978,7 @@ msgstr "" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1037,7 +1037,7 @@ msgid "Progress" msgstr "" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1184,7 +1184,7 @@ msgstr "" msgid "Stock can be taken from any available location." msgstr "" -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1204,7 +1204,7 @@ msgstr "" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "" @@ -1212,7 +1212,7 @@ msgstr "" msgid "No target date set" msgstr "" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "" @@ -1251,7 +1251,7 @@ msgstr "" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "" @@ -1413,8 +1413,8 @@ msgstr "" msgid "Stock item is over-allocated" msgstr "" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "" @@ -1434,56 +1434,56 @@ msgstr "" msgid "Add Build Order Attachment" msgstr "" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "" @@ -1521,335 +1521,359 @@ msgid "Base URL for server instance" msgstr "" #: common/models.py:85 -msgid "Download from URL" +msgid "Default Currency" msgstr "" #: common/models.py:86 -msgid "Allow download of remote images and files from external URL" +msgid "Default currency" msgstr "" #: common/models.py:92 -msgid "Barcode Support" +msgid "Download from URL" msgstr "" #: common/models.py:93 -msgid "Enable barcode scanner support" +msgid "Allow download of remote images and files from external URL" msgstr "" #: common/models.py:99 -msgid "IPN Regex" +msgid "Barcode Support" msgstr "" #: common/models.py:100 +msgid "Enable barcode scanner support" +msgstr "" + +#: common/models.py:106 +msgid "IPN Regex" +msgstr "" + +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "" -#: common/models.py:161 +#: common/models.py:168 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "" -#: common/models.py:168 +#: common/models.py:175 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 -msgid "Use the internal price (if set) in BOM-price calculations" +msgid "Display part price in some forms" msgstr "" -#: common/models.py:230 templates/stats.html:25 -msgid "Debug Mode" +#: common/models.py:230 +msgid "Show related parts" msgstr "" #: common/models.py:231 -msgid "Generate reports in debug mode (HTML output)" +msgid "Display related parts for a part" msgstr "" #: common/models.py:237 -msgid "Page Size" +msgid "Internal Prices" msgstr "" #: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 +msgid "Use the internal price (if set) in BOM-price calculations" +msgstr "" + +#: common/models.py:251 templates/stats.html:25 +msgid "Debug Mode" +msgstr "" + +#: common/models.py:252 +msgid "Generate reports in debug mode (HTML output)" +msgstr "" + +#: common/models.py:258 +msgid "Page Size" +msgstr "" + +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "" @@ -1857,27 +1881,30 @@ msgstr "" msgid "Current value" msgstr "" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "" @@ -1885,44 +1912,57 @@ msgstr "" msgid "Match Items" msgstr "" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1982,7 +2022,7 @@ msgid "Point of contact" msgstr "" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2021,12 +2061,12 @@ msgstr "" msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "" @@ -2062,7 +2102,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "" @@ -2083,7 +2123,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2135,7 +2175,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "" @@ -2154,7 +2194,7 @@ msgstr "" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "" @@ -2174,7 +2214,7 @@ msgstr "" msgid "Download image from URL" msgstr "" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "" @@ -2220,9 +2260,9 @@ msgstr "" msgid "Uses default currency" msgstr "" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2245,7 +2285,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2253,7 +2293,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "" @@ -2269,7 +2309,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "" @@ -2296,7 +2336,7 @@ msgstr "" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "" @@ -2374,8 +2414,8 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "" @@ -2387,7 +2427,7 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2420,16 +2460,16 @@ msgid "Delete" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "" @@ -2448,7 +2488,7 @@ msgstr "" msgid "Supplied Parts" msgstr "" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2465,7 +2505,7 @@ msgstr "" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2477,7 +2517,7 @@ msgstr "" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2510,7 +2550,7 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "" @@ -2560,7 +2600,7 @@ msgid "Pricing Information" msgstr "" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "" @@ -2579,8 +2619,8 @@ msgstr "" msgid "Delete price break" msgstr "" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "" @@ -2602,20 +2642,20 @@ msgstr "" msgid "New Company" msgstr "" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "" @@ -2683,15 +2723,15 @@ msgstr "" msgid "Delete Supplier Part" msgstr "" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "" @@ -2756,178 +2796,178 @@ msgstr "" msgid "Filters" msgstr "" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "" -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "" -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2935,77 +2975,77 @@ msgstr "" msgid "Purchase Order" msgstr "" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "" @@ -3055,7 +3095,7 @@ msgstr "" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3093,57 +3133,71 @@ msgstr "" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "" -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "" @@ -3152,6 +3206,8 @@ msgid "Upload File for Purchase Order" msgstr "" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "" @@ -3241,8 +3297,8 @@ msgid "Purchase Order Items" msgstr "" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "" @@ -3290,9 +3346,9 @@ msgstr "" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3358,18 +3414,18 @@ msgstr "" msgid "Sales Order Items" msgstr "" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "" @@ -3381,8 +3437,8 @@ msgstr "" msgid "ID" msgstr "" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "" @@ -3398,7 +3454,7 @@ msgstr "" msgid "Allocate serial numbers" msgstr "" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "" @@ -3406,8 +3462,8 @@ msgstr "" msgid "Purchase stock" msgstr "" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "" @@ -3461,195 +3517,195 @@ msgstr "" msgid "Sales Order Attachments" msgstr "" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "" @@ -3827,8 +3883,8 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "" @@ -3878,7 +3934,7 @@ msgstr "" msgid "Part description" msgstr "" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "" @@ -4103,7 +4159,7 @@ msgstr "" msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "" @@ -4135,7 +4191,7 @@ msgstr "" msgid "BOM line checksum" msgstr "" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "" @@ -4144,7 +4200,7 @@ msgstr "" msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "" @@ -4152,8 +4208,8 @@ msgstr "" msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "" @@ -4201,8 +4257,8 @@ msgstr "" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "" @@ -4249,7 +4305,7 @@ msgstr "" msgid "Validate Bill of Materials" msgstr "" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "" @@ -4265,7 +4321,7 @@ msgstr "" msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "" @@ -4302,7 +4358,7 @@ msgid "Select Part" msgstr "" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "" @@ -4343,87 +4399,87 @@ msgstr "" msgid "Start New Build" msgstr "" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "" @@ -4462,12 +4518,17 @@ msgstr "" msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "" @@ -4491,7 +4552,7 @@ msgstr "" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "" @@ -4571,12 +4632,21 @@ msgstr "" msgid "Part is not active" msgstr "" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4614,78 +4684,78 @@ msgstr "" msgid "Create new manufacturer" msgstr "" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4693,10 +4763,10 @@ msgstr "" msgid "Unit Cost" msgstr "" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4704,51 +4774,51 @@ msgstr "" msgid "Total Cost" msgstr "" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "" -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "" @@ -4849,7 +4919,7 @@ msgstr "" msgid "Allocated to Orders" msgstr "" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "" @@ -4967,220 +5037,224 @@ msgstr "" msgid "Unknown database" msgstr "" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5286,12 +5360,12 @@ msgid "Test Results" msgstr "" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "" @@ -5318,7 +5392,7 @@ msgstr "" msgid "Moved {n} parts to {loc}" msgstr "" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "" @@ -5408,187 +5482,187 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "" @@ -5740,7 +5814,7 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "" @@ -6137,7 +6211,7 @@ msgstr "" msgid "Serialize Stock" msgstr "" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "" @@ -6287,12 +6361,12 @@ msgid "No category parameter templates found" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "" @@ -6300,23 +6374,23 @@ msgstr "" msgid "Currency Settings" msgstr "" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "" @@ -6340,11 +6414,19 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "" @@ -6629,7 +6711,7 @@ msgstr "" msgid "Barcode does not match a valid location" msgstr "" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "" @@ -6641,31 +6723,35 @@ msgstr "" msgid "Purchase Price Average" msgstr "" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "" @@ -6693,37 +6779,37 @@ msgstr "" msgid "Location not specified" msgstr "" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "" diff --git a/InvenTree/locale/es/LC_MESSAGES/django.po b/InvenTree/locale/es/LC_MESSAGES/django.po index 1bbb282835..7c9ad06f92 100644 --- a/InvenTree/locale/es/LC_MESSAGES/django.po +++ b/InvenTree/locale/es/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" -"PO-Revision-Date: 2021-06-25 14:06\n" +"POT-Creation-Date: 2021-07-01 22:35+0000\n" +"PO-Revision-Date: 2021-07-01 22:38\n" "Last-Translator: \n" "Language-Team: Spanish\n" "Language: es_ES\n" @@ -29,14 +29,14 @@ msgstr "No se especificó ninguna acción" msgid "No matching action found" msgstr "No se encontró ninguna acción coincidente" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "Ingrese la fecha" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "Confirmar" @@ -72,41 +72,41 @@ msgstr "Aplicar tema" msgid "Select Category" msgstr "Seleccionar Categoría" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "Cantidad proporcionada no válida" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "Grupo no válido: un {g}" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "Numeros de serie no encontrados" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" -#: InvenTree/models.py:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "" @@ -147,7 +147,7 @@ msgstr "Nombre" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -155,7 +155,7 @@ msgstr "Nombre" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -172,23 +172,23 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "Inglés" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "Francés" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "Alemán" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "Polaco" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "Turco" @@ -446,11 +446,11 @@ msgid "Order target date" msgstr "" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "" @@ -463,11 +463,11 @@ msgstr "" #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -476,7 +476,7 @@ msgstr "" #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -486,8 +486,8 @@ msgstr "" #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -501,7 +501,7 @@ msgstr "" msgid "Enter quantity for build output" msgstr "" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "Números de serie" @@ -534,7 +534,7 @@ msgstr "" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "Unicación" @@ -544,10 +544,10 @@ msgid "Location of completed parts" msgstr "" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -592,8 +592,8 @@ msgstr "" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -603,12 +603,12 @@ msgstr "" msgid "Build Order Reference" msgstr "" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "Referencia" @@ -628,7 +628,7 @@ msgstr "" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -643,8 +643,8 @@ msgstr "" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -703,7 +703,7 @@ msgstr "" msgid "Build status code" msgstr "" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "" @@ -711,16 +711,16 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "" @@ -737,7 +737,7 @@ msgid "User who issued this build order" msgstr "" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -754,30 +754,30 @@ msgstr "" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "Notas" @@ -810,11 +810,11 @@ msgstr "" msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -828,7 +828,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "" @@ -841,7 +841,7 @@ msgstr "" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -879,7 +879,7 @@ msgstr "" msgid "Auto Allocate" msgstr "" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "" @@ -893,8 +893,8 @@ msgstr "" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "" @@ -915,16 +915,16 @@ msgstr "" #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "Número de serie" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "" @@ -977,7 +977,7 @@ msgstr "" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1036,7 +1036,7 @@ msgid "Progress" msgstr "Progreso" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1183,7 +1183,7 @@ msgstr "" msgid "Stock can be taken from any available location." msgstr "" -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1203,7 +1203,7 @@ msgstr "Lote" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "" @@ -1211,7 +1211,7 @@ msgstr "" msgid "No target date set" msgstr "" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "Completados" @@ -1250,7 +1250,7 @@ msgstr "" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "Detalles" @@ -1412,8 +1412,8 @@ msgstr "" msgid "Stock item is over-allocated" msgstr "" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "" @@ -1433,56 +1433,56 @@ msgstr "" msgid "Add Build Order Attachment" msgstr "" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "" @@ -1520,335 +1520,359 @@ msgid "Base URL for server instance" msgstr "" #: common/models.py:85 -msgid "Download from URL" +msgid "Default Currency" msgstr "" #: common/models.py:86 -msgid "Allow download of remote images and files from external URL" +msgid "Default currency" msgstr "" #: common/models.py:92 -msgid "Barcode Support" +msgid "Download from URL" msgstr "" #: common/models.py:93 -msgid "Enable barcode scanner support" +msgid "Allow download of remote images and files from external URL" msgstr "" #: common/models.py:99 -msgid "IPN Regex" +msgid "Barcode Support" msgstr "" #: common/models.py:100 +msgid "Enable barcode scanner support" +msgstr "" + +#: common/models.py:106 +msgid "IPN Regex" +msgstr "" + +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "" -#: common/models.py:161 +#: common/models.py:168 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "" -#: common/models.py:168 +#: common/models.py:175 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 -msgid "Use the internal price (if set) in BOM-price calculations" +msgid "Display part price in some forms" msgstr "" -#: common/models.py:230 templates/stats.html:25 -msgid "Debug Mode" +#: common/models.py:230 +msgid "Show related parts" msgstr "" #: common/models.py:231 -msgid "Generate reports in debug mode (HTML output)" +msgid "Display related parts for a part" msgstr "" #: common/models.py:237 -msgid "Page Size" +msgid "Internal Prices" msgstr "" #: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 +msgid "Use the internal price (if set) in BOM-price calculations" +msgstr "" + +#: common/models.py:251 templates/stats.html:25 +msgid "Debug Mode" +msgstr "" + +#: common/models.py:252 +msgid "Generate reports in debug mode (HTML output)" +msgstr "" + +#: common/models.py:258 +msgid "Page Size" +msgstr "" + +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "días" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "" @@ -1856,27 +1880,30 @@ msgstr "" msgid "Current value" msgstr "" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "" @@ -1884,44 +1911,57 @@ msgstr "" msgid "Match Items" msgstr "" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1981,7 +2021,7 @@ msgid "Point of contact" msgstr "" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2020,12 +2060,12 @@ msgstr "" msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "" @@ -2061,7 +2101,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "" @@ -2082,7 +2122,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2134,7 +2174,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "" @@ -2153,7 +2193,7 @@ msgstr "" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "" @@ -2173,7 +2213,7 @@ msgstr "" msgid "Download image from URL" msgstr "" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "" @@ -2218,9 +2258,9 @@ msgstr "" msgid "Uses default currency" msgstr "" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2243,7 +2283,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2251,7 +2291,7 @@ msgstr "Opciones" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "" @@ -2267,7 +2307,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "" @@ -2294,7 +2334,7 @@ msgstr "" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "Exportar" @@ -2372,8 +2412,8 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "" @@ -2385,7 +2425,7 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2418,16 +2458,16 @@ msgid "Delete" msgstr "Eliminar" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "" @@ -2446,7 +2486,7 @@ msgstr "" msgid "Supplied Parts" msgstr "" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2463,7 +2503,7 @@ msgstr "" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2475,7 +2515,7 @@ msgstr "" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2508,7 +2548,7 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "" @@ -2558,7 +2598,7 @@ msgid "Pricing Information" msgstr "" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "" @@ -2577,8 +2617,8 @@ msgstr "" msgid "Delete price break" msgstr "" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "Fabricantes" @@ -2600,20 +2640,20 @@ msgstr "" msgid "New Company" msgstr "" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "" @@ -2681,15 +2721,15 @@ msgstr "" msgid "Delete Supplier Part" msgstr "" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "" @@ -2754,178 +2794,178 @@ msgstr "" msgid "Filters" msgstr "" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "" -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "" -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2933,77 +2973,77 @@ msgstr "" msgid "Purchase Order" msgstr "" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "" @@ -3053,7 +3093,7 @@ msgstr "" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3091,57 +3131,71 @@ msgstr "" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "" -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "" @@ -3150,6 +3204,8 @@ msgid "Upload File for Purchase Order" msgstr "" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "" @@ -3239,8 +3295,8 @@ msgid "Purchase Order Items" msgstr "" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "" @@ -3288,9 +3344,9 @@ msgstr "" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3356,18 +3412,18 @@ msgstr "" msgid "Sales Order Items" msgstr "" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "" @@ -3379,8 +3435,8 @@ msgstr "" msgid "ID" msgstr "" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "" @@ -3396,7 +3452,7 @@ msgstr "" msgid "Allocate serial numbers" msgstr "" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "" @@ -3404,8 +3460,8 @@ msgstr "" msgid "Purchase stock" msgstr "" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "" @@ -3459,195 +3515,195 @@ msgstr "" msgid "Sales Order Attachments" msgstr "" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "" @@ -3825,8 +3881,8 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "" @@ -3876,7 +3932,7 @@ msgstr "" msgid "Part description" msgstr "" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "" @@ -4101,7 +4157,7 @@ msgstr "" msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "" @@ -4133,7 +4189,7 @@ msgstr "" msgid "BOM line checksum" msgstr "" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "" @@ -4142,7 +4198,7 @@ msgstr "" msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "" @@ -4150,8 +4206,8 @@ msgstr "" msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "" @@ -4199,8 +4255,8 @@ msgstr "" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "" @@ -4247,7 +4303,7 @@ msgstr "" msgid "Validate Bill of Materials" msgstr "" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "" @@ -4263,7 +4319,7 @@ msgstr "" msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "" @@ -4300,7 +4356,7 @@ msgid "Select Part" msgstr "" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "" @@ -4341,87 +4397,87 @@ msgstr "" msgid "Start New Build" msgstr "" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "" @@ -4460,12 +4516,17 @@ msgstr "" msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "" @@ -4489,7 +4550,7 @@ msgstr "" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "" @@ -4569,12 +4630,21 @@ msgstr "" msgid "Part is not active" msgstr "" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4612,78 +4682,78 @@ msgstr "" msgid "Create new manufacturer" msgstr "" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4691,10 +4761,10 @@ msgstr "" msgid "Unit Cost" msgstr "" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4702,51 +4772,51 @@ msgstr "" msgid "Total Cost" msgstr "" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "" -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "" @@ -4847,7 +4917,7 @@ msgstr "" msgid "Allocated to Orders" msgstr "" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "" @@ -4965,220 +5035,224 @@ msgstr "" msgid "Unknown database" msgstr "" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5284,12 +5358,12 @@ msgid "Test Results" msgstr "" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "" @@ -5316,7 +5390,7 @@ msgstr "" msgid "Moved {n} parts to {loc}" msgstr "" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "" @@ -5406,187 +5480,187 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "" @@ -5738,7 +5812,7 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "" @@ -6135,7 +6209,7 @@ msgstr "" msgid "Serialize Stock" msgstr "" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "" @@ -6284,12 +6358,12 @@ msgid "No category parameter templates found" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "" @@ -6297,23 +6371,23 @@ msgstr "" msgid "Currency Settings" msgstr "" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "" @@ -6337,11 +6411,19 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "" @@ -6626,7 +6708,7 @@ msgstr "" msgid "Barcode does not match a valid location" msgstr "" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "" @@ -6638,31 +6720,35 @@ msgstr "" msgid "Purchase Price Average" msgstr "" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "" @@ -6690,37 +6776,37 @@ msgstr "" msgid "Location not specified" msgstr "" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "" diff --git a/InvenTree/locale/fr/LC_MESSAGES/django.po b/InvenTree/locale/fr/LC_MESSAGES/django.po index 61f43d466b..44f96424bc 100644 --- a/InvenTree/locale/fr/LC_MESSAGES/django.po +++ b/InvenTree/locale/fr/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" -"PO-Revision-Date: 2021-06-24 21:40\n" +"POT-Creation-Date: 2021-07-01 22:35+0000\n" +"PO-Revision-Date: 2021-07-01 22:38\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -29,14 +29,14 @@ msgstr "Aucune action spécifiée" msgid "No matching action found" msgstr "Aucune action correspondante trouvée" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "Entrer la date" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "Confirmer" @@ -72,41 +72,41 @@ msgstr "Appliquer le thème" msgid "Select Category" msgstr "Sélectionnez une catégorie" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Dupliquer le numéro de série: {n}" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "Quantité fournie invalide" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "Chaîne de numéro de série vide" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "Groupe invalide : {g}" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "Numéro de série dupliqué: {g}" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "Aucun numéro de série trouvé" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, 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})" -#: InvenTree/models.py:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "Pièce jointe" @@ -147,7 +147,7 @@ msgstr "Nom" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -155,7 +155,7 @@ msgstr "Nom" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -172,23 +172,23 @@ msgstr "Description (facultative)" msgid "parent" msgstr "parent" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "Anglais" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "Français" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "Allemand" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "Polonais" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "Turc" @@ -446,11 +446,11 @@ msgid "Order target date" msgstr "" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "" @@ -463,11 +463,11 @@ msgstr "" #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -476,7 +476,7 @@ msgstr "" #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -486,8 +486,8 @@ msgstr "" #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -501,7 +501,7 @@ msgstr "" msgid "Enter quantity for build output" msgstr "" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "Numéros de série" @@ -534,7 +534,7 @@ msgstr "" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "" @@ -544,10 +544,10 @@ msgid "Location of completed parts" msgstr "Emplacement des pièces terminées" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -592,8 +592,8 @@ msgstr "" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -603,12 +603,12 @@ msgstr "" msgid "Build Order Reference" msgstr "" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "Référence" @@ -628,7 +628,7 @@ msgstr "" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -643,8 +643,8 @@ msgstr "" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -703,7 +703,7 @@ msgstr "" msgid "Build status code" msgstr "" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "" @@ -711,16 +711,16 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "Date de création" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "" @@ -737,7 +737,7 @@ msgid "User who issued this build order" msgstr "" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -754,30 +754,30 @@ msgstr "" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "Lien Externe" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "Notes" @@ -810,11 +810,11 @@ msgstr "L'élément de construction doit spécifier une sortie de construction, msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -828,7 +828,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "L'article en stock sélectionné n'a pas été trouvé dans la BOM pour la pièce '{p}'" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "" @@ -841,7 +841,7 @@ msgstr "" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -879,7 +879,7 @@ msgstr "" msgid "Auto Allocate" msgstr "" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "" @@ -893,8 +893,8 @@ msgstr "Commander les pièces requises" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "Commander des pièces" @@ -915,16 +915,16 @@ msgstr "" #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "Pieces jointes" @@ -977,7 +977,7 @@ msgstr "" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1036,7 +1036,7 @@ msgid "Progress" msgstr "" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1183,7 +1183,7 @@ msgstr "" msgid "Stock can be taken from any available location." msgstr "" -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1203,7 +1203,7 @@ msgstr "" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "" @@ -1211,7 +1211,7 @@ msgstr "" msgid "No target date set" msgstr "" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "" @@ -1250,7 +1250,7 @@ msgstr "" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "Détails" @@ -1412,8 +1412,8 @@ msgstr "" msgid "Stock item is over-allocated" msgstr "" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "Disponible" @@ -1433,56 +1433,56 @@ msgstr "" msgid "Add Build Order Attachment" msgstr "" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "Pièce jointe ajoutée" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "Sélectionner un fichier à téléverser" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "{name.title()} Fichier" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "" @@ -1520,335 +1520,359 @@ msgid "Base URL for server instance" msgstr "" #: common/models.py:85 -msgid "Download from URL" -msgstr "Télécharger depuis l'URL" +msgid "Default Currency" +msgstr "" #: common/models.py:86 -msgid "Allow download of remote images and files from external URL" +msgid "Default currency" msgstr "" #: common/models.py:92 -msgid "Barcode Support" -msgstr "" +msgid "Download from URL" +msgstr "Télécharger depuis l'URL" #: common/models.py:93 -msgid "Enable barcode scanner support" +msgid "Allow download of remote images and files from external URL" msgstr "" #: common/models.py:99 +msgid "Barcode Support" +msgstr "" + +#: common/models.py:100 +msgid "Enable barcode scanner support" +msgstr "" + +#: common/models.py:106 msgid "IPN Regex" msgstr "Regex IPN" -#: common/models.py:100 +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "Expression régulière pour la correspondance avec l'IPN de la Pièce" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "Autoriser les IPN dupliqués" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "Permettre à plusieurs pièces de partager le même IPN" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "Autoriser l'édition de l'IPN" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "Permettre de modifier la valeur de l'IPN lors de l'édition d'une pièce" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "" -#: common/models.py:161 +#: common/models.py:168 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "" -#: common/models.py:168 +#: common/models.py:175 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 -msgid "Use the internal price (if set) in BOM-price calculations" +msgid "Display part price in some forms" msgstr "" -#: common/models.py:230 templates/stats.html:25 -msgid "Debug Mode" +#: common/models.py:230 +msgid "Show related parts" msgstr "" #: common/models.py:231 -msgid "Generate reports in debug mode (HTML output)" +msgid "Display related parts for a part" msgstr "" #: common/models.py:237 -msgid "Page Size" +msgid "Internal Prices" msgstr "" #: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 +msgid "Use the internal price (if set) in BOM-price calculations" +msgstr "" + +#: common/models.py:251 templates/stats.html:25 +msgid "Debug Mode" +msgstr "" + +#: common/models.py:252 +msgid "Generate reports in debug mode (HTML output)" +msgstr "" + +#: common/models.py:258 +msgid "Page Size" +msgstr "" + +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "jours" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "" @@ -1856,27 +1880,30 @@ msgstr "" msgid "Current value" msgstr "" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "" @@ -1884,44 +1911,57 @@ msgstr "" msgid "Match Items" msgstr "" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1981,7 +2021,7 @@ msgid "Point of contact" msgstr "" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2020,12 +2060,12 @@ msgstr "" msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "" @@ -2061,7 +2101,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "" @@ -2082,7 +2122,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2134,7 +2174,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "" @@ -2153,7 +2193,7 @@ msgstr "" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "" @@ -2173,7 +2213,7 @@ msgstr "" msgid "Download image from URL" msgstr "" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "" @@ -2218,9 +2258,9 @@ msgstr "" msgid "Uses default currency" msgstr "" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2243,7 +2283,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2251,7 +2291,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "" @@ -2267,7 +2307,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "" @@ -2294,7 +2334,7 @@ msgstr "" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "" @@ -2372,8 +2412,8 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "" @@ -2385,7 +2425,7 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2418,16 +2458,16 @@ msgid "Delete" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "" @@ -2446,7 +2486,7 @@ msgstr "" msgid "Supplied Parts" msgstr "" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2463,7 +2503,7 @@ msgstr "" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2475,7 +2515,7 @@ msgstr "" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2508,7 +2548,7 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "" @@ -2558,7 +2598,7 @@ msgid "Pricing Information" msgstr "" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "" @@ -2577,8 +2617,8 @@ msgstr "" msgid "Delete price break" msgstr "" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "" @@ -2600,20 +2640,20 @@ msgstr "" msgid "New Company" msgstr "" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "" @@ -2681,15 +2721,15 @@ msgstr "" msgid "Delete Supplier Part" msgstr "" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "" @@ -2754,178 +2794,178 @@ msgstr "" msgid "Filters" msgstr "" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "" -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "" -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2933,77 +2973,77 @@ msgstr "" msgid "Purchase Order" msgstr "" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "" @@ -3053,7 +3093,7 @@ msgstr "" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3091,57 +3131,71 @@ msgstr "" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "" -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "" @@ -3150,6 +3204,8 @@ msgid "Upload File for Purchase Order" msgstr "" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "" @@ -3239,8 +3295,8 @@ msgid "Purchase Order Items" msgstr "" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "" @@ -3288,9 +3344,9 @@ msgstr "" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3356,18 +3412,18 @@ msgstr "" msgid "Sales Order Items" msgstr "" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "" @@ -3379,8 +3435,8 @@ msgstr "" msgid "ID" msgstr "" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "" @@ -3396,7 +3452,7 @@ msgstr "" msgid "Allocate serial numbers" msgstr "" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "" @@ -3404,8 +3460,8 @@ msgstr "" msgid "Purchase stock" msgstr "" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "" @@ -3459,195 +3515,195 @@ msgstr "" msgid "Sales Order Attachments" msgstr "" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "" @@ -3825,8 +3881,8 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "" @@ -3876,7 +3932,7 @@ msgstr "" msgid "Part description" msgstr "" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "" @@ -4101,7 +4157,7 @@ msgstr "" msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "" @@ -4133,7 +4189,7 @@ msgstr "" msgid "BOM line checksum" msgstr "" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "" @@ -4142,7 +4198,7 @@ msgstr "" msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "" @@ -4150,8 +4206,8 @@ msgstr "" msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "" @@ -4199,8 +4255,8 @@ msgstr "" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "" @@ -4247,7 +4303,7 @@ msgstr "" msgid "Validate Bill of Materials" msgstr "" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "" @@ -4263,7 +4319,7 @@ msgstr "" msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "" @@ -4300,7 +4356,7 @@ msgid "Select Part" msgstr "" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "" @@ -4341,87 +4397,87 @@ msgstr "" msgid "Start New Build" msgstr "" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "" @@ -4460,12 +4516,17 @@ msgstr "" msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "" @@ -4489,7 +4550,7 @@ msgstr "" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "" @@ -4569,12 +4630,21 @@ msgstr "" msgid "Part is not active" msgstr "" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4612,78 +4682,78 @@ msgstr "" msgid "Create new manufacturer" msgstr "" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4691,10 +4761,10 @@ msgstr "" msgid "Unit Cost" msgstr "" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4702,51 +4772,51 @@ msgstr "" msgid "Total Cost" msgstr "" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "" -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "" @@ -4847,7 +4917,7 @@ msgstr "" msgid "Allocated to Orders" msgstr "" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "" @@ -4965,220 +5035,224 @@ msgstr "" msgid "Unknown database" msgstr "" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5284,12 +5358,12 @@ msgid "Test Results" msgstr "" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "" @@ -5316,7 +5390,7 @@ msgstr "" msgid "Moved {n} parts to {loc}" msgstr "" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "" @@ -5406,187 +5480,187 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "" @@ -5738,7 +5812,7 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "" @@ -6135,7 +6209,7 @@ msgstr "" msgid "Serialize Stock" msgstr "" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "" @@ -6284,12 +6358,12 @@ msgid "No category parameter templates found" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "" @@ -6297,23 +6371,23 @@ msgstr "" msgid "Currency Settings" msgstr "" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "" @@ -6337,11 +6411,19 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "" @@ -6626,7 +6708,7 @@ msgstr "" msgid "Barcode does not match a valid location" msgstr "" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "" @@ -6638,31 +6720,35 @@ msgstr "" msgid "Purchase Price Average" msgstr "" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "" @@ -6690,37 +6776,37 @@ msgstr "" msgid "Location not specified" msgstr "" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "" diff --git a/InvenTree/locale/it/LC_MESSAGES/django.po b/InvenTree/locale/it/LC_MESSAGES/django.po index 87d69fb09a..fdb3b7ca79 100644 --- a/InvenTree/locale/it/LC_MESSAGES/django.po +++ b/InvenTree/locale/it/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" -"PO-Revision-Date: 2021-06-24 21:40\n" +"POT-Creation-Date: 2021-07-01 22:35+0000\n" +"PO-Revision-Date: 2021-07-01 22:38\n" "Last-Translator: \n" "Language-Team: Italian\n" "Language: it_IT\n" @@ -29,14 +29,14 @@ msgstr "" msgid "No matching action found" msgstr "" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "" @@ -72,41 +72,41 @@ msgstr "" msgid "Select Category" msgstr "" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" -#: InvenTree/models.py:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "" @@ -147,7 +147,7 @@ msgstr "" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -155,7 +155,7 @@ msgstr "" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -172,23 +172,23 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "" @@ -446,11 +446,11 @@ msgid "Order target date" msgstr "" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "" @@ -463,11 +463,11 @@ msgstr "" #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -476,7 +476,7 @@ msgstr "" #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -486,8 +486,8 @@ msgstr "" #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -501,7 +501,7 @@ msgstr "" msgid "Enter quantity for build output" msgstr "" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "" @@ -534,7 +534,7 @@ msgstr "" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "" @@ -544,10 +544,10 @@ msgid "Location of completed parts" msgstr "" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -592,8 +592,8 @@ msgstr "" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -603,12 +603,12 @@ msgstr "" msgid "Build Order Reference" msgstr "" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "" @@ -628,7 +628,7 @@ msgstr "" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -643,8 +643,8 @@ msgstr "" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -703,7 +703,7 @@ msgstr "" msgid "Build status code" msgstr "" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "" @@ -711,16 +711,16 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "" @@ -737,7 +737,7 @@ msgid "User who issued this build order" msgstr "" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -754,30 +754,30 @@ msgstr "" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "" @@ -810,11 +810,11 @@ msgstr "" msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -828,7 +828,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "" @@ -841,7 +841,7 @@ msgstr "" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -879,7 +879,7 @@ msgstr "" msgid "Auto Allocate" msgstr "" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "" @@ -893,8 +893,8 @@ msgstr "" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "" @@ -915,16 +915,16 @@ msgstr "" #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "" @@ -977,7 +977,7 @@ msgstr "" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1036,7 +1036,7 @@ msgid "Progress" msgstr "" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1183,7 +1183,7 @@ msgstr "" msgid "Stock can be taken from any available location." msgstr "" -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1203,7 +1203,7 @@ msgstr "" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "" @@ -1211,7 +1211,7 @@ msgstr "" msgid "No target date set" msgstr "" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "" @@ -1250,7 +1250,7 @@ msgstr "" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "" @@ -1412,8 +1412,8 @@ msgstr "" msgid "Stock item is over-allocated" msgstr "" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "" @@ -1433,56 +1433,56 @@ msgstr "" msgid "Add Build Order Attachment" msgstr "" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "" @@ -1520,335 +1520,359 @@ msgid "Base URL for server instance" msgstr "" #: common/models.py:85 -msgid "Download from URL" +msgid "Default Currency" msgstr "" #: common/models.py:86 -msgid "Allow download of remote images and files from external URL" +msgid "Default currency" msgstr "" #: common/models.py:92 -msgid "Barcode Support" +msgid "Download from URL" msgstr "" #: common/models.py:93 -msgid "Enable barcode scanner support" +msgid "Allow download of remote images and files from external URL" msgstr "" #: common/models.py:99 -msgid "IPN Regex" +msgid "Barcode Support" msgstr "" #: common/models.py:100 +msgid "Enable barcode scanner support" +msgstr "" + +#: common/models.py:106 +msgid "IPN Regex" +msgstr "" + +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "" -#: common/models.py:161 +#: common/models.py:168 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "" -#: common/models.py:168 +#: common/models.py:175 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 -msgid "Use the internal price (if set) in BOM-price calculations" +msgid "Display part price in some forms" msgstr "" -#: common/models.py:230 templates/stats.html:25 -msgid "Debug Mode" +#: common/models.py:230 +msgid "Show related parts" msgstr "" #: common/models.py:231 -msgid "Generate reports in debug mode (HTML output)" +msgid "Display related parts for a part" msgstr "" #: common/models.py:237 -msgid "Page Size" +msgid "Internal Prices" msgstr "" #: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 +msgid "Use the internal price (if set) in BOM-price calculations" +msgstr "" + +#: common/models.py:251 templates/stats.html:25 +msgid "Debug Mode" +msgstr "" + +#: common/models.py:252 +msgid "Generate reports in debug mode (HTML output)" +msgstr "" + +#: common/models.py:258 +msgid "Page Size" +msgstr "" + +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "" @@ -1856,27 +1880,30 @@ msgstr "" msgid "Current value" msgstr "" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "" @@ -1884,44 +1911,57 @@ msgstr "" msgid "Match Items" msgstr "" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1981,7 +2021,7 @@ msgid "Point of contact" msgstr "" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2020,12 +2060,12 @@ msgstr "" msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "" @@ -2061,7 +2101,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "" @@ -2082,7 +2122,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2134,7 +2174,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "" @@ -2153,7 +2193,7 @@ msgstr "" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "" @@ -2173,7 +2213,7 @@ msgstr "" msgid "Download image from URL" msgstr "" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "" @@ -2218,9 +2258,9 @@ msgstr "" msgid "Uses default currency" msgstr "" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2243,7 +2283,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2251,7 +2291,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "" @@ -2267,7 +2307,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "" @@ -2294,7 +2334,7 @@ msgstr "" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "" @@ -2372,8 +2412,8 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "" @@ -2385,7 +2425,7 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2418,16 +2458,16 @@ msgid "Delete" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "" @@ -2446,7 +2486,7 @@ msgstr "" msgid "Supplied Parts" msgstr "" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2463,7 +2503,7 @@ msgstr "" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2475,7 +2515,7 @@ msgstr "" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2508,7 +2548,7 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "" @@ -2558,7 +2598,7 @@ msgid "Pricing Information" msgstr "" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "" @@ -2577,8 +2617,8 @@ msgstr "" msgid "Delete price break" msgstr "" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "" @@ -2600,20 +2640,20 @@ msgstr "" msgid "New Company" msgstr "" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "" @@ -2681,15 +2721,15 @@ msgstr "" msgid "Delete Supplier Part" msgstr "" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "" @@ -2754,178 +2794,178 @@ msgstr "" msgid "Filters" msgstr "" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "" -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "" -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2933,77 +2973,77 @@ msgstr "" msgid "Purchase Order" msgstr "" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "" @@ -3053,7 +3093,7 @@ msgstr "" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3091,57 +3131,71 @@ msgstr "" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "" -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "" @@ -3150,6 +3204,8 @@ msgid "Upload File for Purchase Order" msgstr "" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "" @@ -3239,8 +3295,8 @@ msgid "Purchase Order Items" msgstr "" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "" @@ -3288,9 +3344,9 @@ msgstr "" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3356,18 +3412,18 @@ msgstr "" msgid "Sales Order Items" msgstr "" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "" @@ -3379,8 +3435,8 @@ msgstr "" msgid "ID" msgstr "" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "" @@ -3396,7 +3452,7 @@ msgstr "" msgid "Allocate serial numbers" msgstr "" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "" @@ -3404,8 +3460,8 @@ msgstr "" msgid "Purchase stock" msgstr "" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "" @@ -3459,195 +3515,195 @@ msgstr "" msgid "Sales Order Attachments" msgstr "" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "" @@ -3825,8 +3881,8 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "" @@ -3876,7 +3932,7 @@ msgstr "" msgid "Part description" msgstr "" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "" @@ -4101,7 +4157,7 @@ msgstr "" msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "" @@ -4133,7 +4189,7 @@ msgstr "" msgid "BOM line checksum" msgstr "" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "" @@ -4142,7 +4198,7 @@ msgstr "" msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "" @@ -4150,8 +4206,8 @@ msgstr "" msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "" @@ -4199,8 +4255,8 @@ msgstr "" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "" @@ -4247,7 +4303,7 @@ msgstr "" msgid "Validate Bill of Materials" msgstr "" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "" @@ -4263,7 +4319,7 @@ msgstr "" msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "" @@ -4300,7 +4356,7 @@ msgid "Select Part" msgstr "" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "" @@ -4341,87 +4397,87 @@ msgstr "" msgid "Start New Build" msgstr "" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "" @@ -4460,12 +4516,17 @@ msgstr "" msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "" @@ -4489,7 +4550,7 @@ msgstr "" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "" @@ -4569,12 +4630,21 @@ msgstr "" msgid "Part is not active" msgstr "" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4612,78 +4682,78 @@ msgstr "" msgid "Create new manufacturer" msgstr "" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4691,10 +4761,10 @@ msgstr "" msgid "Unit Cost" msgstr "" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4702,51 +4772,51 @@ msgstr "" msgid "Total Cost" msgstr "" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "" -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "" @@ -4847,7 +4917,7 @@ msgstr "" msgid "Allocated to Orders" msgstr "" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "" @@ -4965,220 +5035,224 @@ msgstr "" msgid "Unknown database" msgstr "" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5284,12 +5358,12 @@ msgid "Test Results" msgstr "" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "" @@ -5316,7 +5390,7 @@ msgstr "" msgid "Moved {n} parts to {loc}" msgstr "" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "" @@ -5406,187 +5480,187 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "" @@ -5738,7 +5812,7 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "" @@ -6135,7 +6209,7 @@ msgstr "" msgid "Serialize Stock" msgstr "" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "" @@ -6284,12 +6358,12 @@ msgid "No category parameter templates found" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "" @@ -6297,23 +6371,23 @@ msgstr "" msgid "Currency Settings" msgstr "" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "" @@ -6337,11 +6411,19 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "" @@ -6626,7 +6708,7 @@ msgstr "" msgid "Barcode does not match a valid location" msgstr "" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "" @@ -6638,31 +6720,35 @@ msgstr "" msgid "Purchase Price Average" msgstr "" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "" @@ -6690,37 +6776,37 @@ msgstr "" msgid "Location not specified" msgstr "" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "" diff --git a/InvenTree/locale/ja/LC_MESSAGES/django.po b/InvenTree/locale/ja/LC_MESSAGES/django.po index fa6df1a934..5fb994a1e8 100644 --- a/InvenTree/locale/ja/LC_MESSAGES/django.po +++ b/InvenTree/locale/ja/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" -"PO-Revision-Date: 2021-06-24 21:40\n" +"POT-Creation-Date: 2021-07-01 22:35+0000\n" +"PO-Revision-Date: 2021-07-01 22:38\n" "Last-Translator: \n" "Language-Team: Japanese\n" "Language: ja_JP\n" @@ -29,14 +29,14 @@ msgstr "" msgid "No matching action found" msgstr "" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "" @@ -72,41 +72,41 @@ msgstr "" msgid "Select Category" msgstr "" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" -#: InvenTree/models.py:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "" @@ -147,7 +147,7 @@ msgstr "" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -155,7 +155,7 @@ msgstr "" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -172,23 +172,23 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "" @@ -446,11 +446,11 @@ msgid "Order target date" msgstr "" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "" @@ -463,11 +463,11 @@ msgstr "" #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -476,7 +476,7 @@ msgstr "" #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -486,8 +486,8 @@ msgstr "" #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -501,7 +501,7 @@ msgstr "" msgid "Enter quantity for build output" msgstr "" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "" @@ -534,7 +534,7 @@ msgstr "" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "" @@ -544,10 +544,10 @@ msgid "Location of completed parts" msgstr "" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -592,8 +592,8 @@ msgstr "" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -603,12 +603,12 @@ msgstr "" msgid "Build Order Reference" msgstr "" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "" @@ -628,7 +628,7 @@ msgstr "" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -643,8 +643,8 @@ msgstr "" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -703,7 +703,7 @@ msgstr "" msgid "Build status code" msgstr "" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "" @@ -711,16 +711,16 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "" @@ -737,7 +737,7 @@ msgid "User who issued this build order" msgstr "" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -754,30 +754,30 @@ msgstr "" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "" @@ -810,11 +810,11 @@ msgstr "" msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -828,7 +828,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "" @@ -841,7 +841,7 @@ msgstr "" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -879,7 +879,7 @@ msgstr "" msgid "Auto Allocate" msgstr "" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "" @@ -893,8 +893,8 @@ msgstr "" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "" @@ -915,16 +915,16 @@ msgstr "" #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "" @@ -977,7 +977,7 @@ msgstr "" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1036,7 +1036,7 @@ msgid "Progress" msgstr "" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1183,7 +1183,7 @@ msgstr "" msgid "Stock can be taken from any available location." msgstr "" -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1203,7 +1203,7 @@ msgstr "" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "" @@ -1211,7 +1211,7 @@ msgstr "" msgid "No target date set" msgstr "" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "" @@ -1250,7 +1250,7 @@ msgstr "" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "" @@ -1412,8 +1412,8 @@ msgstr "" msgid "Stock item is over-allocated" msgstr "" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "" @@ -1433,56 +1433,56 @@ msgstr "" msgid "Add Build Order Attachment" msgstr "" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "" @@ -1520,335 +1520,359 @@ msgid "Base URL for server instance" msgstr "" #: common/models.py:85 -msgid "Download from URL" +msgid "Default Currency" msgstr "" #: common/models.py:86 -msgid "Allow download of remote images and files from external URL" +msgid "Default currency" msgstr "" #: common/models.py:92 -msgid "Barcode Support" +msgid "Download from URL" msgstr "" #: common/models.py:93 -msgid "Enable barcode scanner support" +msgid "Allow download of remote images and files from external URL" msgstr "" #: common/models.py:99 -msgid "IPN Regex" +msgid "Barcode Support" msgstr "" #: common/models.py:100 +msgid "Enable barcode scanner support" +msgstr "" + +#: common/models.py:106 +msgid "IPN Regex" +msgstr "" + +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "" -#: common/models.py:161 +#: common/models.py:168 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "" -#: common/models.py:168 +#: common/models.py:175 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 -msgid "Use the internal price (if set) in BOM-price calculations" +msgid "Display part price in some forms" msgstr "" -#: common/models.py:230 templates/stats.html:25 -msgid "Debug Mode" +#: common/models.py:230 +msgid "Show related parts" msgstr "" #: common/models.py:231 -msgid "Generate reports in debug mode (HTML output)" +msgid "Display related parts for a part" msgstr "" #: common/models.py:237 -msgid "Page Size" +msgid "Internal Prices" msgstr "" #: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 +msgid "Use the internal price (if set) in BOM-price calculations" +msgstr "" + +#: common/models.py:251 templates/stats.html:25 +msgid "Debug Mode" +msgstr "" + +#: common/models.py:252 +msgid "Generate reports in debug mode (HTML output)" +msgstr "" + +#: common/models.py:258 +msgid "Page Size" +msgstr "" + +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "" @@ -1856,27 +1880,30 @@ msgstr "" msgid "Current value" msgstr "" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "" @@ -1884,44 +1911,57 @@ msgstr "" msgid "Match Items" msgstr "" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1981,7 +2021,7 @@ msgid "Point of contact" msgstr "" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2020,12 +2060,12 @@ msgstr "" msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "" @@ -2061,7 +2101,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "" @@ -2082,7 +2122,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2134,7 +2174,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "" @@ -2153,7 +2193,7 @@ msgstr "" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "" @@ -2173,7 +2213,7 @@ msgstr "" msgid "Download image from URL" msgstr "" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "" @@ -2218,9 +2258,9 @@ msgstr "" msgid "Uses default currency" msgstr "" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2243,7 +2283,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2251,7 +2291,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "" @@ -2267,7 +2307,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "" @@ -2294,7 +2334,7 @@ msgstr "" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "" @@ -2372,8 +2412,8 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "" @@ -2385,7 +2425,7 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2418,16 +2458,16 @@ msgid "Delete" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "" @@ -2446,7 +2486,7 @@ msgstr "" msgid "Supplied Parts" msgstr "" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2463,7 +2503,7 @@ msgstr "" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2475,7 +2515,7 @@ msgstr "" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2508,7 +2548,7 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "" @@ -2558,7 +2598,7 @@ msgid "Pricing Information" msgstr "" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "" @@ -2577,8 +2617,8 @@ msgstr "" msgid "Delete price break" msgstr "" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "" @@ -2600,20 +2640,20 @@ msgstr "" msgid "New Company" msgstr "" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "" @@ -2681,15 +2721,15 @@ msgstr "" msgid "Delete Supplier Part" msgstr "" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "" @@ -2754,178 +2794,178 @@ msgstr "" msgid "Filters" msgstr "" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "" -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "" -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2933,77 +2973,77 @@ msgstr "" msgid "Purchase Order" msgstr "" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "" @@ -3053,7 +3093,7 @@ msgstr "" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3091,57 +3131,71 @@ msgstr "" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "" -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "" @@ -3150,6 +3204,8 @@ msgid "Upload File for Purchase Order" msgstr "" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "" @@ -3239,8 +3295,8 @@ msgid "Purchase Order Items" msgstr "" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "" @@ -3288,9 +3344,9 @@ msgstr "" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3356,18 +3412,18 @@ msgstr "" msgid "Sales Order Items" msgstr "" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "" @@ -3379,8 +3435,8 @@ msgstr "" msgid "ID" msgstr "" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "" @@ -3396,7 +3452,7 @@ msgstr "" msgid "Allocate serial numbers" msgstr "" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "" @@ -3404,8 +3460,8 @@ msgstr "" msgid "Purchase stock" msgstr "" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "" @@ -3459,195 +3515,195 @@ msgstr "" msgid "Sales Order Attachments" msgstr "" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "" @@ -3825,8 +3881,8 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "" @@ -3876,7 +3932,7 @@ msgstr "" msgid "Part description" msgstr "" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "" @@ -4101,7 +4157,7 @@ msgstr "" msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "" @@ -4133,7 +4189,7 @@ msgstr "" msgid "BOM line checksum" msgstr "" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "" @@ -4142,7 +4198,7 @@ msgstr "" msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "" @@ -4150,8 +4206,8 @@ msgstr "" msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "" @@ -4199,8 +4255,8 @@ msgstr "" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "" @@ -4247,7 +4303,7 @@ msgstr "" msgid "Validate Bill of Materials" msgstr "" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "" @@ -4263,7 +4319,7 @@ msgstr "" msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "" @@ -4300,7 +4356,7 @@ msgid "Select Part" msgstr "" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "" @@ -4341,87 +4397,87 @@ msgstr "" msgid "Start New Build" msgstr "" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "" @@ -4460,12 +4516,17 @@ msgstr "" msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "" @@ -4489,7 +4550,7 @@ msgstr "" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "" @@ -4569,12 +4630,21 @@ msgstr "" msgid "Part is not active" msgstr "" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4612,78 +4682,78 @@ msgstr "" msgid "Create new manufacturer" msgstr "" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4691,10 +4761,10 @@ msgstr "" msgid "Unit Cost" msgstr "" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4702,51 +4772,51 @@ msgstr "" msgid "Total Cost" msgstr "" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "" -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "" @@ -4847,7 +4917,7 @@ msgstr "" msgid "Allocated to Orders" msgstr "" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "" @@ -4965,220 +5035,224 @@ msgstr "" msgid "Unknown database" msgstr "" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5284,12 +5358,12 @@ msgid "Test Results" msgstr "" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "" @@ -5316,7 +5390,7 @@ msgstr "" msgid "Moved {n} parts to {loc}" msgstr "" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "" @@ -5406,187 +5480,187 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "" @@ -5738,7 +5812,7 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "" @@ -6135,7 +6209,7 @@ msgstr "" msgid "Serialize Stock" msgstr "" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "" @@ -6284,12 +6358,12 @@ msgid "No category parameter templates found" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "" @@ -6297,23 +6371,23 @@ msgstr "" msgid "Currency Settings" msgstr "" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "" @@ -6337,11 +6411,19 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "" @@ -6626,7 +6708,7 @@ msgstr "" msgid "Barcode does not match a valid location" msgstr "" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "" @@ -6638,31 +6720,35 @@ msgstr "" msgid "Purchase Price Average" msgstr "" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "" @@ -6690,37 +6776,37 @@ msgstr "" msgid "Location not specified" msgstr "" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "" diff --git a/InvenTree/locale/pl/LC_MESSAGES/django.po b/InvenTree/locale/pl/LC_MESSAGES/django.po index 4bc233a127..200625b8cb 100644 --- a/InvenTree/locale/pl/LC_MESSAGES/django.po +++ b/InvenTree/locale/pl/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" -"PO-Revision-Date: 2021-06-24 21:40\n" +"POT-Creation-Date: 2021-07-01 22:35+0000\n" +"PO-Revision-Date: 2021-07-01 22:38\n" "Last-Translator: \n" "Language-Team: Polish\n" "Language: pl_PL\n" @@ -29,14 +29,14 @@ msgstr "Nie określono działania" msgid "No matching action found" msgstr "Nie znaleziono pasującej akcji" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "Wprowadź dane" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "Potwierdź" @@ -72,41 +72,41 @@ msgstr "Zastosuj motyw" msgid "Select Category" msgstr "Wybierz kategorię" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Powtórzony numer seryjny: {n}" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "Podano nieprawidłową ilość" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "Pusty ciąg numeru seryjnego" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "Nieprawidłowa grupa: {g}" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "Powtórzony numer seryjny: {g}" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "Nie znaleziono numerów seryjnych" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, 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:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "Załącznik" @@ -147,7 +147,7 @@ msgstr "Nazwa" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -155,7 +155,7 @@ msgstr "Nazwa" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -172,23 +172,23 @@ msgstr "Opis (opcjonalny)" msgid "parent" msgstr "nadrzędny" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "Angielski" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "Francuski" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "Niemiecki" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "Polski" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "Turecki" @@ -446,11 +446,11 @@ msgid "Order target date" msgstr "" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "Data docelowa" @@ -463,11 +463,11 @@ msgstr "" #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -476,7 +476,7 @@ msgstr "" #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -486,8 +486,8 @@ msgstr "" #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -501,7 +501,7 @@ msgstr "" msgid "Enter quantity for build output" msgstr "" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "Numer seryjny" @@ -534,7 +534,7 @@ msgstr "Oznacz budowę jako ukończoną" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "Lokalizacja" @@ -544,10 +544,10 @@ msgid "Location of completed parts" msgstr "Lokalizacja ukończonych części" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -592,8 +592,8 @@ msgstr "Zlecenie Budowy" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -603,12 +603,12 @@ msgstr "Zlecenia budowy" msgid "Build Order Reference" msgstr "Odwołanie do zamówienia wykonania" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "Referencja" @@ -628,7 +628,7 @@ msgstr "Zamówienie budowy, do którego budowa jest przypisana" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -643,8 +643,8 @@ msgstr "Zamówienie budowy, do którego budowa jest przypisana" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -703,7 +703,7 @@ msgstr "Status budowania" msgid "Build status code" msgstr "Kod statusu budowania" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "Kod partii" @@ -711,16 +711,16 @@ msgstr "Kod partii" msgid "Batch code for this build output" msgstr "Kod partii dla wyjścia budowy" -#: build/models.py:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "Data utworzenia" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "Docelowy termin zakończenia" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "Data zakończenia" @@ -737,7 +737,7 @@ msgid "User who issued this build order" msgstr "Użytkownik, który wydał to zamówienie" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -754,30 +754,30 @@ msgstr "Użytkownik odpowiedzialny za to zamówienie budowy" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "Link Zewnętrzny" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "Link do zewnętrznego adresu URL" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "Uwagi" @@ -810,11 +810,11 @@ msgstr "" msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -828,7 +828,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "Budowa" @@ -841,7 +841,7 @@ msgstr "" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -879,7 +879,7 @@ msgstr "Przydziel zapasy do budowy" msgid "Auto Allocate" msgstr "Automatyczne przypisywanie" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "Cofnij przydział zapasów" @@ -893,8 +893,8 @@ msgstr "Zamów wymagane komponenty" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "Zamów części" @@ -915,16 +915,16 @@ msgstr "" #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "Numer Seryjny" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "Załączniki" @@ -977,7 +977,7 @@ msgstr "" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1036,7 +1036,7 @@ msgid "Progress" msgstr "Postęp" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1183,7 +1183,7 @@ msgstr "Źródło magazynu" msgid "Stock can be taken from any available location." msgstr "" -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1203,7 +1203,7 @@ msgstr "Partia" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "Utworzony" @@ -1211,7 +1211,7 @@ msgstr "Utworzony" msgid "No target date set" msgstr "" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "Zakończone" @@ -1250,7 +1250,7 @@ msgstr "Szczegóły zlecenia budowy" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "Szczegóły" @@ -1412,8 +1412,8 @@ msgstr "" msgid "Stock item is over-allocated" msgstr "" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "Dostępne" @@ -1433,56 +1433,56 @@ msgstr "" msgid "Add Build Order Attachment" msgstr "" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "Dodano załącznik" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "Edytuj załącznik" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "Załącznik zaktualizowany" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "Usuń załącznik" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "Załącznik usunięto" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "" @@ -1520,335 +1520,359 @@ msgid "Base URL for server instance" msgstr "Bazowy adres URL dla instancji serwera" #: common/models.py:85 +msgid "Default Currency" +msgstr "" + +#: common/models.py:86 +msgid "Default currency" +msgstr "" + +#: common/models.py:92 msgid "Download from URL" msgstr "Pobierz z adresu URL" -#: common/models.py:86 +#: common/models.py:93 msgid "Allow download of remote images and files from external URL" msgstr "Zezwól na pobieranie zewnętrznych obrazów i plików z zewnętrznego URL" -#: common/models.py:92 +#: common/models.py:99 msgid "Barcode Support" msgstr "Obsługa kodu kreskowego" -#: common/models.py:93 +#: common/models.py:100 msgid "Enable barcode scanner support" msgstr "Włącz obsługę skanera kodów" -#: common/models.py:99 +#: common/models.py:106 msgid "IPN Regex" msgstr "Wyrażenie regularne IPN" -#: common/models.py:100 +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "Zezwól na powtarzający się IPN" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "Zezwól na edycję IPN" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "Skopiuj BOM komponentu" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "Szablon" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "Złożenie" -#: common/models.py:161 +#: common/models.py:168 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "Komponent" -#: common/models.py:168 +#: common/models.py:175 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "Możliwość zakupu" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "Części są domyślnie z możliwością zakupu" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "Możliwość sprzedaży" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "Części są domyślnie z możliwością sprzedaży" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "Możliwość śledzenia" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "Części są domyślnie z możliwością śledzenia" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "Wirtualny" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "Części są domyślnie wirtualne" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 -msgid "Use the internal price (if set) in BOM-price calculations" +msgid "Display part price in some forms" msgstr "" -#: common/models.py:230 templates/stats.html:25 -msgid "Debug Mode" -msgstr "Tryb Debugowania" +#: common/models.py:230 +msgid "Show related parts" +msgstr "" #: common/models.py:231 -msgid "Generate reports in debug mode (HTML output)" +msgid "Display related parts for a part" msgstr "" #: common/models.py:237 +msgid "Internal Prices" +msgstr "" + +#: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 +msgid "Use the internal price (if set) in BOM-price calculations" +msgstr "" + +#: common/models.py:251 templates/stats.html:25 +msgid "Debug Mode" +msgstr "Tryb Debugowania" + +#: common/models.py:252 +msgid "Generate reports in debug mode (HTML output)" +msgstr "" + +#: common/models.py:258 msgid "Page Size" msgstr "Rozmiar strony" -#: common/models.py:238 +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "Raporty testów" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "Włącz generowanie raportów testów" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "dni" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "Grupuj według komponentu" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "Ustawienia wartości" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "Cena" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "Domyślny" @@ -1856,27 +1880,30 @@ msgstr "Domyślny" msgid "Current value" msgstr "Aktualna wartość" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "Zmień ustawienie" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "Wyślij plik" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "" @@ -1884,44 +1911,57 @@ msgstr "" msgid "Match Items" msgstr "" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "Waluta" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "URL" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "URL zdjęcia" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "Cena jednostkowa" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "Cena jednostkowa" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "Wybierz producenta" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "Numer producenta" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1981,7 +2021,7 @@ msgid "Point of contact" msgstr "Punkt kontaktowy" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2020,12 +2060,12 @@ msgstr "jest producentem" msgid "Does this company manufacture parts?" msgstr "Czy to przedsiębiorstwo produkuje części?" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "Część bazowa" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "Wybierz część" @@ -2061,7 +2101,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "" @@ -2082,7 +2122,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2134,7 +2174,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "Opakowanie" @@ -2153,7 +2193,7 @@ msgstr "" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "" @@ -2173,7 +2213,7 @@ msgstr "Prześlij nowy obraz" msgid "Download image from URL" msgstr "" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "" @@ -2218,9 +2258,9 @@ msgstr "Nie określono strony internetowej" msgid "Uses default currency" msgstr "" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2243,7 +2283,7 @@ msgstr "Nowa część producenta" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2251,7 +2291,7 @@ msgstr "Opcje" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "Zamów części" @@ -2267,7 +2307,7 @@ msgstr "Usuń części" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "Nowy komponent" @@ -2294,7 +2334,7 @@ msgstr "Zapasy dostawcy" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "Eksportuj" @@ -2372,8 +2412,8 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "Dostawcy" @@ -2385,7 +2425,7 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2418,16 +2458,16 @@ msgid "Delete" msgstr "Usuń" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "Parametry" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "" @@ -2446,7 +2486,7 @@ msgstr "" msgid "Supplied Parts" msgstr "Dostarczone części" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2463,7 +2503,7 @@ msgstr "" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2475,7 +2515,7 @@ msgstr "" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2508,7 +2548,7 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "" @@ -2558,7 +2598,7 @@ msgid "Pricing Information" msgstr "Informacja cenowa" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "" @@ -2577,8 +2617,8 @@ msgstr "Edytuj przedział cenowy" msgid "Delete price break" msgstr "" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "Producenci" @@ -2600,20 +2640,20 @@ msgstr "Firmy" msgid "New Company" msgstr "Nowa firma" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "Pobierz obraz" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "" @@ -2681,15 +2721,15 @@ msgstr "" msgid "Delete Supplier Part" msgstr "" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "Edytuj przedział cenowy" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "" @@ -2754,178 +2794,178 @@ msgstr "" msgid "Filters" msgstr "Filtry" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "Złóż zamówienie" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "Oznacz zamówienie jako zakończone" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "Anuluj zamówienie" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "Wyślij zamówienie" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "" -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "" -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "Wprowadź ilość produktów magazynowych" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "Odniesienie zamówienia" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "Opis Zamówienia" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "Link do zewnętrznej witryny" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "Utworzony przez" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "Użytkownik lub grupa odpowiedzialna za to zamówienie" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "Notatki do zamówienia" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "odebrane przez" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "Data wydania" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "Data wysyłki" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "wysłane przez" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "Ilość elementów" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "Zamówienie" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2933,77 +2973,77 @@ msgstr "Zamówienie" msgid "Purchase Order" msgstr "" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "Odebrane" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "Cena zakupu" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "Cena zakupu jednostkowego" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "Cena sprzedaży" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "Jednostkowa cena sprzedaży" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "Linia" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "Komponent" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "" @@ -3053,7 +3093,7 @@ msgstr "Wydany" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3091,57 +3131,71 @@ msgstr "Notatki zamówień" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "" -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "Wiersz" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "" @@ -3150,6 +3204,8 @@ msgid "Upload File for Purchase Order" msgstr "" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "" @@ -3239,8 +3295,8 @@ msgid "Purchase Order Items" msgstr "" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "" @@ -3288,9 +3344,9 @@ msgstr "" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3356,18 +3412,18 @@ msgstr "" msgid "Sales Order Items" msgstr "" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "Akcje" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "" @@ -3379,8 +3435,8 @@ msgstr "" msgid "ID" msgstr "Numer ID" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "Przydzielono" @@ -3396,7 +3452,7 @@ msgstr "" msgid "Allocate serial numbers" msgstr "" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "" @@ -3404,8 +3460,8 @@ msgstr "" msgid "Purchase stock" msgstr "" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "" @@ -3459,195 +3515,195 @@ msgstr "" msgid "Sales Order Attachments" msgstr "" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "Wyślij zamówienie" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "Otrzymane przedmioty" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "Nie ustawiono miejsca docelowego" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "Błąd konwersji ilości na liczbę" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "Nie znaleziono ceny" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "Domyślna lokalizacja" @@ -3825,8 +3881,8 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "" @@ -3876,7 +3932,7 @@ msgstr "Wariant" msgid "Part description" msgstr "Opis części" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "Słowa kluczowe" @@ -4101,7 +4157,7 @@ msgstr "" msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "" @@ -4133,7 +4189,7 @@ msgstr "Suma kontrolna" msgid "BOM line checksum" msgstr "" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "" @@ -4142,7 +4198,7 @@ msgstr "" msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "" @@ -4150,8 +4206,8 @@ msgstr "" msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "" @@ -4199,8 +4255,8 @@ msgstr "" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "Zestawienie materiałowe" @@ -4247,7 +4303,7 @@ msgstr "" msgid "Validate Bill of Materials" msgstr "" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "" @@ -4263,7 +4319,7 @@ msgstr "" msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "" @@ -4300,7 +4356,7 @@ msgid "Select Part" msgstr "" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "" @@ -4341,87 +4397,87 @@ msgstr "" msgid "Start New Build" msgstr "" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "Wszystkie części" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "Stwórz nową kategorię komponentów" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "Utwórz nową lokalizację magazynową" @@ -4460,12 +4516,17 @@ msgstr "" msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "Parametry części" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "Duplikuj część" @@ -4489,7 +4550,7 @@ msgstr "" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "Szczegóły części" @@ -4569,12 +4630,21 @@ msgstr "" msgid "Part is not active" msgstr "" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4612,78 +4682,78 @@ msgstr "" msgid "Create new manufacturer" msgstr "" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4691,10 +4761,10 @@ msgstr "" msgid "Unit Cost" msgstr "" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4702,51 +4772,51 @@ msgstr "" msgid "Total Cost" msgstr "" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "" -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "" @@ -4847,7 +4917,7 @@ msgstr "" msgid "Allocated to Orders" msgstr "" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "" @@ -4965,220 +5035,224 @@ msgstr "" msgid "Unknown database" msgstr "" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5284,12 +5358,12 @@ msgid "Test Results" msgstr "" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "" @@ -5316,7 +5390,7 @@ msgstr "" msgid "Moved {n} parts to {loc}" msgstr "" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "" @@ -5406,187 +5480,187 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "" @@ -5738,7 +5812,7 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "" @@ -6135,7 +6209,7 @@ msgstr "" msgid "Serialize Stock" msgstr "" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "" @@ -6284,12 +6358,12 @@ msgid "No category parameter templates found" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "" @@ -6297,23 +6371,23 @@ msgstr "" msgid "Currency Settings" msgstr "" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "" @@ -6337,11 +6411,19 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "" @@ -6626,7 +6708,7 @@ msgstr "" msgid "Barcode does not match a valid location" msgstr "" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "" @@ -6638,31 +6720,35 @@ msgstr "" msgid "Purchase Price Average" msgstr "" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "" @@ -6690,37 +6776,37 @@ msgstr "" msgid "Location not specified" msgstr "" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "" diff --git a/InvenTree/locale/ru/LC_MESSAGES/django.po b/InvenTree/locale/ru/LC_MESSAGES/django.po index 0b04ba9921..ea71217a29 100644 --- a/InvenTree/locale/ru/LC_MESSAGES/django.po +++ b/InvenTree/locale/ru/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" -"PO-Revision-Date: 2021-06-24 21:40\n" +"POT-Creation-Date: 2021-07-01 22:35+0000\n" +"PO-Revision-Date: 2021-07-01 22:38\n" "Last-Translator: \n" "Language-Team: Russian\n" "Language: ru_RU\n" @@ -29,14 +29,14 @@ msgstr "Действие не указано" msgid "No matching action found" msgstr "Соответствующее действие не найдено" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "Введите дату" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "Подтвердить" @@ -72,41 +72,41 @@ msgstr "Применить тему" msgid "Select Category" msgstr "Выбрать категорию" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Дублировать серийный номер: {n}" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "недопустимое количество" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "Пустая строка серийного номера" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "Некорректный идентификатор группы {g}" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "Повторяющийся серийный {g}" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "Серийных номеров не найдено" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "Число уникальных серийных номеров ({s}) должно соответствовать количеству ({q})" -#: InvenTree/models.py:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "Вложения" @@ -147,7 +147,7 @@ msgstr "Название" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -155,7 +155,7 @@ msgstr "Название" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -172,23 +172,23 @@ msgstr "Описание (необязательно)" msgid "parent" msgstr "родитель" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "Английский" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "Французский" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "Немецкий" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "Польский" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "Турецкий" @@ -446,11 +446,11 @@ msgid "Order target date" msgstr "Срок выполнения заказа" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "Целевая дата" @@ -463,11 +463,11 @@ msgstr "Целевая дата для сборки. Сборка будет п #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -476,7 +476,7 @@ msgstr "Целевая дата для сборки. Сборка будет п #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -486,8 +486,8 @@ msgstr "Целевая дата для сборки. Сборка будет п #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -501,7 +501,7 @@ msgstr "Количество элементов для сборки" msgid "Enter quantity for build output" msgstr "Введите количество для вывода сборки" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "Серийные номера" @@ -534,7 +534,7 @@ msgstr "Пометить сборку как завершенную" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "Расположение" @@ -544,10 +544,10 @@ msgid "Location of completed parts" msgstr "Расположение укомплектованных частей" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -592,8 +592,8 @@ msgstr "Порядок сборки" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -603,12 +603,12 @@ msgstr "Порядок сборки" msgid "Build Order Reference" msgstr "Ссылка на заказ" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "" @@ -628,7 +628,7 @@ msgstr "" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -643,8 +643,8 @@ msgstr "" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -703,7 +703,7 @@ msgstr "" msgid "Build status code" msgstr "" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "" @@ -711,16 +711,16 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "" @@ -737,7 +737,7 @@ msgid "User who issued this build order" msgstr "" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -754,30 +754,30 @@ msgstr "" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "" @@ -810,11 +810,11 @@ msgstr "" msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -828,7 +828,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "" @@ -841,7 +841,7 @@ msgstr "" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -879,7 +879,7 @@ msgstr "" msgid "Auto Allocate" msgstr "" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "" @@ -893,8 +893,8 @@ msgstr "" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "" @@ -915,16 +915,16 @@ msgstr "" #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "" @@ -977,7 +977,7 @@ msgstr "" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1036,7 +1036,7 @@ msgid "Progress" msgstr "" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1183,7 +1183,7 @@ msgstr "" msgid "Stock can be taken from any available location." msgstr "" -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1203,7 +1203,7 @@ msgstr "" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "" @@ -1211,7 +1211,7 @@ msgstr "" msgid "No target date set" msgstr "" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "" @@ -1250,7 +1250,7 @@ msgstr "" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "" @@ -1412,8 +1412,8 @@ msgstr "" msgid "Stock item is over-allocated" msgstr "" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "" @@ -1433,56 +1433,56 @@ msgstr "" msgid "Add Build Order Attachment" msgstr "" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "" @@ -1520,335 +1520,359 @@ msgid "Base URL for server instance" msgstr "" #: common/models.py:85 -msgid "Download from URL" +msgid "Default Currency" msgstr "" #: common/models.py:86 -msgid "Allow download of remote images and files from external URL" +msgid "Default currency" msgstr "" #: common/models.py:92 -msgid "Barcode Support" +msgid "Download from URL" msgstr "" #: common/models.py:93 -msgid "Enable barcode scanner support" +msgid "Allow download of remote images and files from external URL" msgstr "" #: common/models.py:99 -msgid "IPN Regex" +msgid "Barcode Support" msgstr "" #: common/models.py:100 +msgid "Enable barcode scanner support" +msgstr "" + +#: common/models.py:106 +msgid "IPN Regex" +msgstr "" + +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "" -#: common/models.py:161 +#: common/models.py:168 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "" -#: common/models.py:168 +#: common/models.py:175 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 -msgid "Use the internal price (if set) in BOM-price calculations" +msgid "Display part price in some forms" msgstr "" -#: common/models.py:230 templates/stats.html:25 -msgid "Debug Mode" +#: common/models.py:230 +msgid "Show related parts" msgstr "" #: common/models.py:231 -msgid "Generate reports in debug mode (HTML output)" +msgid "Display related parts for a part" msgstr "" #: common/models.py:237 -msgid "Page Size" +msgid "Internal Prices" msgstr "" #: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 +msgid "Use the internal price (if set) in BOM-price calculations" +msgstr "" + +#: common/models.py:251 templates/stats.html:25 +msgid "Debug Mode" +msgstr "" + +#: common/models.py:252 +msgid "Generate reports in debug mode (HTML output)" +msgstr "" + +#: common/models.py:258 +msgid "Page Size" +msgstr "" + +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "" @@ -1856,27 +1880,30 @@ msgstr "" msgid "Current value" msgstr "" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "" @@ -1884,44 +1911,57 @@ msgstr "" msgid "Match Items" msgstr "" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1981,7 +2021,7 @@ msgid "Point of contact" msgstr "" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2020,12 +2060,12 @@ msgstr "" msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "" @@ -2061,7 +2101,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "" @@ -2082,7 +2122,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2134,7 +2174,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "" @@ -2153,7 +2193,7 @@ msgstr "" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "" @@ -2173,7 +2213,7 @@ msgstr "" msgid "Download image from URL" msgstr "" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "" @@ -2218,9 +2258,9 @@ msgstr "" msgid "Uses default currency" msgstr "" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2243,7 +2283,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2251,7 +2291,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "" @@ -2267,7 +2307,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "" @@ -2294,7 +2334,7 @@ msgstr "" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "" @@ -2372,8 +2412,8 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "" @@ -2385,7 +2425,7 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2418,16 +2458,16 @@ msgid "Delete" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "" @@ -2446,7 +2486,7 @@ msgstr "" msgid "Supplied Parts" msgstr "" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2463,7 +2503,7 @@ msgstr "" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2475,7 +2515,7 @@ msgstr "" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2508,7 +2548,7 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "" @@ -2558,7 +2598,7 @@ msgid "Pricing Information" msgstr "" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "" @@ -2577,8 +2617,8 @@ msgstr "" msgid "Delete price break" msgstr "" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "" @@ -2600,20 +2640,20 @@ msgstr "" msgid "New Company" msgstr "" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "" @@ -2681,15 +2721,15 @@ msgstr "" msgid "Delete Supplier Part" msgstr "" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "" @@ -2754,178 +2794,178 @@ msgstr "" msgid "Filters" msgstr "" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "" -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "" -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2933,77 +2973,77 @@ msgstr "" msgid "Purchase Order" msgstr "" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "" @@ -3053,7 +3093,7 @@ msgstr "" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3091,57 +3131,71 @@ msgstr "" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "" -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "" @@ -3150,6 +3204,8 @@ msgid "Upload File for Purchase Order" msgstr "" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "" @@ -3239,8 +3295,8 @@ msgid "Purchase Order Items" msgstr "" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "" @@ -3288,9 +3344,9 @@ msgstr "" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3356,18 +3412,18 @@ msgstr "" msgid "Sales Order Items" msgstr "" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "" @@ -3379,8 +3435,8 @@ msgstr "" msgid "ID" msgstr "" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "" @@ -3396,7 +3452,7 @@ msgstr "" msgid "Allocate serial numbers" msgstr "" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "" @@ -3404,8 +3460,8 @@ msgstr "" msgid "Purchase stock" msgstr "" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "" @@ -3459,195 +3515,195 @@ msgstr "" msgid "Sales Order Attachments" msgstr "" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "" @@ -3825,8 +3881,8 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "" @@ -3876,7 +3932,7 @@ msgstr "" msgid "Part description" msgstr "" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "" @@ -4101,7 +4157,7 @@ msgstr "" msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "" @@ -4133,7 +4189,7 @@ msgstr "" msgid "BOM line checksum" msgstr "" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "" @@ -4142,7 +4198,7 @@ msgstr "" msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "" @@ -4150,8 +4206,8 @@ msgstr "" msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "" @@ -4199,8 +4255,8 @@ msgstr "" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "" @@ -4247,7 +4303,7 @@ msgstr "" msgid "Validate Bill of Materials" msgstr "" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "" @@ -4263,7 +4319,7 @@ msgstr "" msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "" @@ -4300,7 +4356,7 @@ msgid "Select Part" msgstr "" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "" @@ -4341,87 +4397,87 @@ msgstr "" msgid "Start New Build" msgstr "" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "" @@ -4460,12 +4516,17 @@ msgstr "" msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "" @@ -4489,7 +4550,7 @@ msgstr "" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "" @@ -4569,12 +4630,21 @@ msgstr "" msgid "Part is not active" msgstr "" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4612,78 +4682,78 @@ msgstr "" msgid "Create new manufacturer" msgstr "" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4691,10 +4761,10 @@ msgstr "" msgid "Unit Cost" msgstr "" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4702,51 +4772,51 @@ msgstr "" msgid "Total Cost" msgstr "" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "" -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "" @@ -4847,7 +4917,7 @@ msgstr "" msgid "Allocated to Orders" msgstr "" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "" @@ -4965,220 +5035,224 @@ msgstr "" msgid "Unknown database" msgstr "" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5284,12 +5358,12 @@ msgid "Test Results" msgstr "" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "" @@ -5316,7 +5390,7 @@ msgstr "" msgid "Moved {n} parts to {loc}" msgstr "" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "" @@ -5406,187 +5480,187 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "" @@ -5738,7 +5812,7 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "" @@ -6135,7 +6209,7 @@ msgstr "" msgid "Serialize Stock" msgstr "" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "" @@ -6284,12 +6358,12 @@ msgid "No category parameter templates found" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "" @@ -6297,23 +6371,23 @@ msgstr "" msgid "Currency Settings" msgstr "" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "" @@ -6337,11 +6411,19 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "" @@ -6626,7 +6708,7 @@ msgstr "" msgid "Barcode does not match a valid location" msgstr "" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "" @@ -6638,31 +6720,35 @@ msgstr "" msgid "Purchase Price Average" msgstr "" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "" @@ -6690,37 +6776,37 @@ msgstr "" msgid "Location not specified" msgstr "" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "" diff --git a/InvenTree/locale/tr/LC_MESSAGES/django.po b/InvenTree/locale/tr/LC_MESSAGES/django.po index 20d48e6e5b..4b8bfcdd8a 100644 --- a/InvenTree/locale/tr/LC_MESSAGES/django.po +++ b/InvenTree/locale/tr/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" -"PO-Revision-Date: 2021-06-24 21:40\n" +"POT-Creation-Date: 2021-07-01 22:35+0000\n" +"PO-Revision-Date: 2021-07-01 22:38\n" "Last-Translator: \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -29,14 +29,14 @@ msgstr "İşlem belirtilmedi" msgid "No matching action found" msgstr "Eşleşen eylem bulunamadı" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "Tarih giriniz" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "Onay" @@ -72,41 +72,41 @@ msgstr "Temayı Uygula" msgid "Select Category" msgstr "Kategori Seçin" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "Tekrarlanan seri {n}" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "Geçersiz veri sağlandı" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "Boş seri numarası dizesi" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "Geçersiz grup: {g}" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "Tekrarlanan seri {g}" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "Seri numarası bulunamadı" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, 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})" -#: InvenTree/models.py:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "Ek" @@ -147,7 +147,7 @@ msgstr "Adı" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -155,7 +155,7 @@ msgstr "Adı" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -172,23 +172,23 @@ msgstr "Açıklama (isteğe bağlı)" msgid "parent" msgstr "üst" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "İngilizce" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "Fransızca" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "Almanca" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "Polonyaca" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "Türkçe" @@ -446,11 +446,11 @@ msgid "Order target date" msgstr "Emir hedef tarihi" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "Hedeflenen tarih" @@ -463,11 +463,11 @@ msgstr "Yapım işinin tamamlanması için hedef tarih. Bu tarihten sonra yapım #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -476,7 +476,7 @@ msgstr "Yapım işinin tamamlanması için hedef tarih. Bu tarihten sonra yapım #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -486,8 +486,8 @@ msgstr "Yapım işinin tamamlanması için hedef tarih. Bu tarihten sonra yapım #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -501,7 +501,7 @@ msgstr "Yapılacak öge sayısı" msgid "Enter quantity for build output" msgstr "Yapım işi çıktısı için miktarını girin" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "Seri Numaraları" @@ -534,7 +534,7 @@ msgstr "Yapım işini tamamlandı olarak işaretle" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "Konum" @@ -544,10 +544,10 @@ msgid "Location of completed parts" msgstr "Tamamlanmış parçaların konumu" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -592,8 +592,8 @@ msgstr "Yapım İşi Emri" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -603,12 +603,12 @@ msgstr "Yapım İşi Emirleri" msgid "Build Order Reference" msgstr "Yapım İşi Emri Referansı" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "Referans" @@ -628,7 +628,7 @@ msgstr "Bu yapım işinin tahsis edildiği yapım işi emri" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -643,8 +643,8 @@ msgstr "Bu yapım işinin tahsis edildiği yapım işi emri" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -703,7 +703,7 @@ msgstr "Yapım İşi Durumu" msgid "Build status code" msgstr "Yapım işi durum kodu" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "Sıra numarası" @@ -711,16 +711,16 @@ 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:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "Oluşturulma tarihi" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "Hedef tamamlama tarihi" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "Tamamlama tarihi" @@ -737,7 +737,7 @@ msgid "User who issued this build order" msgstr "Bu yapım işi emrini veren kullanıcı" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -754,30 +754,30 @@ msgstr "Bu yapım işi emrinden sorumlu kullanıcı" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "Harici Bağlantı" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "Harici URL'ye bağlantı" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "Notlar" @@ -810,11 +810,11 @@ msgstr "Ana parça izlenebilir olarak işaretlendiğinden, yapım işi çıktıs msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "Tahsis edilecek miktar ({n}) mevcut miktarı ({q}) geçmemeli" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "Stok kalemi fazladan tahsis edilmiş" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "Tahsis edilen miktar sıfırdan büyük olmalıdır" @@ -828,7 +828,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "{p} parçasının malzeme listesindeki seçili stok kalemi bulunamadı" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "Yapım İşi" @@ -841,7 +841,7 @@ msgstr "Yapım işi için tahsis edilen parçalar" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -879,7 +879,7 @@ msgstr "Yapım işi için stok tahsis et" msgid "Auto Allocate" msgstr "Otomatik Tahsis Et" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "Stok tahsisini kaldır" @@ -893,8 +893,8 @@ msgstr "Gerekli parçaları sipariş edin" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "Parça Siparişi" @@ -915,16 +915,16 @@ msgstr "Bu yapım işi emri, herhangi bir takip edilmeyen malzeme listesi öğes #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "Seri Numara" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "Ekler" @@ -977,7 +977,7 @@ msgstr "Stok, yapım işi emri için tamamen tahsis edilemedi" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1036,7 +1036,7 @@ msgid "Progress" msgstr "İlerleme" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1183,7 +1183,7 @@ msgstr "Stok Kaynağı" msgid "Stock can be taken from any available location." msgstr "Stok herhangi bir konumdan alınabilir." -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1203,7 +1203,7 @@ msgstr "Toplu" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "Oluşturuldu" @@ -1211,7 +1211,7 @@ msgstr "Oluşturuldu" msgid "No target date set" msgstr "Hedef tarih ayarlanmadı" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "Tamamlandı" @@ -1250,7 +1250,7 @@ msgstr "Yapım İşi Emri Detayları" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "Detaylar" @@ -1412,8 +1412,8 @@ msgstr "Öge stokta bulunmalı" msgid "Stock item is over-allocated" msgstr "Stok kalemi fazladan tahsis edilmiş" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "Mevcut" @@ -1433,56 +1433,56 @@ msgstr "Yapım İşi Ögesini Güncelle" msgid "Add Build Order Attachment" msgstr "" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "Ek eklendi" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "Ek Düzenle" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "Ek güncellendi" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "Eki Sil" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "Eki sil" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "Desteklenmeyen dosya formatı: {ext.upper()}" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "Dosya okurken hata (geçersiz biçim)" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "Dosya okurken hata (hatalı ölçüler)" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "Dosya okurken hata (veri bozulmuş olabilir)" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "Dosya" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "Yüklenecek dosyayı seç" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "{name.title()} Dosya" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "{name} dosyasını yüklemek için seçin" @@ -1520,335 +1520,359 @@ msgid "Base URL for server instance" msgstr "" #: common/models.py:85 -msgid "Download from URL" +msgid "Default Currency" msgstr "" #: common/models.py:86 -msgid "Allow download of remote images and files from external URL" -msgstr "Harici URL'den resim ve dosyaların indirilmesine izin ver" +msgid "Default currency" +msgstr "" #: common/models.py:92 -msgid "Barcode Support" +msgid "Download from URL" msgstr "" #: common/models.py:93 +msgid "Allow download of remote images and files from external URL" +msgstr "Harici URL'den resim ve dosyaların indirilmesine izin ver" + +#: common/models.py:99 +msgid "Barcode Support" +msgstr "" + +#: common/models.py:100 msgid "Enable barcode scanner support" msgstr "" -#: common/models.py:99 +#: common/models.py:106 msgid "IPN Regex" msgstr "DPN Regex" -#: common/models.py:100 +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "Parça DPN eşleştirmesi için Düzenli İfade Kalıbı (Regex)" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "Yinelenen DPN'ye İzin Ver" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "Birden çok parçanın aynı DPN'yi paylaşmasına izin ver" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "DPN Düzenlemeye İzin Ver" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "Parçayı düzenlerken DPN değiştirmeye izin ver" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "Kategori Paremetre Sablonu Kopyala" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "Parça oluştururken kategori parametre şablonlarını kopyala" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "Şablon" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "Parçaları varsayılan olan şablondur" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "Montaj" -#: common/models.py:161 +#: common/models.py:168 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:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "Bileşen" -#: common/models.py:168 +#: common/models.py:175 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:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "Satın Alınabilir" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "Parçalar varsayılan olarak satın alınabilir" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "Satılabilir" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "Parçalar varsayılan olarak satılabilir" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "Takip Edilebilir" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "Parçalar varsayılan olarak takip edilebilir" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "Sanal" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "Parçalar varsayılan olarak sanaldır" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 -msgid "Use the internal price (if set) in BOM-price calculations" +msgid "Display part price in some forms" msgstr "" -#: common/models.py:230 templates/stats.html:25 -msgid "Debug Mode" +#: common/models.py:230 +msgid "Show related parts" msgstr "" #: common/models.py:231 -msgid "Generate reports in debug mode (HTML output)" +msgid "Display related parts for a part" msgstr "" #: common/models.py:237 -msgid "Page Size" +msgid "Internal Prices" msgstr "" #: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 +msgid "Use the internal price (if set) in BOM-price calculations" +msgstr "" + +#: common/models.py:251 templates/stats.html:25 +msgid "Debug Mode" +msgstr "" + +#: common/models.py:252 +msgid "Generate reports in debug mode (HTML output)" +msgstr "" + +#: common/models.py:258 +msgid "Page Size" +msgstr "" + +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "Stok konumu ve ögeler üzerinde sahiplik kontrolünü etkinleştirin" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "" @@ -1856,27 +1880,30 @@ msgstr "" msgid "Current value" msgstr "" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "Dosya Yükle" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "" @@ -1884,44 +1911,57 @@ msgstr "" msgid "Match Items" msgstr "" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1981,7 +2021,7 @@ msgid "Point of contact" msgstr "" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2020,12 +2060,12 @@ msgstr "" msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "" @@ -2061,7 +2101,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "" @@ -2082,7 +2122,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2134,7 +2174,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "" @@ -2153,7 +2193,7 @@ msgstr "" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "Atanan Stok" @@ -2173,7 +2213,7 @@ msgstr "" msgid "Download image from URL" msgstr "" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "Satın Alma Emri Oluştur" @@ -2218,9 +2258,9 @@ msgstr "" msgid "Uses default currency" msgstr "" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2243,7 +2283,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2251,7 +2291,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "" @@ -2267,7 +2307,7 @@ msgstr "Parçaları Sil" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "" @@ -2294,7 +2334,7 @@ msgstr "Tedarikçi Stoku" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "" @@ -2372,8 +2412,8 @@ msgstr "Bu üretici parçası için tanımlanmış %(count)s tedarikçi bulunmak #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "" @@ -2385,7 +2425,7 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2418,16 +2458,16 @@ msgid "Delete" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "" @@ -2446,7 +2486,7 @@ msgstr "" msgid "Supplied Parts" msgstr "" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2463,7 +2503,7 @@ msgstr "Stok Kalemleri" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2475,7 +2515,7 @@ msgstr "Satış Emirleri" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2508,7 +2548,7 @@ msgid "New Sales Order" msgstr "Yeni Satış Emri" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "Tedarikçi Parçası" @@ -2558,7 +2598,7 @@ msgid "Pricing Information" msgstr "" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "" @@ -2577,8 +2617,8 @@ msgstr "" msgid "Delete price break" msgstr "" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "" @@ -2600,20 +2640,20 @@ msgstr "" msgid "New Company" msgstr "" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "Sağlanan URL geçerli bir resim dosyası değil" @@ -2681,15 +2721,15 @@ msgstr "" msgid "Delete Supplier Part" msgstr "" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "" @@ -2754,178 +2794,178 @@ msgstr "" msgid "Filters" msgstr "" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "Parçaları bu konuma alın" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "" -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "" -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "Stok kalemi seri numaları girin" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2933,77 +2973,77 @@ msgstr "" msgid "Purchase Order" msgstr "" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Tahsis miktarı stok miktarını aşamaz" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "Seri numaralı stok kalemi için miktar bir olmalı" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "Stok tahsis miktarını girin" @@ -3053,7 +3093,7 @@ msgstr "" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3091,57 +3131,71 @@ msgstr "" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "Aşağıdaki gerekli sütunlar için eksik seçimler" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "" -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "Dosya Alanları" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "Tedarikçi Parçası Seçin" @@ -3150,6 +3204,8 @@ msgid "Upload File for Purchase Order" msgstr "Sipariş Emri için Dosya Yükle" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "" @@ -3239,8 +3295,8 @@ msgid "Purchase Order Items" msgstr "" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "" @@ -3288,9 +3344,9 @@ msgstr "" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3356,18 +3412,18 @@ msgstr "" msgid "Sales Order Items" msgstr "" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "İşlemler" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "Stok tahsisini düzenle" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "Stok tahsisini sil" @@ -3379,8 +3435,8 @@ msgstr "" msgid "ID" msgstr "" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "" @@ -3396,7 +3452,7 @@ msgstr "" msgid "Allocate serial numbers" msgstr "Seri numaralarını tahsis et" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "" @@ -3404,8 +3460,8 @@ msgstr "" msgid "Purchase stock" msgstr "" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "" @@ -3459,195 +3515,195 @@ msgstr "Bu işlem Sipariş Emrinden belirtilen stok kalemleri tahsis edemedi" msgid "Sales Order Attachments" msgstr "" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "Seri Numaralarını Tahsis Et" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "{serial} seri numarası için eşleşen öge bulunamadı" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "{serial} stokta yok" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "{serial} zaten bir emirde tahsis edilmiş" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "Tahsis Miktarını Düzenle" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "Tahsisi Sil" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "Varsayılan Konum" @@ -3825,8 +3881,8 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "Parça Kategorileri" @@ -3876,7 +3932,7 @@ msgstr "Çeşidi" msgid "Part description" msgstr "" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "" @@ -4101,7 +4157,7 @@ msgstr "" msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "" @@ -4133,7 +4189,7 @@ msgstr "" msgid "BOM line checksum" msgstr "" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "" @@ -4142,7 +4198,7 @@ msgstr "" 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:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "Çeşide İzin Ver" @@ -4150,8 +4206,8 @@ msgstr "Çeşide İzin Ver" 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:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "" @@ -4199,8 +4255,8 @@ msgstr "" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "" @@ -4247,7 +4303,7 @@ msgstr "" msgid "Validate Bill of Materials" msgstr "" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "" @@ -4263,7 +4319,7 @@ msgstr "" msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "" @@ -4300,7 +4356,7 @@ msgid "Select Part" msgstr "" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "" @@ -4341,87 +4397,87 @@ msgstr "" msgid "Start New Build" msgstr "" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "Kategori Detayları" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "Alt kategoriler" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "Parçalar (Alt kategoriler dahil)" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "Kategori ayarla" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "Kategori Ayarla" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "Yeni konum oluştur" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "Yeni Stok konumu oluştur" @@ -4460,12 +4516,17 @@ msgstr "" msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "" @@ -4489,7 +4550,7 @@ msgstr "" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "" @@ -4569,12 +4630,21 @@ msgstr "" msgid "Part is not active" msgstr "" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4612,78 +4682,78 @@ msgstr "" msgid "Create new manufacturer" msgstr "" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "Parça Çeşitleri" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "Çeşitler" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "Tahsisler" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "Parça Test Şablonları" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4691,10 +4761,10 @@ msgstr "" msgid "Unit Cost" msgstr "" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4702,51 +4772,51 @@ msgstr "" msgid "Total Cost" msgstr "" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "" -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "" @@ -4847,7 +4917,7 @@ msgstr "Satış Emirleri için Gerekli" msgid "Allocated to Orders" msgstr "" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "" @@ -4965,220 +5035,224 @@ msgstr "Yeni Çeşit" msgid "Unknown database" msgstr "" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "Test Şablonu Oluştur" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "Test Şablonu Düzenle" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "Test Şablonu Sil" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "Çeşit Oluştur" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "Parça Parametre Şablonu Oluştur" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "Parça Parametre Şablonu Düzenle" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "Parça Parametre Şablonu Sil" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "Kategori Parametre Şablonu Oluştur" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "Kategori Parametre Şablonu Düzenle" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "Kategori Parametre Şablonu Sil" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5284,12 +5358,12 @@ msgid "Test Results" msgstr "" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "" @@ -5316,7 +5390,7 @@ msgstr "{n} öge için stok güncellendi" msgid "Moved {n} parts to {loc}" msgstr "" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "" @@ -5406,187 +5480,187 @@ msgstr "Varsayılan Konum Ayarla" msgid "Set the destination as the default location for selected parts" msgstr "Hedefi seçili parçalar için varsayılan konum olarak ayarla" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "Bu seri numarasına sahip stok kalemi zaten var" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "Seri numarası olan ögenin miktarı bir olmalı" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Miktar birden büyük ise seri numarası ayarlanamaz" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "Üst Stok Kalemi" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "Bu stok kalemi için tedarikçi parçası seçin" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "Stok Konumu" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "Bu öge için seri numarası" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "Seri numaraları tam sayı listesi olmalı" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "Miktar seri numaları ile eşleşmiyor" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "Seri numaraları zaten mevcut: {exists}" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "Stok kalemi stokta olmadığı için taşınamaz" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "" @@ -5738,7 +5812,7 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "Konum ayarlanmadı" @@ -6135,7 +6209,7 @@ msgstr "" msgid "Serialize Stock" msgstr "Stoku Seri Numarala" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "" @@ -6284,12 +6358,12 @@ msgid "No category parameter templates found" msgstr "Kategori parametre şablonu bulunamadı" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "Şablonu Düzenle" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "Şablonu Sil" @@ -6297,23 +6371,23 @@ msgstr "Şablonu Sil" msgid "Currency Settings" msgstr "" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "" @@ -6337,11 +6411,19 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "Parça Parametre Şablonu" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "Parça parametre şablonu bulunamadı" @@ -6626,7 +6708,7 @@ msgstr "Konuma Kaydet" msgid "Barcode does not match a valid location" msgstr "Barkod geçerli bir konumla eşleşmiyor" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "" @@ -6638,31 +6720,35 @@ msgstr "" msgid "Purchase Price Average" msgstr "" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "" @@ -6690,37 +6776,37 @@ msgstr "" msgid "Location not specified" msgstr "" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "Gerekli Parça" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "" diff --git a/InvenTree/locale/zh/LC_MESSAGES/django.po b/InvenTree/locale/zh/LC_MESSAGES/django.po index 34dbe857dc..006635f31e 100644 --- a/InvenTree/locale/zh/LC_MESSAGES/django.po +++ b/InvenTree/locale/zh/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-24 21:38+0000\n" -"PO-Revision-Date: 2021-06-24 21:40\n" +"POT-Creation-Date: 2021-07-01 22:35+0000\n" +"PO-Revision-Date: 2021-07-01 22:38\n" "Last-Translator: \n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" @@ -29,14 +29,14 @@ msgstr "未指定操作" msgid "No matching action found" msgstr "未找到指定操作" -#: InvenTree/fields.py:44 +#: InvenTree/fields.py:84 msgid "Enter date" msgstr "输入日期" #: InvenTree/forms.py:112 build/forms.py:102 build/forms.py:123 #: build/forms.py:145 build/forms.py:169 build/forms.py:185 build/forms.py:227 -#: order/forms.py:27 order/forms.py:38 order/forms.py:49 order/forms.py:60 -#: order/forms.py:71 part/forms.py:134 +#: order/forms.py:31 order/forms.py:42 order/forms.py:53 order/forms.py:64 +#: order/forms.py:75 part/forms.py:134 msgid "Confirm" msgstr "确认" @@ -72,41 +72,41 @@ msgstr "应用主题" msgid "Select Category" msgstr "选择分类" -#: InvenTree/helpers.py:377 +#: InvenTree/helpers.py:396 #, python-brace-format msgid "Duplicate serial: {n}" msgstr "" -#: InvenTree/helpers.py:384 order/models.py:248 order/models.py:358 +#: InvenTree/helpers.py:403 order/models.py:244 order/models.py:354 #: stock/views.py:1795 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/helpers.py:387 +#: InvenTree/helpers.py:406 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:409 InvenTree/helpers.py:412 InvenTree/helpers.py:415 -#: InvenTree/helpers.py:440 +#: InvenTree/helpers.py:428 InvenTree/helpers.py:431 InvenTree/helpers.py:434 +#: InvenTree/helpers.py:459 #, python-brace-format msgid "Invalid group: {g}" msgstr "" -#: InvenTree/helpers.py:445 +#: InvenTree/helpers.py:464 #, python-brace-format msgid "Duplicate serial: {g}" msgstr "" -#: InvenTree/helpers.py:453 +#: InvenTree/helpers.py:472 msgid "No serial numbers found" msgstr "未找到序列号" -#: InvenTree/helpers.py:457 +#: InvenTree/helpers.py:476 #, python-brace-format msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" -#: InvenTree/models.py:59 stock/models.py:1763 +#: InvenTree/models.py:59 stock/models.py:1758 msgid "Attachment" msgstr "附件" @@ -147,7 +147,7 @@ msgstr "名称" #: company/templates/company/manufacturer_part_base.html:72 #: company/templates/company/supplier_part_base.html:71 #: company/templates/company/supplier_part_detail.html:31 label/models.py:109 -#: order/models.py:104 order/templates/order/purchase_order_detail.html:147 +#: order/models.py:100 order/templates/order/purchase_order_detail.html:147 #: part/models.py:695 part/templates/part/detail.html:54 #: part/templates/part/set_category.html:14 report/models.py:193 #: report/models.py:530 report/models.py:569 @@ -155,7 +155,7 @@ msgstr "名称" #: templates/InvenTree/search.html:144 templates/InvenTree/search.html:224 #: templates/InvenTree/search.html:296 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:190 -#: templates/js/build.js:833 templates/js/build.js:1101 +#: templates/js/build.js:834 templates/js/build.js:1102 #: templates/js/company.js:56 templates/js/order.js:183 #: templates/js/order.js:280 templates/js/part.js:177 templates/js/part.js:260 #: templates/js/part.js:437 templates/js/part.js:654 templates/js/part.js:722 @@ -172,23 +172,23 @@ msgstr "" msgid "parent" msgstr "" -#: InvenTree/settings.py:503 +#: InvenTree/settings.py:504 msgid "English" msgstr "" -#: InvenTree/settings.py:504 +#: InvenTree/settings.py:505 msgid "French" msgstr "" -#: InvenTree/settings.py:505 +#: InvenTree/settings.py:506 msgid "German" msgstr "" -#: InvenTree/settings.py:506 +#: InvenTree/settings.py:507 msgid "Polish" msgstr "" -#: InvenTree/settings.py:507 +#: InvenTree/settings.py:508 msgid "Turkish" msgstr "" @@ -446,11 +446,11 @@ msgid "Order target date" msgstr "" #: build/forms.py:42 build/templates/build/build_base.html:146 -#: build/templates/build/detail.html:121 order/forms.py:114 order/forms.py:149 +#: build/templates/build/detail.html:121 order/forms.py:118 order/forms.py:153 #: order/templates/order/order_base.html:124 #: order/templates/order/sales_order_base.html:119 #: report/templates/report/inventree_build_order_base.html:126 -#: templates/js/build.js:880 templates/js/order.js:200 +#: templates/js/build.js:881 templates/js/order.js:200 #: templates/js/order.js:298 msgid "Target Date" msgstr "" @@ -463,11 +463,11 @@ msgstr "" #: build/templates/build/allocation_card.html:23 #: build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:133 -#: build/templates/build/detail.html:31 common/models.py:720 -#: company/forms.py:191 company/templates/company/supplier_part_pricing.html:77 -#: order/forms.py:193 order/forms.py:211 order/forms.py:246 order/forms.py:268 -#: order/forms.py:285 order/models.py:617 order/models.py:841 -#: order/templates/order/order_wizard/match_parts.html:29 +#: build/templates/build/detail.html:31 common/models.py:741 +#: company/forms.py:189 company/templates/company/supplier_part_pricing.html:77 +#: order/forms.py:197 order/forms.py:215 order/forms.py:250 order/forms.py:272 +#: order/forms.py:289 order/models.py:613 order/models.py:835 +#: order/templates/order/order_wizard/match_parts.html:30 #: order/templates/order/order_wizard/select_parts.html:34 #: order/templates/order/purchase_order_detail.html:179 #: order/templates/order/sales_order_detail.html:70 @@ -476,7 +476,7 @@ msgstr "" #: order/templates/order/sales_order_detail.html:234 part/forms.py:342 #: part/forms.py:372 part/forms.py:388 part/forms.py:404 part/models.py:2293 #: part/templates/part/internal_prices.html:98 -#: part/templates/part/order_prices.html:202 +#: part/templates/part/order_prices.html:203 #: part/templates/part/part_pricing.html:16 #: part/templates/part/sale_prices.html:85 #: report/templates/report/inventree_build_order_base.html:114 @@ -486,8 +486,8 @@ msgstr "" #: stock/forms.py:175 stock/forms.py:308 #: stock/templates/stock/item_base.html:255 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:364 -#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:571 -#: templates/js/build.js:1111 templates/js/order.js:393 +#: templates/js/bom.js:205 templates/js/build.js:233 templates/js/build.js:572 +#: templates/js/build.js:1112 templates/js/order.js:393 #: templates/js/part.js:796 templates/js/stock.js:1164 #: templates/js/stock.js:1383 msgid "Quantity" @@ -501,7 +501,7 @@ msgstr "" msgid "Enter quantity for build output" msgstr "" -#: build/forms.py:95 order/forms.py:240 stock/forms.py:118 +#: build/forms.py:95 order/forms.py:244 stock/forms.py:118 msgid "Serial Numbers" msgstr "" @@ -534,7 +534,7 @@ msgstr "" #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:260 templates/js/barcode.js:363 #: templates/js/barcode.js:531 templates/js/build.js:218 -#: templates/js/build.js:585 templates/js/order.js:378 +#: templates/js/build.js:586 templates/js/order.js:378 #: templates/js/stock.js:643 templates/js/stock.js:1056 msgid "Location" msgstr "" @@ -544,10 +544,10 @@ msgid "Location of completed parts" msgstr "" #: build/forms.py:215 build/templates/build/build_base.html:138 -#: build/templates/build/detail.html:59 order/models.py:469 +#: build/templates/build/detail.html:59 order/models.py:465 #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:408 templates/InvenTree/search.html:252 -#: templates/js/barcode.js:119 templates/js/build.js:867 +#: templates/js/barcode.js:119 templates/js/build.js:868 #: templates/js/order.js:187 templates/js/order.js:285 #: templates/js/stock.js:630 templates/js/stock.js:1133 #: templates/js/stock.js:1399 @@ -592,8 +592,8 @@ msgstr "" #: build/models.py:67 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:12 #: order/templates/order/so_navbar.html:19 -#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:57 -#: part/templates/part/navbar.html:60 templates/InvenTree/index.html:183 +#: order/templates/order/so_navbar.html:22 part/templates/part/navbar.html:58 +#: part/templates/part/navbar.html:61 templates/InvenTree/index.html:183 #: templates/InvenTree/search.html:185 #: templates/InvenTree/settings/tabs.html:34 users/models.py:43 msgid "Build Orders" @@ -603,12 +603,12 @@ msgstr "" msgid "Build Order Reference" msgstr "" -#: build/models.py:128 order/models.py:102 order/models.py:619 +#: build/models.py:128 order/models.py:98 order/models.py:615 #: order/templates/order/purchase_order_detail.html:174 #: order/templates/order/sales_order_detail.html:229 part/models.py:2302 #: report/templates/report/inventree_po_report.html:92 #: report/templates/report/inventree_so_report.html:92 templates/js/bom.js:197 -#: templates/js/build.js:660 templates/js/build.js:1105 +#: templates/js/build.js:661 templates/js/build.js:1106 msgid "Reference" msgstr "" @@ -628,7 +628,7 @@ msgstr "" #: build/models.py:153 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:128 #: build/templates/build/detail.html:26 company/models.py:663 -#: order/models.py:661 order/models.py:717 +#: order/models.py:657 order/models.py:712 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:132 #: order/templates/order/receive_parts.html:19 @@ -643,8 +643,8 @@ msgstr "" #: report/templates/report/inventree_so_report.html:90 #: templates/InvenTree/search.html:112 templates/InvenTree/search.html:210 #: templates/js/barcode.js:362 templates/js/bom.js:163 -#: templates/js/build.js:551 templates/js/build.js:838 -#: templates/js/build.js:1078 templates/js/company.js:140 +#: templates/js/build.js:552 templates/js/build.js:839 +#: templates/js/build.js:1079 templates/js/company.js:140 #: templates/js/company.js:339 templates/js/part.js:241 #: templates/js/part.js:404 templates/js/stock.js:526 #: templates/js/stock.js:1371 @@ -703,7 +703,7 @@ msgstr "" msgid "Build status code" msgstr "" -#: build/models.py:213 stock/models.py:466 +#: build/models.py:213 stock/models.py:462 msgid "Batch Code" msgstr "" @@ -711,16 +711,16 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:220 order/models.py:108 part/models.py:867 +#: build/models.py:220 order/models.py:104 part/models.py:867 #: part/templates/part/detail.html:126 templates/js/order.js:293 msgid "Creation Date" msgstr "" -#: build/models.py:224 order/models.py:475 +#: build/models.py:224 order/models.py:471 msgid "Target completion date" msgstr "" -#: build/models.py:228 order/models.py:221 templates/js/build.js:885 +#: build/models.py:228 order/models.py:217 templates/js/build.js:886 msgid "Completion Date" msgstr "" @@ -737,7 +737,7 @@ msgid "User who issued this build order" msgstr "" #: build/models.py:251 build/templates/build/build_base.html:184 -#: build/templates/build/detail.html:105 order/models.py:122 +#: build/templates/build/detail.html:105 order/models.py:118 #: order/templates/order/order_base.html:138 #: order/templates/order/sales_order_base.html:140 part/models.py:871 #: report/templates/report/inventree_build_order_base.html:159 @@ -754,30 +754,30 @@ msgstr "" #: company/templates/company/supplier_part_base.html:78 #: company/templates/company/supplier_part_detail.html:28 #: part/templates/part/detail.html:83 part/templates/part/part_base.html:94 -#: stock/models.py:460 stock/templates/stock/item_base.html:345 +#: stock/models.py:456 stock/templates/stock/item_base.html:345 msgid "External Link" msgstr "" -#: build/models.py:258 part/models.py:729 stock/models.py:462 +#: build/models.py:258 part/models.py:729 stock/models.py:458 msgid "Link to external URL" msgstr "" #: build/models.py:262 build/templates/build/navbar.html:53 #: company/models.py:132 company/models.py:539 #: company/templates/company/navbar.html:70 -#: company/templates/company/navbar.html:73 order/models.py:126 -#: order/models.py:621 order/templates/order/po_navbar.html:38 +#: company/templates/company/navbar.html:73 order/models.py:122 +#: order/models.py:617 order/templates/order/po_navbar.html:38 #: order/templates/order/po_navbar.html:41 #: order/templates/order/purchase_order_detail.html:243 #: order/templates/order/sales_order_detail.html:309 #: order/templates/order/so_navbar.html:33 #: order/templates/order/so_navbar.html:36 part/models.py:856 -#: part/templates/part/navbar.html:142 +#: part/templates/part/navbar.html:145 #: report/templates/report/inventree_build_order_base.html:173 #: stock/forms.py:173 stock/forms.py:317 stock/forms.py:349 stock/forms.py:377 -#: stock/models.py:532 stock/models.py:1667 stock/models.py:1769 +#: stock/models.py:528 stock/models.py:1662 stock/models.py:1764 #: stock/templates/stock/navbar.html:57 templates/js/barcode.js:37 -#: templates/js/bom.js:356 templates/js/stock.js:141 templates/js/stock.js:699 +#: templates/js/bom.js:349 templates/js/stock.js:141 templates/js/stock.js:699 msgid "Notes" msgstr "" @@ -810,11 +810,11 @@ msgstr "" msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:1188 order/models.py:815 +#: build/models.py:1188 order/models.py:809 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:1192 order/models.py:818 +#: build/models.py:1192 order/models.py:812 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -828,7 +828,7 @@ msgid "Selected stock item not found in BOM for part '{p}'" msgstr "" #: build/models.py:1316 stock/templates/stock/item_base.html:317 -#: templates/InvenTree/search.html:183 templates/js/build.js:811 +#: templates/InvenTree/search.html:183 templates/js/build.js:812 #: templates/navbar.html:29 msgid "Build" msgstr "" @@ -841,7 +841,7 @@ msgstr "" #: stock/templates/stock/item_base.html:31 #: stock/templates/stock/item_base.html:339 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:206 -#: templates/js/build.js:211 templates/js/build.js:928 +#: templates/js/build.js:211 templates/js/build.js:929 #: templates/js/order.js:366 templates/js/order.js:371 #: templates/js/stock.js:1115 msgid "Stock Item" @@ -879,7 +879,7 @@ msgstr "" msgid "Auto Allocate" msgstr "" -#: build/templates/build/allocate.html:25 templates/js/build.js:743 +#: build/templates/build/allocate.html:25 templates/js/build.js:744 msgid "Unallocate stock" msgstr "" @@ -893,8 +893,8 @@ msgstr "" #: build/templates/build/allocate.html:30 #: company/templates/company/detail_manufacturer_part.html:33 -#: company/templates/company/detail_supplier_part.html:32 order/views.py:986 -#: part/templates/part/category.html:127 +#: company/templates/company/detail_supplier_part.html:32 order/views.py:992 +#: part/templates/part/category.html:136 msgid "Order Parts" msgstr "" @@ -915,16 +915,16 @@ msgstr "" #: order/templates/order/sales_order_detail.html:75 #: order/templates/order/sales_order_detail.html:160 #: report/templates/report/inventree_test_report_base.html:75 -#: stock/models.py:454 stock/templates/stock/item_base.html:249 -#: templates/js/build.js:569 +#: stock/models.py:450 stock/templates/stock/item_base.html:249 +#: templates/js/build.js:570 msgid "Serial Number" msgstr "" #: build/templates/build/attachments.html:12 #: build/templates/build/navbar.html:43 build/templates/build/navbar.html:46 #: order/templates/order/po_navbar.html:35 -#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:133 -#: part/templates/part/navbar.html:136 stock/templates/stock/navbar.html:47 +#: order/templates/order/so_navbar.html:29 part/templates/part/navbar.html:136 +#: part/templates/part/navbar.html:139 stock/templates/stock/navbar.html:47 #: stock/templates/stock/navbar.html:50 msgid "Attachments" msgstr "" @@ -977,7 +977,7 @@ msgstr "" #: company/templates/company/supplier_part_base.html:26 #: order/templates/order/order_base.html:26 #: order/templates/order/sales_order_base.html:37 -#: part/templates/part/category.html:18 part/templates/part/part_base.html:22 +#: part/templates/part/category.html:27 part/templates/part/part_base.html:22 #: stock/templates/stock/item_base.html:62 #: stock/templates/stock/location.html:31 msgid "Admin view" @@ -1036,7 +1036,7 @@ msgid "Progress" msgstr "" #: build/templates/build/build_base.html:170 -#: build/templates/build/detail.html:84 order/models.py:715 +#: build/templates/build/detail.html:84 order/models.py:710 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:35 #: order/templates/order/sales_order_ship.html:25 @@ -1183,7 +1183,7 @@ msgstr "" msgid "Stock can be taken from any available location." msgstr "" -#: build/templates/build/detail.html:46 order/forms.py:85 order/models.py:678 +#: build/templates/build/detail.html:46 order/forms.py:89 order/models.py:673 #: order/templates/order/purchase_order_detail.html:239 #: order/templates/order/receive_parts.html:25 stock/forms.py:169 #: stock/forms.py:375 @@ -1203,7 +1203,7 @@ msgstr "" #: build/templates/build/detail.html:116 #: order/templates/order/order_base.html:111 -#: order/templates/order/sales_order_base.html:113 templates/js/build.js:875 +#: order/templates/order/sales_order_base.html:113 templates/js/build.js:876 msgid "Created" msgstr "" @@ -1211,7 +1211,7 @@ msgstr "" msgid "No target date set" msgstr "" -#: build/templates/build/detail.html:132 templates/js/build.js:853 +#: build/templates/build/detail.html:132 templates/js/build.js:854 msgid "Completed" msgstr "" @@ -1250,7 +1250,7 @@ msgstr "" #: build/templates/build/navbar.html:15 #: company/templates/company/navbar.html:15 #: order/templates/order/po_navbar.html:15 -#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:17 +#: order/templates/order/so_navbar.html:15 part/templates/part/navbar.html:18 #: templates/js/stock.js:1044 msgid "Details" msgstr "" @@ -1412,8 +1412,8 @@ msgstr "" msgid "Stock item is over-allocated" msgstr "" -#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:670 -#: templates/js/build.js:935 templates/js/build.js:1118 +#: build/views.py:872 templates/js/bom.js:230 templates/js/build.js:671 +#: templates/js/build.js:936 templates/js/build.js:1119 msgid "Available" msgstr "" @@ -1433,56 +1433,56 @@ msgstr "" msgid "Add Build Order Attachment" msgstr "" -#: build/views.py:1083 order/views.py:115 order/views.py:167 part/views.py:173 +#: build/views.py:1083 order/views.py:117 order/views.py:169 part/views.py:178 #: stock/views.py:277 msgid "Added attachment" msgstr "" -#: build/views.py:1119 order/views.py:194 order/views.py:215 +#: build/views.py:1119 order/views.py:196 order/views.py:217 msgid "Edit Attachment" msgstr "" -#: build/views.py:1129 order/views.py:198 order/views.py:219 +#: build/views.py:1129 order/views.py:200 order/views.py:221 msgid "Attachment updated" msgstr "" -#: build/views.py:1139 order/views.py:234 order/views.py:248 +#: build/views.py:1139 order/views.py:236 order/views.py:250 msgid "Delete Attachment" msgstr "" -#: build/views.py:1144 order/views.py:240 order/views.py:254 stock/views.py:333 +#: build/views.py:1144 order/views.py:242 order/views.py:256 stock/views.py:333 msgid "Deleted attachment" msgstr "" -#: common/files.py:64 +#: common/files.py:66 msgid "Unsupported file format: {ext.upper()}" msgstr "" -#: common/files.py:69 +#: common/files.py:71 msgid "Error reading file (invalid format)" msgstr "" -#: common/files.py:71 +#: common/files.py:73 msgid "Error reading file (incorrect dimension)" msgstr "" -#: common/files.py:73 +#: common/files.py:75 msgid "Error reading file (data could be corrupted)" msgstr "" -#: common/forms.py:39 templates/attachment_table.html:15 +#: common/forms.py:34 templates/attachment_table.html:15 msgid "File" msgstr "" -#: common/forms.py:40 +#: common/forms.py:35 msgid "Select file to upload" msgstr "" -#: common/forms.py:55 +#: common/forms.py:50 msgid "{name.title()} File" msgstr "" -#: common/forms.py:56 +#: common/forms.py:51 #, python-brace-format msgid "Select {name} file to upload" msgstr "" @@ -1520,335 +1520,359 @@ msgid "Base URL for server instance" msgstr "" #: common/models.py:85 -msgid "Download from URL" +msgid "Default Currency" msgstr "" #: common/models.py:86 -msgid "Allow download of remote images and files from external URL" +msgid "Default currency" msgstr "" #: common/models.py:92 -msgid "Barcode Support" +msgid "Download from URL" msgstr "" #: common/models.py:93 -msgid "Enable barcode scanner support" +msgid "Allow download of remote images and files from external URL" msgstr "" #: common/models.py:99 -msgid "IPN Regex" +msgid "Barcode Support" msgstr "" #: common/models.py:100 +msgid "Enable barcode scanner support" +msgstr "" + +#: common/models.py:106 +msgid "IPN Regex" +msgstr "" + +#: common/models.py:107 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/models.py:104 +#: common/models.py:111 msgid "Allow Duplicate IPN" msgstr "" -#: common/models.py:105 +#: common/models.py:112 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/models.py:111 +#: common/models.py:118 msgid "Allow Editing IPN" msgstr "" -#: common/models.py:112 +#: common/models.py:119 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/models.py:118 +#: common/models.py:125 msgid "Copy Part BOM Data" msgstr "" -#: common/models.py:119 +#: common/models.py:126 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/models.py:125 +#: common/models.py:132 msgid "Copy Part Parameter Data" msgstr "" -#: common/models.py:126 +#: common/models.py:133 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/models.py:132 +#: common/models.py:139 msgid "Copy Part Test Data" msgstr "" -#: common/models.py:133 +#: common/models.py:140 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/models.py:139 +#: common/models.py:146 msgid "Copy Category Parameter Templates" msgstr "" -#: common/models.py:140 +#: common/models.py:147 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/models.py:146 +#: common/models.py:153 msgid "Recent Part Count" msgstr "" -#: common/models.py:147 +#: common/models.py:154 msgid "Number of recent parts to display on index page" msgstr "" -#: common/models.py:153 part/models.py:2193 part/templates/part/detail.html:160 +#: common/models.py:160 part/models.py:2193 part/templates/part/detail.html:160 #: report/models.py:186 stock/forms.py:259 templates/js/table_filters.js:25 #: templates/js/table_filters.js:315 msgid "Template" msgstr "" -#: common/models.py:154 +#: common/models.py:161 msgid "Parts are templates by default" msgstr "" -#: common/models.py:160 part/models.py:819 part/templates/part/detail.html:170 +#: common/models.py:167 part/models.py:819 part/templates/part/detail.html:170 #: templates/js/table_filters.js:128 templates/js/table_filters.js:327 msgid "Assembly" msgstr "" -#: common/models.py:161 +#: common/models.py:168 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/models.py:167 part/models.py:825 part/templates/part/detail.html:180 +#: common/models.py:174 part/models.py:825 part/templates/part/detail.html:180 #: templates/js/table_filters.js:331 msgid "Component" msgstr "" -#: common/models.py:168 +#: common/models.py:175 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/models.py:174 part/models.py:836 part/templates/part/detail.html:200 +#: common/models.py:181 part/models.py:836 part/templates/part/detail.html:200 msgid "Purchaseable" msgstr "" -#: common/models.py:175 +#: common/models.py:182 msgid "Parts are purchaseable by default" msgstr "" -#: common/models.py:181 part/models.py:841 part/templates/part/detail.html:210 +#: common/models.py:188 part/models.py:841 part/templates/part/detail.html:210 #: templates/js/table_filters.js:339 msgid "Salable" msgstr "" -#: common/models.py:182 +#: common/models.py:189 msgid "Parts are salable by default" msgstr "" -#: common/models.py:188 part/models.py:831 part/templates/part/detail.html:190 +#: common/models.py:195 part/models.py:831 part/templates/part/detail.html:190 #: templates/js/table_filters.js:33 templates/js/table_filters.js:343 msgid "Trackable" msgstr "" -#: common/models.py:189 +#: common/models.py:196 msgid "Parts are trackable by default" msgstr "" -#: common/models.py:195 part/models.py:851 part/templates/part/detail.html:150 +#: common/models.py:202 part/models.py:851 part/templates/part/detail.html:150 #: templates/js/table_filters.js:29 msgid "Virtual" msgstr "" -#: common/models.py:196 +#: common/models.py:203 msgid "Parts are virtual by default" msgstr "" -#: common/models.py:202 +#: common/models.py:209 msgid "Show Quantity in Forms" msgstr "" -#: common/models.py:203 +#: common/models.py:210 msgid "Display available part quantity in some forms" msgstr "" -#: common/models.py:209 -msgid "Show Price in Forms" -msgstr "" - -#: common/models.py:210 -msgid "Display part price in some forms" -msgstr "" - #: common/models.py:216 -msgid "Internal Prices" +msgid "Show Import in Views" msgstr "" #: common/models.py:217 -msgid "Enable internal prices for parts" +msgid "Display the import wizard in some part views" msgstr "" #: common/models.py:223 -msgid "Internal Price as BOM-Price" +msgid "Show Price in Forms" msgstr "" #: common/models.py:224 -msgid "Use the internal price (if set) in BOM-price calculations" +msgid "Display part price in some forms" msgstr "" -#: common/models.py:230 templates/stats.html:25 -msgid "Debug Mode" +#: common/models.py:230 +msgid "Show related parts" msgstr "" #: common/models.py:231 -msgid "Generate reports in debug mode (HTML output)" +msgid "Display related parts for a part" msgstr "" #: common/models.py:237 -msgid "Page Size" +msgid "Internal Prices" msgstr "" #: common/models.py:238 +msgid "Enable internal prices for parts" +msgstr "" + +#: common/models.py:244 +msgid "Internal Price as BOM-Price" +msgstr "" + +#: common/models.py:245 +msgid "Use the internal price (if set) in BOM-price calculations" +msgstr "" + +#: common/models.py:251 templates/stats.html:25 +msgid "Debug Mode" +msgstr "" + +#: common/models.py:252 +msgid "Generate reports in debug mode (HTML output)" +msgstr "" + +#: common/models.py:258 +msgid "Page Size" +msgstr "" + +#: common/models.py:259 msgid "Default page size for PDF reports" msgstr "" -#: common/models.py:248 +#: common/models.py:269 msgid "Test Reports" msgstr "" -#: common/models.py:249 +#: common/models.py:270 msgid "Enable generation of test reports" msgstr "" -#: common/models.py:255 +#: common/models.py:276 msgid "Stock Expiry" msgstr "" -#: common/models.py:256 +#: common/models.py:277 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:262 +#: common/models.py:283 msgid "Sell Expired Stock" msgstr "" -#: common/models.py:263 +#: common/models.py:284 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:269 +#: common/models.py:290 msgid "Stock Stale Time" msgstr "" -#: common/models.py:270 +#: common/models.py:291 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:272 part/templates/part/detail.html:121 +#: common/models.py:293 part/templates/part/detail.html:121 msgid "days" msgstr "" -#: common/models.py:277 +#: common/models.py:298 msgid "Build Expired Stock" msgstr "" -#: common/models.py:278 +#: common/models.py:299 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:284 +#: common/models.py:305 msgid "Stock Ownership Control" msgstr "" -#: common/models.py:285 +#: common/models.py:306 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/models.py:291 +#: common/models.py:312 msgid "Group by Part" msgstr "" -#: common/models.py:292 +#: common/models.py:313 msgid "Group stock items by part reference in table views" msgstr "" -#: common/models.py:298 +#: common/models.py:319 msgid "Recent Stock Count" msgstr "" -#: common/models.py:299 +#: common/models.py:320 msgid "Number of recent stock items to display on index page" msgstr "" -#: common/models.py:305 +#: common/models.py:326 msgid "Build Order Reference Prefix" msgstr "" -#: common/models.py:306 +#: common/models.py:327 msgid "Prefix value for build order reference" msgstr "" -#: common/models.py:311 +#: common/models.py:332 msgid "Build Order Reference Regex" msgstr "" -#: common/models.py:312 +#: common/models.py:333 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:316 +#: common/models.py:337 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:317 +#: common/models.py:338 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:322 +#: common/models.py:343 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:323 +#: common/models.py:344 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:546 +#: common/models.py:567 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:548 +#: common/models.py:569 msgid "Settings value" msgstr "" -#: common/models.py:583 +#: common/models.py:604 msgid "Must be an integer value" msgstr "" -#: common/models.py:606 +#: common/models.py:627 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:617 +#: common/models.py:638 msgid "Value must be an integer value" msgstr "" -#: common/models.py:640 +#: common/models.py:661 msgid "Key string must be unique" msgstr "" -#: common/models.py:721 company/forms.py:192 +#: common/models.py:742 company/forms.py:190 msgid "Price break quantity" msgstr "" -#: common/models.py:729 company/templates/company/supplier_part_pricing.html:82 +#: common/models.py:749 company/templates/company/supplier_part_pricing.html:82 #: part/templates/part/internal_prices.html:103 -#: part/templates/part/sale_prices.html:90 templates/js/bom.js:271 +#: part/templates/part/sale_prices.html:90 msgid "Price" msgstr "" -#: common/models.py:730 +#: common/models.py:750 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:822 +#: common/models.py:842 msgid "Default" msgstr "" @@ -1856,27 +1880,30 @@ msgstr "" msgid "Current value" msgstr "" -#: common/views.py:32 +#: common/views.py:33 msgid "Change Setting" msgstr "" -#: common/views.py:101 +#: common/views.py:102 msgid "Supplied value is not allowed" msgstr "" -#: common/views.py:110 +#: common/views.py:111 msgid "Supplied value must be a boolean" msgstr "" #: common/views.py:184 order/templates/order/order_wizard/po_upload.html:42 #: order/templates/order/po_navbar.html:19 -#: order/templates/order/po_navbar.html:22 order/views.py:582 +#: order/templates/order/po_navbar.html:22 order/views.py:605 #: part/templates/part/bom_upload/upload_file.html:27 +#: part/templates/part/import_wizard/part_upload.html:45 part/views.py:761 msgid "Upload File" msgstr "" #: common/views.py:185 order/templates/order/order_wizard/match_fields.html:52 -#: order/views.py:583 part/templates/part/bom_upload/select_fields.html:58 +#: order/views.py:606 part/templates/part/bom_upload/select_fields.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:45 +#: part/templates/part/import_wizard/match_fields.html:52 part/views.py:762 msgid "Match Fields" msgstr "" @@ -1884,44 +1911,57 @@ msgstr "" msgid "Match Items" msgstr "" -#: common/views.py:479 +#: common/views.py:531 msgid "Fields matching failed" msgstr "" -#: company/forms.py:38 company/models.py:142 +#: common/views.py:586 +msgid "Parts imported" +msgstr "" + +#: common/views.py:608 order/templates/order/order_wizard/match_fields.html:27 +#: order/templates/order/order_wizard/match_parts.html:19 +#: order/templates/order/order_wizard/po_upload.html:40 +#: part/templates/part/import_wizard/match_fields.html:27 +#: part/templates/part/import_wizard/match_references.html:19 +#: part/templates/part/import_wizard/part_upload.html:43 +msgid "Previous Step" +msgstr "" + +#: company/forms.py:37 company/models.py:142 #: company/templates/company/detail.html:42 msgid "Currency" msgstr "" -#: company/forms.py:39 company/models.py:144 +#: company/forms.py:38 company/models.py:144 msgid "Default currency used for this company" msgstr "" -#: company/forms.py:77 part/forms.py:46 +#: company/forms.py:76 part/forms.py:46 msgid "URL" msgstr "" -#: company/forms.py:78 part/forms.py:47 +#: company/forms.py:77 part/forms.py:47 msgid "Image URL" msgstr "" -#: company/forms.py:133 templates/js/part.js:787 +#: company/forms.py:132 templates/js/part.js:787 msgid "Single Price" msgstr "" -#: company/forms.py:135 +#: company/forms.py:133 msgid "Single quantity price" msgstr "" -#: company/forms.py:143 company/models.py:321 +#: company/forms.py:141 company/models.py:321 msgid "Select manufacturer" msgstr "" -#: company/forms.py:149 company/models.py:328 +#: company/forms.py:147 company/models.py:328 msgid "Manufacturer Part Number" msgstr "" -#: company/forms.py:151 company/models.py:327 +#: company/forms.py:149 company/models.py:327 #: company/templates/company/manufacturer_part_base.html:89 #: company/templates/company/manufacturer_part_detail.html:26 #: company/templates/company/supplier_part_base.html:102 @@ -1981,7 +2021,7 @@ msgid "Point of contact" msgstr "" #: company/models.py:121 company/models.py:333 company/models.py:526 -#: order/models.py:106 part/models.py:728 +#: order/models.py:102 part/models.py:728 #: report/templates/report/inventree_build_order_base.html:165 #: templates/js/company.js:188 templates/js/company.js:419 #: templates/js/part.js:498 @@ -2020,12 +2060,12 @@ msgstr "" msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:305 company/models.py:497 stock/models.py:407 +#: company/models.py:305 company/models.py:497 stock/models.py:403 #: stock/templates/stock/item_base.html:235 msgid "Base Part" msgstr "" -#: company/models.py:309 company/models.py:501 order/views.py:1597 +#: company/models.py:309 company/models.py:501 order/views.py:1603 msgid "Select part" msgstr "" @@ -2061,7 +2101,7 @@ msgstr "" #: company/models.py:403 part/templates/part/params.html:28 #: report/templates/report/inventree_test_report_base.html:90 -#: stock/models.py:1756 templates/InvenTree/settings/header.html:8 +#: stock/models.py:1751 templates/InvenTree/settings/header.html:8 #: templates/js/company.js:241 templates/js/stock.js:137 msgid "Value" msgstr "" @@ -2082,7 +2122,7 @@ msgstr "" #: company/models.py:507 company/templates/company/detail.html:62 #: company/templates/company/supplier_part_base.html:84 -#: company/templates/company/supplier_part_detail.html:25 order/models.py:193 +#: company/templates/company/supplier_part_detail.html:25 order/models.py:189 #: order/templates/order/order_base.html:92 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:175 #: part/bom.py:286 stock/templates/stock/item_base.html:369 @@ -2134,7 +2174,7 @@ msgid "Minimum charge (e.g. stocking fee)" msgstr "" #: company/models.py:544 company/templates/company/supplier_part_base.html:109 -#: stock/models.py:431 stock/templates/stock/item_base.html:310 +#: stock/models.py:427 stock/templates/stock/item_base.html:310 #: templates/js/stock.js:695 msgid "Packaging" msgstr "" @@ -2153,7 +2193,7 @@ msgstr "" #: company/templates/company/assigned_stock.html:10 #: company/templates/company/navbar.html:62 -#: company/templates/company/navbar.html:65 templates/js/build.js:562 +#: company/templates/company/navbar.html:65 templates/js/build.js:563 msgid "Assigned Stock" msgstr "" @@ -2173,7 +2213,7 @@ msgstr "" msgid "Download image from URL" msgstr "" -#: company/templates/company/company_base.html:46 order/views.py:311 +#: company/templates/company/company_base.html:46 order/views.py:313 msgid "Create Purchase Order" msgstr "" @@ -2218,9 +2258,9 @@ msgstr "" msgid "Uses default currency" msgstr "" -#: company/templates/company/detail.html:67 order/models.py:464 -#: order/templates/order/sales_order_base.html:94 stock/models.py:449 -#: stock/models.py:450 stock/templates/stock/item_base.html:262 +#: company/templates/company/detail.html:67 order/models.py:460 +#: order/templates/order/sales_order_base.html:94 stock/models.py:445 +#: stock/models.py:446 stock/templates/stock/item_base.html:262 #: templates/js/company.js:40 templates/js/order.js:267 #: templates/js/stock.js:1097 msgid "Customer" @@ -2243,7 +2283,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:28 #: company/templates/company/detail_supplier_part.html:27 #: company/templates/company/manufacturer_part_suppliers.html:20 -#: part/templates/part/category.html:122 +#: part/templates/part/category.html:131 #: part/templates/part/manufacturer.html:22 #: part/templates/part/supplier.html:20 msgid "Options" @@ -2251,7 +2291,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:33 #: company/templates/company/detail_supplier_part.html:32 -#: part/templates/part/category.html:127 +#: part/templates/part/category.html:136 msgid "Order parts" msgstr "" @@ -2267,7 +2307,7 @@ msgstr "" #: company/templates/company/detail_manufacturer_part.html:66 #: company/templates/company/detail_supplier_part.html:66 -#: part/templates/part/bom.html:159 part/templates/part/category.html:118 +#: part/templates/part/bom.html:159 part/templates/part/category.html:127 #: templates/js/stock.js:1312 msgid "New Part" msgstr "" @@ -2294,7 +2334,7 @@ msgstr "" #: company/templates/company/detail_stock.html:37 #: company/templates/company/supplier_part_stock.html:34 -#: part/templates/part/category.html:114 part/templates/part/category.html:128 +#: part/templates/part/category.html:123 part/templates/part/category.html:137 #: part/templates/part/stock.html:54 stock/templates/stock/location.html:163 msgid "Export" msgstr "" @@ -2372,8 +2412,8 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:14 #: company/templates/company/manufacturer_part_suppliers.html:10 -#: company/views.py:63 part/templates/part/navbar.html:86 -#: part/templates/part/navbar.html:89 templates/InvenTree/search.html:316 +#: company/views.py:63 part/templates/part/navbar.html:87 +#: part/templates/part/navbar.html:90 templates/InvenTree/search.html:316 #: templates/navbar.html:35 msgid "Suppliers" msgstr "" @@ -2385,7 +2425,7 @@ msgstr "" #: company/templates/company/manufacturer_part_navbar.html:22 #: company/templates/company/navbar.html:41 #: company/templates/company/supplier_part_navbar.html:15 -#: part/templates/part/navbar.html:38 stock/api.py:54 +#: part/templates/part/navbar.html:39 stock/api.py:54 #: stock/templates/stock/loc_link.html:7 stock/templates/stock/location.html:36 #: stock/templates/stock/stock_app_base.html:10 #: templates/InvenTree/index.html:128 templates/InvenTree/search.html:196 @@ -2418,16 +2458,16 @@ msgid "Delete" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:37 -#: part/templates/part/category_navbar.html:34 -#: part/templates/part/category_navbar.html:37 -#: part/templates/part/navbar.html:24 +#: part/templates/part/category_navbar.html:46 +#: part/templates/part/category_navbar.html:49 +#: part/templates/part/navbar.html:25 msgid "Parameters" msgstr "" #: company/templates/company/manufacturer_part_suppliers.html:43 #: part/templates/part/params.html:18 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:48 +#: templates/InvenTree/settings/part.html:65 msgid "New Parameter" msgstr "" @@ -2446,7 +2486,7 @@ msgstr "" msgid "Supplied Parts" msgstr "" -#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:35 +#: company/templates/company/navbar.html:38 part/templates/part/navbar.html:36 #: stock/templates/stock/location.html:107 #: stock/templates/stock/location.html:122 #: stock/templates/stock/location.html:136 @@ -2463,7 +2503,7 @@ msgstr "" #: company/templates/company/sales_orders.html:11 #: order/templates/order/sales_orders.html:8 #: order/templates/order/sales_orders.html:13 -#: part/templates/part/navbar.html:112 part/templates/part/navbar.html:115 +#: part/templates/part/navbar.html:113 part/templates/part/navbar.html:116 #: part/templates/part/sales_orders.html:10 templates/InvenTree/index.html:228 #: templates/InvenTree/search.html:345 #: templates/InvenTree/settings/tabs.html:40 templates/navbar.html:46 @@ -2475,7 +2515,7 @@ msgstr "" #: company/templates/company/purchase_orders.html:10 #: order/templates/order/purchase_orders.html:8 #: order/templates/order/purchase_orders.html:13 -#: part/templates/part/navbar.html:92 part/templates/part/navbar.html:95 +#: part/templates/part/navbar.html:93 part/templates/part/navbar.html:96 #: part/templates/part/orders.html:10 templates/InvenTree/index.html:205 #: templates/InvenTree/search.html:325 #: templates/InvenTree/settings/tabs.html:37 templates/navbar.html:37 @@ -2508,7 +2548,7 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:7 -#: company/templates/company/supplier_part_base.html:20 stock/models.py:416 +#: company/templates/company/supplier_part_base.html:20 stock/models.py:412 #: stock/templates/stock/item_base.html:374 templates/js/company.js:380 msgid "Supplier Part" msgstr "" @@ -2558,7 +2598,7 @@ msgid "Pricing Information" msgstr "" #: company/templates/company/supplier_part_pricing.html:19 company/views.py:855 -#: part/templates/part/sale_prices.html:17 part/views.py:2751 +#: part/templates/part/sale_prices.html:17 part/views.py:2918 msgid "Add Price Break" msgstr "" @@ -2577,8 +2617,8 @@ msgstr "" msgid "Delete price break" msgstr "" -#: company/views.py:70 part/templates/part/navbar.html:80 -#: part/templates/part/navbar.html:83 templates/InvenTree/search.html:306 +#: company/views.py:70 part/templates/part/navbar.html:81 +#: part/templates/part/navbar.html:84 templates/InvenTree/search.html:306 #: templates/navbar.html:36 msgid "Manufacturers" msgstr "" @@ -2600,20 +2640,20 @@ msgstr "" msgid "New Company" msgstr "" -#: company/views.py:169 part/views.py:948 +#: company/views.py:169 part/views.py:1115 msgid "Download Image" msgstr "" -#: company/views.py:198 part/views.py:980 +#: company/views.py:198 part/views.py:1147 msgid "Image size exceeds maximum allowable size for download" msgstr "" -#: company/views.py:205 part/views.py:987 +#: company/views.py:205 part/views.py:1154 #, python-brace-format msgid "Invalid response: {code}" msgstr "" -#: company/views.py:214 part/views.py:996 +#: company/views.py:214 part/views.py:1163 msgid "Supplied URL is not a valid image file" msgstr "" @@ -2681,15 +2721,15 @@ msgstr "" msgid "Delete Supplier Part" msgstr "" -#: company/views.py:860 part/views.py:2755 +#: company/views.py:860 part/views.py:2922 msgid "Added new price break" msgstr "" -#: company/views.py:916 part/views.py:2799 +#: company/views.py:916 part/views.py:2966 msgid "Edit Price Break" msgstr "" -#: company/views.py:931 part/views.py:2813 +#: company/views.py:931 part/views.py:2980 msgid "Delete Price Break" msgstr "" @@ -2754,178 +2794,178 @@ msgstr "" msgid "Filters" msgstr "" -#: order/forms.py:27 order/templates/order/order_base.html:47 +#: order/forms.py:31 order/templates/order/order_base.html:47 msgid "Place order" msgstr "" -#: order/forms.py:38 order/templates/order/order_base.html:54 +#: order/forms.py:42 order/templates/order/order_base.html:54 msgid "Mark order as complete" msgstr "" -#: order/forms.py:49 order/forms.py:60 order/templates/order/order_base.html:59 +#: order/forms.py:53 order/forms.py:64 order/templates/order/order_base.html:59 #: order/templates/order/sales_order_base.html:61 msgid "Cancel order" msgstr "" -#: order/forms.py:71 order/templates/order/sales_order_base.html:58 +#: order/forms.py:75 order/templates/order/sales_order_base.html:58 msgid "Ship order" msgstr "" -#: order/forms.py:86 +#: order/forms.py:90 msgid "Receive parts to this location" msgstr "" -#: order/forms.py:108 +#: order/forms.py:112 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:115 +#: order/forms.py:119 msgid "Target date for order delivery. Order will be overdue after this date." msgstr "" -#: order/forms.py:143 +#: order/forms.py:147 msgid "Enter sales order number" msgstr "" -#: order/forms.py:150 order/models.py:476 +#: order/forms.py:154 order/models.py:472 msgid "Target date for order completion. Order will be overdue after this date." msgstr "" -#: order/forms.py:242 +#: order/forms.py:246 msgid "Enter stock item serial numbers" msgstr "" -#: order/forms.py:248 +#: order/forms.py:252 msgid "Enter quantity of stock items" msgstr "" -#: order/models.py:102 +#: order/models.py:98 msgid "Order reference" msgstr "" -#: order/models.py:104 +#: order/models.py:100 msgid "Order description" msgstr "" -#: order/models.py:106 +#: order/models.py:102 msgid "Link to external page" msgstr "" -#: order/models.py:114 part/templates/part/detail.html:132 +#: order/models.py:110 part/templates/part/detail.html:132 msgid "Created By" msgstr "" -#: order/models.py:121 +#: order/models.py:117 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:126 +#: order/models.py:122 msgid "Order notes" msgstr "" -#: order/models.py:185 order/models.py:469 +#: order/models.py:181 order/models.py:465 msgid "Purchase order status" msgstr "" -#: order/models.py:194 +#: order/models.py:190 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:197 order/templates/order/order_base.html:98 +#: order/models.py:193 order/templates/order/order_base.html:98 #: templates/js/order.js:179 msgid "Supplier Reference" msgstr "" -#: order/models.py:197 +#: order/models.py:193 msgid "Supplier order reference code" msgstr "" -#: order/models.py:204 +#: order/models.py:200 msgid "received by" msgstr "" -#: order/models.py:209 +#: order/models.py:205 msgid "Issue Date" msgstr "" -#: order/models.py:210 +#: order/models.py:206 msgid "Date order was issued" msgstr "" -#: order/models.py:215 +#: order/models.py:211 msgid "Target Delivery Date" msgstr "" -#: order/models.py:216 +#: order/models.py:212 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:222 +#: order/models.py:218 msgid "Date order was completed" msgstr "" -#: order/models.py:246 part/views.py:1686 stock/models.py:304 -#: stock/models.py:1020 +#: order/models.py:242 part/views.py:1853 stock/models.py:300 +#: stock/models.py:1015 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:251 +#: order/models.py:247 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:349 +#: order/models.py:345 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:353 +#: order/models.py:349 msgid "Quantity must be an integer" msgstr "" -#: order/models.py:355 +#: order/models.py:351 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:465 +#: order/models.py:461 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer Reference " msgstr "" -#: order/models.py:471 +#: order/models.py:467 msgid "Customer order reference code" msgstr "" -#: order/models.py:479 templates/js/order.js:303 +#: order/models.py:475 templates/js/order.js:303 msgid "Shipment Date" msgstr "" -#: order/models.py:486 +#: order/models.py:482 msgid "shipped by" msgstr "" -#: order/models.py:530 +#: order/models.py:526 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:617 +#: order/models.py:613 msgid "Item quantity" msgstr "" -#: order/models.py:619 +#: order/models.py:615 msgid "Line item reference" msgstr "" -#: order/models.py:621 +#: order/models.py:617 msgid "Line item notes" msgstr "" -#: order/models.py:647 order/models.py:715 templates/js/order.js:353 +#: order/models.py:643 order/models.py:710 templates/js/order.js:353 msgid "Order" msgstr "" -#: order/models.py:648 order/templates/order/order_base.html:9 +#: order/models.py:644 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 #: report/templates/report/inventree_po_report.html:77 #: stock/templates/stock/item_base.html:324 templates/js/order.js:148 @@ -2933,77 +2973,77 @@ msgstr "" msgid "Purchase Order" msgstr "" -#: order/models.py:662 +#: order/models.py:658 msgid "Supplier part" msgstr "" -#: order/models.py:665 order/templates/order/order_base.html:131 +#: order/models.py:661 order/templates/order/order_base.html:131 #: order/templates/order/purchase_order_detail.html:219 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:133 msgid "Received" msgstr "" -#: order/models.py:665 +#: order/models.py:661 msgid "Number of items received" msgstr "" -#: order/models.py:672 stock/models.py:542 +#: order/models.py:667 stock/models.py:537 #: stock/templates/stock/item_base.html:331 templates/js/stock.js:690 msgid "Purchase Price" msgstr "" -#: order/models.py:673 +#: order/models.py:668 msgid "Unit purchase price" msgstr "" -#: order/models.py:681 +#: order/models.py:676 msgid "Where does the Purchaser want this item to be stored?" msgstr "" -#: order/models.py:724 part/templates/part/navbar.html:109 -#: part/templates/part/order_prices.html:107 +#: order/models.py:718 part/templates/part/navbar.html:110 +#: part/templates/part/order_prices.html:108 #: part/templates/part/part_pricing.html:97 msgid "Sale Price" msgstr "" -#: order/models.py:725 +#: order/models.py:719 msgid "Unit sale price" msgstr "" -#: order/models.py:800 order/models.py:802 +#: order/models.py:794 order/models.py:796 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:806 +#: order/models.py:800 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:808 +#: order/models.py:802 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:811 +#: order/models.py:805 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:821 +#: order/models.py:815 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:826 +#: order/models.py:820 msgid "Line" msgstr "" -#: order/models.py:837 +#: order/models.py:831 msgid "Item" msgstr "" -#: order/models.py:838 +#: order/models.py:832 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:841 +#: order/models.py:835 msgid "Enter stock allocation quantity" msgstr "" @@ -3053,7 +3093,7 @@ msgstr "" #: order/templates/order/order_base.html:180 #: order/templates/order/purchase_order_detail.html:100 -#: part/templates/part/category.html:208 part/templates/part/category.html:250 +#: part/templates/part/category.html:217 part/templates/part/category.html:259 #: stock/templates/stock/location.html:191 templates/js/stock.js:736 #: templates/js/stock.js:1324 msgid "New Location" @@ -3091,57 +3131,71 @@ msgstr "" #: order/templates/order/order_wizard/match_fields.html:9 #: part/templates/part/bom_upload/select_fields.html:21 +#: part/templates/part/import_wizard/ajax_match_fields.html:9 +#: part/templates/part/import_wizard/match_fields.html:9 msgid "Missing selections for the following required columns" msgstr "" #: order/templates/order/order_wizard/match_fields.html:20 +#: part/templates/part/import_wizard/ajax_match_fields.html:20 +#: part/templates/part/import_wizard/match_fields.html:20 msgid "Duplicate selections found, see below. Fix them then retry submitting." msgstr "" -#: order/templates/order/order_wizard/match_fields.html:27 -#: order/templates/order/order_wizard/match_parts.html:18 -#: order/templates/order/order_wizard/po_upload.html:40 -msgid "Previous Step" -msgstr "" - #: order/templates/order/order_wizard/match_fields.html:29 -#: order/templates/order/order_wizard/match_parts.html:20 +#: order/templates/order/order_wizard/match_parts.html:21 #: part/templates/part/bom_upload/select_fields.html:32 +#: part/templates/part/import_wizard/match_fields.html:29 +#: part/templates/part/import_wizard/match_references.html:21 msgid "Submit Selections" msgstr "" #: order/templates/order/order_wizard/match_fields.html:35 #: part/templates/part/bom_upload/select_fields.html:41 +#: part/templates/part/import_wizard/ajax_match_fields.html:28 +#: part/templates/part/import_wizard/match_fields.html:35 msgid "File Fields" msgstr "" #: order/templates/order/order_wizard/match_fields.html:42 #: part/templates/part/bom_upload/select_fields.html:47 +#: part/templates/part/import_wizard/ajax_match_fields.html:35 +#: part/templates/part/import_wizard/match_fields.html:42 msgid "Remove column" msgstr "" #: order/templates/order/order_wizard/match_fields.html:60 +#: part/templates/part/import_wizard/ajax_match_fields.html:53 +#: part/templates/part/import_wizard/match_fields.html:60 msgid "Duplicate selection" msgstr "" #: order/templates/order/order_wizard/match_fields.html:71 -#: order/templates/order/order_wizard/match_parts.html:51 +#: order/templates/order/order_wizard/match_parts.html:52 #: part/templates/part/bom_upload/select_fields.html:76 #: part/templates/part/bom_upload/select_parts.html:58 +#: part/templates/part/import_wizard/ajax_match_fields.html:64 +#: part/templates/part/import_wizard/ajax_match_references.html:42 +#: part/templates/part/import_wizard/match_fields.html:71 +#: part/templates/part/import_wizard/match_references.html:49 msgid "Remove row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:11 +#: order/templates/order/order_wizard/match_parts.html:12 #: part/templates/part/bom_upload/select_parts.html:21 +#: part/templates/part/import_wizard/ajax_match_references.html:12 +#: part/templates/part/import_wizard/match_references.html:12 msgid "Errors exist in the submitted data" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:27 +#: order/templates/order/order_wizard/match_parts.html:28 #: part/templates/part/bom_upload/select_parts.html:39 +#: part/templates/part/import_wizard/ajax_match_references.html:21 +#: part/templates/part/import_wizard/match_references.html:28 msgid "Row" msgstr "" -#: order/templates/order/order_wizard/match_parts.html:28 +#: order/templates/order/order_wizard/match_parts.html:29 msgid "Select Supplier Part" msgstr "" @@ -3150,6 +3204,8 @@ msgid "Upload File for Purchase Order" msgstr "" #: order/templates/order/order_wizard/po_upload.html:18 +#: part/templates/part/import_wizard/ajax_part_upload.html:10 +#: part/templates/part/import_wizard/part_upload.html:21 #, python-format msgid "Step %(step)s of %(count)s" msgstr "" @@ -3239,8 +3295,8 @@ msgid "Purchase Order Items" msgstr "" #: order/templates/order/purchase_order_detail.html:24 -#: order/templates/order/sales_order_detail.html:22 order/views.py:1321 -#: order/views.py:1404 +#: order/templates/order/sales_order_detail.html:22 order/views.py:1327 +#: order/views.py:1410 msgid "Add Line Item" msgstr "" @@ -3288,9 +3344,9 @@ msgstr "" #: order/templates/order/receive_parts.html:14 part/api.py:45 #: part/models.py:322 part/templates/part/cat_link.html:7 -#: part/templates/part/category.html:99 part/templates/part/category.html:148 -#: part/templates/part/category_navbar.html:22 -#: part/templates/part/category_navbar.html:29 +#: part/templates/part/category.html:108 part/templates/part/category.html:157 +#: part/templates/part/category_navbar.html:25 +#: part/templates/part/category_navbar.html:32 #: part/templates/part/category_partlist.html:10 #: templates/InvenTree/index.html:97 templates/InvenTree/search.html:114 #: templates/InvenTree/settings/tabs.html:28 templates/js/part.js:666 @@ -3356,18 +3412,18 @@ msgstr "" msgid "Sales Order Items" msgstr "" -#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:365 -#: templates/js/build.js:724 templates/js/build.js:1141 +#: order/templates/order/sales_order_detail.html:95 templates/js/bom.js:358 +#: templates/js/build.js:725 templates/js/build.js:1142 msgid "Actions" msgstr "" -#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:610 -#: templates/js/build.js:946 +#: order/templates/order/sales_order_detail.html:102 templates/js/build.js:611 +#: templates/js/build.js:947 msgid "Edit stock allocation" msgstr "" -#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:612 -#: templates/js/build.js:947 +#: order/templates/order/sales_order_detail.html:103 templates/js/build.js:613 +#: templates/js/build.js:948 msgid "Delete stock allocation" msgstr "" @@ -3379,8 +3435,8 @@ msgstr "" msgid "ID" msgstr "" -#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:675 -#: templates/js/build.js:942 +#: order/templates/order/sales_order_detail.html:274 templates/js/build.js:676 +#: templates/js/build.js:943 msgid "Allocated" msgstr "" @@ -3396,7 +3452,7 @@ msgstr "" msgid "Allocate serial numbers" msgstr "" -#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:738 +#: order/templates/order/sales_order_detail.html:346 templates/js/build.js:739 msgid "Allocate stock" msgstr "" @@ -3404,8 +3460,8 @@ msgstr "" msgid "Purchase stock" msgstr "" -#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:731 -#: templates/js/build.js:1149 +#: order/templates/order/sales_order_detail.html:353 templates/js/build.js:732 +#: templates/js/build.js:1150 msgid "Build stock" msgstr "" @@ -3459,195 +3515,195 @@ msgstr "" msgid "Sales Order Attachments" msgstr "" -#: order/views.py:104 +#: order/views.py:106 msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:154 +#: order/views.py:156 msgid "Add Sales Order Attachment" msgstr "" -#: order/views.py:346 +#: order/views.py:348 msgid "Create Sales Order" msgstr "" -#: order/views.py:381 +#: order/views.py:383 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:401 +#: order/views.py:403 msgid "Edit Sales Order" msgstr "" -#: order/views.py:417 +#: order/views.py:419 msgid "Cancel Order" msgstr "" -#: order/views.py:426 order/views.py:452 +#: order/views.py:428 order/views.py:454 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:429 order/views.py:455 +#: order/views.py:431 order/views.py:457 msgid "Order cannot be cancelled" msgstr "" -#: order/views.py:443 +#: order/views.py:445 msgid "Cancel sales order" msgstr "" -#: order/views.py:469 +#: order/views.py:471 msgid "Issue Order" msgstr "" -#: order/views.py:478 +#: order/views.py:480 msgid "Confirm order placement" msgstr "" -#: order/views.py:488 +#: order/views.py:490 msgid "Purchase order issued" msgstr "" -#: order/views.py:499 +#: order/views.py:501 msgid "Complete Order" msgstr "" -#: order/views.py:515 +#: order/views.py:517 msgid "Confirm order completion" msgstr "" -#: order/views.py:526 +#: order/views.py:528 msgid "Purchase order completed" msgstr "" -#: order/views.py:536 +#: order/views.py:538 msgid "Ship Order" msgstr "" -#: order/views.py:552 +#: order/views.py:554 msgid "Confirm order shipment" msgstr "" -#: order/views.py:558 +#: order/views.py:560 msgid "Could not ship order" msgstr "" -#: order/views.py:584 +#: order/views.py:607 msgid "Match Supplier Parts" msgstr "" -#: order/views.py:798 +#: order/views.py:804 msgid "Receive Parts" msgstr "" -#: order/views.py:868 +#: order/views.py:874 msgid "Items received" msgstr "" -#: order/views.py:882 +#: order/views.py:888 msgid "No destination set" msgstr "" -#: order/views.py:927 +#: order/views.py:933 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:933 +#: order/views.py:939 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:939 +#: order/views.py:945 msgid "No lines specified" msgstr "" -#: order/views.py:1012 +#: order/views.py:1018 msgid "Update prices" msgstr "" -#: order/views.py:1270 +#: order/views.py:1276 #, python-brace-format msgid "Ordered {n} parts" msgstr "" -#: order/views.py:1330 +#: order/views.py:1336 msgid "Supplier part must be specified" msgstr "" -#: order/views.py:1336 +#: order/views.py:1342 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:1467 order/views.py:1485 +#: order/views.py:1473 order/views.py:1491 msgid "Edit Line Item" msgstr "" -#: order/views.py:1501 order/views.py:1513 +#: order/views.py:1507 order/views.py:1519 msgid "Delete Line Item" msgstr "" -#: order/views.py:1506 order/views.py:1518 +#: order/views.py:1512 order/views.py:1524 msgid "Deleted line item" msgstr "" -#: order/views.py:1531 +#: order/views.py:1537 msgid "Allocate Serial Numbers" msgstr "" -#: order/views.py:1576 +#: order/views.py:1582 #, python-brace-format msgid "Allocated {n} items" msgstr "" -#: order/views.py:1592 +#: order/views.py:1598 msgid "Select line item" msgstr "" -#: order/views.py:1623 +#: order/views.py:1629 #, python-brace-format msgid "No matching item for serial {serial}" msgstr "" -#: order/views.py:1633 +#: order/views.py:1639 #, python-brace-format msgid "{serial} is not in stock" msgstr "" -#: order/views.py:1641 +#: order/views.py:1647 #, python-brace-format msgid "{serial} already allocated to an order" msgstr "" -#: order/views.py:1695 +#: order/views.py:1701 msgid "Allocate Stock to Order" msgstr "" -#: order/views.py:1769 +#: order/views.py:1775 msgid "Edit Allocation Quantity" msgstr "" -#: order/views.py:1784 +#: order/views.py:1790 msgid "Remove allocation" msgstr "" -#: order/views.py:1856 +#: order/views.py:1862 msgid "Sales order not found" msgstr "" -#: order/views.py:1862 +#: order/views.py:1868 msgid "Price not found" msgstr "" -#: order/views.py:1865 +#: order/views.py:1871 #, python-brace-format msgid "Updated {part} unit-price to {price}" msgstr "" -#: order/views.py:1870 +#: order/views.py:1876 #, python-brace-format msgid "Updated {part} unit-price to {price} and quantity to {qty}" msgstr "" #: part/bom.py:138 part/models.py:72 part/models.py:747 -#: part/templates/part/category.html:66 part/templates/part/detail.html:90 +#: part/templates/part/category.html:75 part/templates/part/detail.html:90 msgid "Default Location" msgstr "" @@ -3825,8 +3881,8 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:83 part/templates/part/category.html:23 -#: part/templates/part/category.html:94 templates/InvenTree/search.html:127 +#: part/models.py:83 part/templates/part/category.html:32 +#: part/templates/part/category.html:103 templates/InvenTree/search.html:127 #: templates/stats.html:84 users/models.py:39 msgid "Part Categories" msgstr "" @@ -3876,7 +3932,7 @@ msgstr "" msgid "Part description" msgstr "" -#: part/models.py:701 part/templates/part/category.html:73 +#: part/models.py:701 part/templates/part/category.html:82 #: part/templates/part/detail.html:67 msgid "Keywords" msgstr "" @@ -4101,7 +4157,7 @@ msgstr "" msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:285 +#: part/models.py:2295 templates/js/bom.js:216 templates/js/bom.js:278 msgid "Optional" msgstr "" @@ -4133,7 +4189,7 @@ msgstr "" msgid "BOM line checksum" msgstr "" -#: part/models.py:2311 templates/js/bom.js:302 templates/js/bom.js:309 +#: part/models.py:2311 templates/js/bom.js:295 templates/js/bom.js:302 #: templates/js/table_filters.js:51 msgid "Inherited" msgstr "" @@ -4142,7 +4198,7 @@ msgstr "" msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:2317 templates/js/bom.js:294 +#: part/models.py:2317 templates/js/bom.js:287 msgid "Allow Variants" msgstr "" @@ -4150,8 +4206,8 @@ msgstr "" msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:2394 part/views.py:1692 part/views.py:1744 -#: stock/models.py:294 +#: part/models.py:2394 part/views.py:1859 part/views.py:1911 +#: stock/models.py:290 msgid "Quantity must be integer value for trackable parts" msgstr "" @@ -4199,8 +4255,8 @@ msgstr "" msgid "Deleting this entry will remove the BOM row from the following part" msgstr "" -#: part/templates/part/bom.html:10 part/templates/part/navbar.html:50 -#: part/templates/part/navbar.html:53 +#: part/templates/part/bom.html:10 part/templates/part/navbar.html:51 +#: part/templates/part/navbar.html:54 msgid "Bill of Materials" msgstr "" @@ -4247,7 +4303,7 @@ msgstr "" msgid "Validate Bill of Materials" msgstr "" -#: part/templates/part/bom.html:61 part/views.py:1987 +#: part/templates/part/bom.html:61 part/views.py:2154 msgid "Export Bill of Materials" msgstr "" @@ -4263,7 +4319,7 @@ msgstr "" msgid "All selected BOM items will be deleted" msgstr "" -#: part/templates/part/bom.html:160 part/views.py:585 +#: part/templates/part/bom.html:160 part/views.py:590 #: templates/js/stock.js:1313 msgid "Create New Part" msgstr "" @@ -4300,7 +4356,7 @@ msgid "Select Part" msgstr "" #: part/templates/part/bom_upload/select_parts.html:65 -#: part/templates/part/category.html:117 +#: part/templates/part/category.html:126 msgid "Create new part" msgstr "" @@ -4341,87 +4397,87 @@ msgstr "" msgid "Start New Build" msgstr "" -#: part/templates/part/category.html:24 +#: part/templates/part/category.html:33 msgid "All parts" msgstr "" -#: part/templates/part/category.html:29 part/views.py:2397 +#: part/templates/part/category.html:38 part/views.py:2564 msgid "Create new part category" msgstr "" -#: part/templates/part/category.html:35 +#: part/templates/part/category.html:44 msgid "Edit part category" msgstr "" -#: part/templates/part/category.html:40 +#: part/templates/part/category.html:49 msgid "Delete part category" msgstr "" -#: part/templates/part/category.html:50 part/templates/part/category.html:89 +#: part/templates/part/category.html:59 part/templates/part/category.html:98 msgid "Category Details" msgstr "" -#: part/templates/part/category.html:55 +#: part/templates/part/category.html:64 msgid "Category Path" msgstr "" -#: part/templates/part/category.html:60 +#: part/templates/part/category.html:69 msgid "Category Description" msgstr "" -#: part/templates/part/category.html:79 -#: part/templates/part/category_navbar.html:11 -#: part/templates/part/category_navbar.html:18 +#: part/templates/part/category.html:88 +#: part/templates/part/category_navbar.html:14 +#: part/templates/part/category_navbar.html:21 #: part/templates/part/subcategory.html:16 msgid "Subcategories" msgstr "" -#: part/templates/part/category.html:84 +#: part/templates/part/category.html:93 msgid "Parts (Including subcategories)" msgstr "" -#: part/templates/part/category.html:113 +#: part/templates/part/category.html:122 msgid "Export Part Data" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set category" msgstr "" -#: part/templates/part/category.html:125 +#: part/templates/part/category.html:134 msgid "Set Category" msgstr "" -#: part/templates/part/category.html:128 +#: part/templates/part/category.html:137 msgid "Export Data" msgstr "" -#: part/templates/part/category.html:132 +#: part/templates/part/category.html:141 msgid "View list display" msgstr "" -#: part/templates/part/category.html:135 +#: part/templates/part/category.html:144 msgid "View grid display" msgstr "" -#: part/templates/part/category.html:209 +#: part/templates/part/category.html:218 #: stock/templates/stock/location.html:192 templates/js/stock.js:737 msgid "Create new location" msgstr "" -#: part/templates/part/category.html:214 part/templates/part/category.html:244 +#: part/templates/part/category.html:223 part/templates/part/category.html:253 msgid "New Category" msgstr "" -#: part/templates/part/category.html:215 +#: part/templates/part/category.html:224 msgid "Create new category" msgstr "" -#: part/templates/part/category.html:245 +#: part/templates/part/category.html:254 msgid "Create new Part Category" msgstr "" -#: part/templates/part/category.html:251 stock/views.py:1391 +#: part/templates/part/category.html:260 stock/views.py:1391 msgid "Create new Stock Location" msgstr "" @@ -4460,12 +4516,17 @@ msgstr "" msgid "If this category is deleted, these parts will be moved to the top-level category Teile" msgstr "" +#: part/templates/part/category_navbar.html:37 +#: part/templates/part/category_navbar.html:40 +msgid "Import Parts" +msgstr "" + #: part/templates/part/category_parametric.html:10 -#: part/templates/part/navbar.html:21 part/templates/part/params.html:10 +#: part/templates/part/navbar.html:22 part/templates/part/params.html:10 msgid "Part Parameters" msgstr "" -#: part/templates/part/copy_part.html:9 part/views.py:461 +#: part/templates/part/copy_part.html:9 part/views.py:466 msgid "Duplicate Part" msgstr "" @@ -4489,7 +4550,7 @@ msgstr "" msgid "%(full_name)s - %(desc)s (%(match_per)s%% match)" msgstr "" -#: part/templates/part/detail.html:11 part/templates/part/navbar.html:13 +#: part/templates/part/detail.html:11 part/templates/part/navbar.html:14 msgid "Part Details" msgstr "" @@ -4569,12 +4630,21 @@ msgstr "" msgid "Part is not active" msgstr "" +#: part/templates/part/import_wizard/ajax_part_upload.html:29 +#: part/templates/part/import_wizard/part_upload.html:51 +msgid "Unsuffitient privileges." +msgstr "" + +#: part/templates/part/import_wizard/part_upload.html:14 +msgid "Import Parts from File" +msgstr "" + #: part/templates/part/internal_prices.html:11 -#: part/templates/part/navbar.html:100 +#: part/templates/part/navbar.html:101 msgid "Internal Price Information" msgstr "" -#: part/templates/part/internal_prices.html:19 part/views.py:2822 +#: part/templates/part/internal_prices.html:19 part/views.py:2989 msgid "Add Internal Price Break" msgstr "" @@ -4612,78 +4682,78 @@ msgstr "" msgid "Create new manufacturer" msgstr "" -#: part/templates/part/navbar.html:28 part/templates/part/variants.html:11 +#: part/templates/part/navbar.html:29 part/templates/part/variants.html:11 msgid "Part Variants" msgstr "" -#: part/templates/part/navbar.html:31 +#: part/templates/part/navbar.html:32 msgid "Variants" msgstr "" -#: part/templates/part/navbar.html:42 +#: part/templates/part/navbar.html:43 msgid "Allocated Stock" msgstr "" -#: part/templates/part/navbar.html:45 +#: part/templates/part/navbar.html:46 msgid "Allocations" msgstr "" -#: part/templates/part/navbar.html:66 part/templates/part/navbar.html:69 +#: part/templates/part/navbar.html:67 part/templates/part/navbar.html:70 msgid "Used In" msgstr "" -#: part/templates/part/navbar.html:74 part/templates/part/order_prices.html:12 +#: part/templates/part/navbar.html:75 part/templates/part/order_prices.html:12 msgid "Order Price Information" msgstr "" -#: part/templates/part/navbar.html:77 +#: part/templates/part/navbar.html:78 msgid "Order Price" msgstr "" -#: part/templates/part/navbar.html:103 part/templates/part/order_prices.html:93 +#: part/templates/part/navbar.html:104 part/templates/part/order_prices.html:94 #: part/templates/part/part_pricing.html:82 msgid "Internal Price" msgstr "" -#: part/templates/part/navbar.html:106 +#: part/templates/part/navbar.html:107 msgid "Sales Price Information" msgstr "" -#: part/templates/part/navbar.html:120 part/templates/part/part_tests.html:10 +#: part/templates/part/navbar.html:121 part/templates/part/part_tests.html:10 msgid "Part Test Templates" msgstr "" -#: part/templates/part/navbar.html:123 stock/templates/stock/item_base.html:414 +#: part/templates/part/navbar.html:124 stock/templates/stock/item_base.html:414 msgid "Tests" msgstr "" -#: part/templates/part/navbar.html:127 part/templates/part/navbar.html:130 +#: part/templates/part/navbar.html:129 part/templates/part/navbar.html:132 #: part/templates/part/related.html:10 msgid "Related Parts" msgstr "" -#: part/templates/part/navbar.html:139 part/templates/part/notes.html:12 +#: part/templates/part/navbar.html:142 part/templates/part/notes.html:12 msgid "Part Notes" msgstr "" -#: part/templates/part/order_prices.html:24 +#: part/templates/part/order_prices.html:25 #: part/templates/part/part_base.html:282 msgid "Calculate" msgstr "" -#: part/templates/part/order_prices.html:31 +#: part/templates/part/order_prices.html:32 msgid "Pricing ranges" msgstr "" -#: part/templates/part/order_prices.html:36 +#: part/templates/part/order_prices.html:37 #: part/templates/part/part_pricing.html:22 msgid "Supplier Pricing" msgstr "" -#: part/templates/part/order_prices.html:37 -#: part/templates/part/order_prices.html:62 -#: part/templates/part/order_prices.html:94 -#: part/templates/part/order_prices.html:108 +#: part/templates/part/order_prices.html:38 +#: part/templates/part/order_prices.html:63 +#: part/templates/part/order_prices.html:95 +#: part/templates/part/order_prices.html:109 #: part/templates/part/part_pricing.html:26 #: part/templates/part/part_pricing.html:52 #: part/templates/part/part_pricing.html:85 @@ -4691,10 +4761,10 @@ msgstr "" msgid "Unit Cost" msgstr "" -#: part/templates/part/order_prices.html:44 -#: part/templates/part/order_prices.html:69 -#: part/templates/part/order_prices.html:99 -#: part/templates/part/order_prices.html:113 +#: part/templates/part/order_prices.html:45 +#: part/templates/part/order_prices.html:70 +#: part/templates/part/order_prices.html:100 +#: part/templates/part/order_prices.html:114 #: part/templates/part/part_pricing.html:32 #: part/templates/part/part_pricing.html:58 #: part/templates/part/part_pricing.html:89 @@ -4702,51 +4772,51 @@ msgstr "" msgid "Total Cost" msgstr "" -#: part/templates/part/order_prices.html:52 +#: part/templates/part/order_prices.html:53 #: part/templates/part/part_pricing.html:40 msgid "No supplier pricing available" msgstr "" -#: part/templates/part/order_prices.html:61 -#: part/templates/part/order_prices.html:128 +#: part/templates/part/order_prices.html:62 +#: part/templates/part/order_prices.html:129 #: part/templates/part/part_pricing.html:48 msgid "BOM Pricing" msgstr "" -#: part/templates/part/order_prices.html:77 +#: part/templates/part/order_prices.html:78 #: part/templates/part/part_pricing.html:66 msgid "Note: BOM pricing is incomplete for this part" msgstr "" -#: part/templates/part/order_prices.html:84 +#: part/templates/part/order_prices.html:85 #: part/templates/part/part_pricing.html:73 msgid "No BOM pricing available" msgstr "" -#: part/templates/part/order_prices.html:122 +#: part/templates/part/order_prices.html:123 #: part/templates/part/part_pricing.html:113 msgid "No pricing information is available for this part." msgstr "" -#: part/templates/part/order_prices.html:138 +#: part/templates/part/order_prices.html:139 msgid "Stock Pricing" msgstr "" -#: part/templates/part/order_prices.html:146 +#: part/templates/part/order_prices.html:147 msgid "No stock pricing history is available for this part." msgstr "" -#: part/templates/part/order_prices.html:165 +#: part/templates/part/order_prices.html:166 #, python-format msgid "Single Price - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:177 +#: part/templates/part/order_prices.html:178 #, python-format msgid "Single Price Difference - %(currency)s" msgstr "" -#: part/templates/part/order_prices.html:189 +#: part/templates/part/order_prices.html:190 #, python-format msgid "Part Single Price - %(currency)s" msgstr "" @@ -4847,7 +4917,7 @@ msgstr "" msgid "Allocated to Orders" msgstr "" -#: part/templates/part/part_base.html:172 templates/js/bom.js:323 +#: part/templates/part/part_base.html:172 templates/js/bom.js:316 msgid "Can Build" msgstr "" @@ -4965,220 +5035,224 @@ msgstr "" msgid "Unknown database" msgstr "" -#: part/views.py:90 +#: part/views.py:95 msgid "Add Related Part" msgstr "" -#: part/views.py:145 +#: part/views.py:150 msgid "Delete Related Part" msgstr "" -#: part/views.py:159 +#: part/views.py:164 msgid "Add part attachment" msgstr "" -#: part/views.py:212 templates/attachment_table.html:32 +#: part/views.py:217 templates/attachment_table.html:32 msgid "Edit attachment" msgstr "" -#: part/views.py:216 +#: part/views.py:221 msgid "Part attachment updated" msgstr "" -#: part/views.py:231 +#: part/views.py:236 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:239 +#: part/views.py:244 msgid "Deleted part attachment" msgstr "" -#: part/views.py:248 +#: part/views.py:253 msgid "Create Test Template" msgstr "" -#: part/views.py:275 +#: part/views.py:280 msgid "Edit Test Template" msgstr "" -#: part/views.py:289 +#: part/views.py:294 msgid "Delete Test Template" msgstr "" -#: part/views.py:296 +#: part/views.py:301 msgid "Set Part Category" msgstr "" -#: part/views.py:346 +#: part/views.py:351 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:381 +#: part/views.py:386 msgid "Create Variant" msgstr "" -#: part/views.py:466 +#: part/views.py:471 msgid "Copied part" msgstr "" -#: part/views.py:520 part/views.py:658 +#: part/views.py:525 part/views.py:663 msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:590 +#: part/views.py:595 msgid "Created new part" msgstr "" -#: part/views.py:925 +#: part/views.py:763 +msgid "Match References" +msgstr "" + +#: part/views.py:1092 msgid "Part QR Code" msgstr "" -#: part/views.py:1027 +#: part/views.py:1194 msgid "Upload Part Image" msgstr "" -#: part/views.py:1033 part/views.py:1068 +#: part/views.py:1200 part/views.py:1235 msgid "Updated part image" msgstr "" -#: part/views.py:1042 +#: part/views.py:1209 msgid "Select Part Image" msgstr "" -#: part/views.py:1071 +#: part/views.py:1238 msgid "Part image not found" msgstr "" -#: part/views.py:1082 +#: part/views.py:1249 msgid "Edit Part Properties" msgstr "" -#: part/views.py:1117 +#: part/views.py:1284 msgid "Duplicate BOM" msgstr "" -#: part/views.py:1147 +#: part/views.py:1314 msgid "Confirm duplication of BOM from parent" msgstr "" -#: part/views.py:1168 +#: part/views.py:1335 msgid "Validate BOM" msgstr "" -#: part/views.py:1189 +#: part/views.py:1356 msgid "Confirm that the BOM is valid" msgstr "" -#: part/views.py:1200 +#: part/views.py:1367 msgid "Validated Bill of Materials" msgstr "" -#: part/views.py:1334 +#: part/views.py:1501 msgid "No BOM file provided" msgstr "" -#: part/views.py:1695 +#: part/views.py:1862 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1720 part/views.py:1723 +#: part/views.py:1887 part/views.py:1890 msgid "Select valid part" msgstr "" -#: part/views.py:1729 +#: part/views.py:1896 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1767 +#: part/views.py:1934 msgid "Select a part" msgstr "" -#: part/views.py:1773 +#: part/views.py:1940 msgid "Selected part creates a circular BOM" msgstr "" -#: part/views.py:1777 +#: part/views.py:1944 msgid "Specify quantity" msgstr "" -#: part/views.py:2039 +#: part/views.py:2206 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:2046 +#: part/views.py:2213 msgid "Part was deleted" msgstr "" -#: part/views.py:2055 +#: part/views.py:2222 msgid "Part Pricing" msgstr "" -#: part/views.py:2196 +#: part/views.py:2363 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:2206 +#: part/views.py:2373 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:2213 +#: part/views.py:2380 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:2221 +#: part/views.py:2388 msgid "Create Part Parameter" msgstr "" -#: part/views.py:2271 +#: part/views.py:2438 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:2285 +#: part/views.py:2452 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:2345 +#: part/views.py:2512 msgid "Edit Part Category" msgstr "" -#: part/views.py:2383 +#: part/views.py:2550 msgid "Delete Part Category" msgstr "" -#: part/views.py:2389 +#: part/views.py:2556 msgid "Part category was deleted" msgstr "" -#: part/views.py:2441 +#: part/views.py:2608 msgid "Create Category Parameter Template" msgstr "" -#: part/views.py:2542 +#: part/views.py:2709 msgid "Edit Category Parameter Template" msgstr "" -#: part/views.py:2598 +#: part/views.py:2765 msgid "Delete Category Parameter Template" msgstr "" -#: part/views.py:2617 +#: part/views.py:2784 msgid "Create BOM Item" msgstr "" -#: part/views.py:2687 +#: part/views.py:2854 msgid "Edit BOM item" msgstr "" -#: part/views.py:2743 +#: part/views.py:2910 msgid "Confim BOM item deletion" msgstr "" -#: part/views.py:2831 +#: part/views.py:2998 msgid "Edit Internal Price Break" msgstr "" -#: part/views.py:2839 +#: part/views.py:3006 msgid "Delete Internal Price Break" msgstr "" @@ -5284,12 +5358,12 @@ msgid "Test Results" msgstr "" #: report/templates/report/inventree_test_report_base.html:88 -#: stock/models.py:1744 +#: stock/models.py:1739 msgid "Test" msgstr "" #: report/templates/report/inventree_test_report_base.html:89 -#: stock/models.py:1750 +#: stock/models.py:1745 msgid "Result" msgstr "" @@ -5316,7 +5390,7 @@ msgstr "" msgid "Moved {n} parts to {loc}" msgstr "" -#: stock/forms.py:114 stock/forms.py:418 stock/models.py:509 +#: stock/forms.py:114 stock/forms.py:418 stock/models.py:505 #: stock/templates/stock/item_base.html:381 templates/js/stock.js:658 msgid "Expiry Date" msgstr "" @@ -5406,187 +5480,187 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:56 stock/models.py:547 +#: stock/models.py:52 stock/models.py:542 msgid "Owner" msgstr "" -#: stock/models.py:57 stock/models.py:548 +#: stock/models.py:53 stock/models.py:543 msgid "Select Owner" msgstr "" -#: stock/models.py:275 +#: stock/models.py:271 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:311 +#: stock/models.py:307 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:321 stock/models.py:330 +#: stock/models.py:317 stock/models.py:326 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:322 +#: stock/models.py:318 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:344 +#: stock/models.py:340 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:350 +#: stock/models.py:346 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:357 +#: stock/models.py:353 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:399 +#: stock/models.py:395 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:408 +#: stock/models.py:404 msgid "Base part" msgstr "" -#: stock/models.py:417 +#: stock/models.py:413 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:422 stock/templates/stock/stock_app_base.html:8 +#: stock/models.py:418 stock/templates/stock/stock_app_base.html:8 msgid "Stock Location" msgstr "" -#: stock/models.py:425 +#: stock/models.py:421 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:432 +#: stock/models.py:428 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_base.html:270 +#: stock/models.py:433 stock/templates/stock/item_base.html:270 msgid "Installed In" msgstr "" -#: stock/models.py:440 +#: stock/models.py:436 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:456 +#: stock/models.py:452 msgid "Serial number for this item" msgstr "" -#: stock/models.py:468 +#: stock/models.py:464 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:472 +#: stock/models.py:468 msgid "Stock Quantity" msgstr "" -#: stock/models.py:481 +#: stock/models.py:477 msgid "Source Build" msgstr "" -#: stock/models.py:483 +#: stock/models.py:479 msgid "Build for this stock item" msgstr "" -#: stock/models.py:494 +#: stock/models.py:490 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:497 +#: stock/models.py:493 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:503 +#: stock/models.py:499 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:510 +#: stock/models.py:506 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete on deplete" msgstr "" -#: stock/models.py:523 +#: stock/models.py:519 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:533 stock/templates/stock/item_notes.html:13 +#: stock/models.py:529 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/navbar.html:54 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:543 +#: stock/models.py:538 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1011 +#: stock/models.py:1006 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1017 +#: stock/models.py:1012 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1023 +#: stock/models.py:1018 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:1026 +#: stock/models.py:1021 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:1029 +#: stock/models.py:1024 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1036 +#: stock/models.py:1031 #, python-brace-format msgid "Serial numbers already exist: {exists}" msgstr "" -#: stock/models.py:1194 +#: stock/models.py:1189 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1668 +#: stock/models.py:1663 msgid "Entry notes" msgstr "" -#: stock/models.py:1721 +#: stock/models.py:1716 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1727 +#: stock/models.py:1722 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1745 +#: stock/models.py:1740 msgid "Test name" msgstr "" -#: stock/models.py:1751 templates/js/table_filters.js:217 +#: stock/models.py:1746 templates/js/table_filters.js:217 msgid "Test result" msgstr "" -#: stock/models.py:1757 +#: stock/models.py:1752 msgid "Test output value" msgstr "" -#: stock/models.py:1764 +#: stock/models.py:1759 msgid "Test result attachment" msgstr "" -#: stock/models.py:1770 +#: stock/models.py:1765 msgid "Test notes" msgstr "" @@ -5738,7 +5812,7 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:289 templates/js/build.js:593 +#: stock/templates/stock/item_base.html:289 templates/js/build.js:594 msgid "No location set" msgstr "" @@ -6135,7 +6209,7 @@ msgstr "" msgid "Serialize Stock" msgstr "" -#: stock/views.py:1575 templates/js/build.js:326 +#: stock/views.py:1575 templates/js/build.js:327 msgid "Create new Stock Item" msgstr "" @@ -6284,12 +6358,12 @@ msgid "No category parameter templates found" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:85 +#: templates/InvenTree/settings/part.html:102 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:86 +#: templates/InvenTree/settings/part.html:103 msgid "Delete Template" msgstr "" @@ -6297,23 +6371,23 @@ msgstr "" msgid "Currency Settings" msgstr "" -#: templates/InvenTree/settings/currencies.html:18 +#: templates/InvenTree/settings/currencies.html:25 msgid "Base Currency" msgstr "" -#: templates/InvenTree/settings/currencies.html:22 +#: templates/InvenTree/settings/currencies.html:29 msgid "Exchange Rates" msgstr "" -#: templates/InvenTree/settings/currencies.html:32 +#: templates/InvenTree/settings/currencies.html:39 msgid "Last Update" msgstr "" -#: templates/InvenTree/settings/currencies.html:38 +#: templates/InvenTree/settings/currencies.html:45 msgid "Never" msgstr "" -#: templates/InvenTree/settings/currencies.html:43 +#: templates/InvenTree/settings/currencies.html:50 msgid "Update Now" msgstr "" @@ -6337,11 +6411,19 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:44 +#: templates/InvenTree/settings/part.html:45 +msgid "Part Import" +msgstr "" + +#: templates/InvenTree/settings/part.html:48 +msgid "Import Part" +msgstr "" + +#: templates/InvenTree/settings/part.html:61 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:65 +#: templates/InvenTree/settings/part.html:82 msgid "No part parameter templates found" msgstr "" @@ -6626,7 +6708,7 @@ msgstr "" msgid "Barcode does not match a valid location" msgstr "" -#: templates/js/bom.js:175 templates/js/build.js:1091 +#: templates/js/bom.js:175 templates/js/build.js:1092 msgid "Open subassembly" msgstr "" @@ -6638,31 +6720,35 @@ msgstr "" msgid "Purchase Price Average" msgstr "" -#: templates/js/bom.js:277 +#: templates/js/bom.js:265 +msgid "Buy Price" +msgstr "" + +#: templates/js/bom.js:271 msgid "No pricing available" msgstr "" -#: templates/js/bom.js:313 templates/js/bom.js:399 +#: templates/js/bom.js:306 templates/js/bom.js:392 msgid "View BOM" msgstr "" -#: templates/js/bom.js:373 +#: templates/js/bom.js:366 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:375 +#: templates/js/bom.js:368 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:377 +#: templates/js/bom.js:370 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:379 +#: templates/js/bom.js:372 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:470 templates/js/build.js:423 templates/js/build.js:1189 +#: templates/js/bom.js:463 templates/js/build.js:424 templates/js/build.js:1190 msgid "No BOM items found" msgstr "" @@ -6690,37 +6776,37 @@ msgstr "" msgid "Location not specified" msgstr "" -#: templates/js/build.js:325 templates/stock_table.html:20 +#: templates/js/build.js:326 templates/stock_table.html:20 msgid "New Stock Item" msgstr "" -#: templates/js/build.js:644 +#: templates/js/build.js:645 msgid "Required Part" msgstr "" -#: templates/js/build.js:665 +#: templates/js/build.js:666 msgid "Quantity Per" msgstr "" -#: templates/js/build.js:735 templates/js/build.js:1153 +#: templates/js/build.js:736 templates/js/build.js:1154 #: templates/stock_table.html:59 msgid "Order stock" msgstr "" -#: templates/js/build.js:788 +#: templates/js/build.js:789 msgid "No builds matching query" msgstr "" -#: templates/js/build.js:805 templates/js/part.js:390 templates/js/part.js:635 +#: templates/js/build.js:806 templates/js/part.js:390 templates/js/part.js:635 #: templates/js/stock.js:514 templates/js/stock.js:966 msgid "Select" msgstr "" -#: templates/js/build.js:825 +#: templates/js/build.js:826 msgid "Build order is overdue" msgstr "" -#: templates/js/build.js:924 +#: templates/js/build.js:925 msgid "No parts allocated for" msgstr "" diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index c22d76a52e..04414e3db3 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -5,11 +5,12 @@ JSON API for the Order app # -*- coding: utf-8 -*- from __future__ import unicode_literals +from django.conf.urls import url, include + from django_filters.rest_framework import DjangoFilterBackend from rest_framework import generics -from rest_framework import filters - -from django.conf.urls import url, include +from rest_framework import filters, status +from rest_framework.response import Response from InvenTree.helpers import str2bool from InvenTree.api import AttachmentMixin @@ -38,6 +39,20 @@ class POList(generics.ListCreateAPIView): queryset = PurchaseOrder.objects.all() serializer_class = POSerializer + def create(self, request, *args, **kwargs): + """ + Save user information on create + """ + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + + item = serializer.save() + item.created_by = request.user + item.save() + + headers = self.get_success_headers(serializer.data) + return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) + def get_serializer(self, *args, **kwargs): try: @@ -239,10 +254,12 @@ class POLineItemList(generics.ListCreateAPIView): ] -class POLineItemDetail(generics.RetrieveUpdateAPIView): - """ API endpoint for detail view of a PurchaseOrderLineItem object """ +class POLineItemDetail(generics.RetrieveUpdateDestroyAPIView): + """ + Detail API endpoint for PurchaseOrderLineItem object + """ - queryset = PurchaseOrderLineItem + queryset = PurchaseOrderLineItem.objects.all() serializer_class = POLineItemSerializer @@ -259,6 +276,15 @@ class SOAttachmentList(generics.ListCreateAPIView, AttachmentMixin): ] +class SOAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, AttachmentMixin): + """ + Detail endpoint for SalesOrderAttachment + """ + + queryset = SalesOrderAttachment.objects.all() + serializer_class = SOAttachmentSerializer + + class SOList(generics.ListCreateAPIView): """ API endpoint for accessing a list of SalesOrder objects. @@ -270,6 +296,20 @@ class SOList(generics.ListCreateAPIView): queryset = SalesOrder.objects.all() serializer_class = SalesOrderSerializer + def create(self, request, *args, **kwargs): + """ + Save user information on create + """ + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + + item = serializer.save() + item.created_by = request.user + item.save() + + headers = self.get_success_headers(serializer.data) + return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) + def get_serializer(self, *args, **kwargs): try: @@ -474,7 +514,7 @@ class SOLineItemList(generics.ListCreateAPIView): ] -class SOLineItemDetail(generics.RetrieveUpdateAPIView): +class SOLineItemDetail(generics.RetrieveUpdateDestroyAPIView): """ API endpoint for detail view of a SalesOrderLineItem object """ queryset = SalesOrderLineItem.objects.all() @@ -554,12 +594,22 @@ class POAttachmentList(generics.ListCreateAPIView, AttachmentMixin): serializer_class = POAttachmentSerializer +class POAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, AttachmentMixin): + """ + Detail endpoint for a PurchaseOrderAttachment + """ + + queryset = PurchaseOrderAttachment.objects.all() + serializer_class = POAttachmentSerializer + + order_api_urls = [ # API endpoints for purchase orders - url(r'^po/(?P\d+)/$', PODetail.as_view(), name='api-po-detail'), url(r'po/attachment/', include([ + url(r'^(?P\d+)/$', POAttachmentDetail.as_view(), name='api-po-attachment-detail'), url(r'^.*$', POAttachmentList.as_view(), name='api-po-attachment-list'), ])), + url(r'^po/(?P\d+)/$', PODetail.as_view(), name='api-po-detail'), url(r'^po/.*$', POList.as_view(), name='api-po-list'), # API endpoints for purchase order line items @@ -568,12 +618,12 @@ order_api_urls = [ # API endpoints for sales ordesr url(r'^so/', include([ - url(r'^(?P\d+)/$', SODetail.as_view(), name='api-so-detail'), url(r'attachment/', include([ + url(r'^(?P\d+)/$', SOAttachmentDetail.as_view(), name='api-so-attachment-detail'), url(r'^.*$', SOAttachmentList.as_view(), name='api-so-attachment-list'), ])), - # List all sales orders + url(r'^(?P\d+)/$', SODetail.as_view(), name='api-so-detail'), url(r'^.*$', SOList.as_view(), name='api-so-list'), ])), diff --git a/InvenTree/order/forms.py b/InvenTree/order/forms.py index f094caafbe..b8a66a825d 100644 --- a/InvenTree/order/forms.py +++ b/InvenTree/order/forms.py @@ -12,7 +12,6 @@ from mptt.fields import TreeNodeChoiceField from InvenTree.forms import HelperForm from InvenTree.fields import InvenTreeMoneyField, RoundingDecimalFormField -from InvenTree.fields import DatePickerFormField from InvenTree.helpers import clean_decimal @@ -21,8 +20,8 @@ from common.forms import MatchItemForm import part.models from stock.models import StockLocation -from .models import PurchaseOrder, PurchaseOrderLineItem, PurchaseOrderAttachment -from .models import SalesOrder, SalesOrderLineItem, SalesOrderAttachment +from .models import PurchaseOrder +from .models import SalesOrder, SalesOrderLineItem from .models import SalesOrderAllocation @@ -97,135 +96,6 @@ class ReceivePurchaseOrderForm(HelperForm): ] -class EditPurchaseOrderForm(HelperForm): - """ Form for editing a PurchaseOrder object """ - - def __init__(self, *args, **kwargs): - - self.field_prefix = { - 'reference': 'PO', - 'link': 'fa-link', - 'target_date': 'fa-calendar-alt', - } - - self.field_placeholder = { - 'reference': _('Purchase Order reference'), - } - - super().__init__(*args, **kwargs) - - target_date = DatePickerFormField( - label=_('Target Date'), - help_text=_('Target date for order delivery. Order will be overdue after this date.'), - ) - - class Meta: - model = PurchaseOrder - fields = [ - 'reference', - 'supplier', - 'supplier_reference', - 'description', - 'target_date', - 'link', - 'responsible', - ] - - -class EditSalesOrderForm(HelperForm): - """ Form for editing a SalesOrder object """ - - def __init__(self, *args, **kwargs): - - self.field_prefix = { - 'reference': 'SO', - 'link': 'fa-link', - 'target_date': 'fa-calendar-alt', - } - - self.field_placeholder = { - 'reference': _('Enter sales order number'), - } - - super().__init__(*args, **kwargs) - - target_date = DatePickerFormField( - label=_('Target Date'), - help_text=_('Target date for order completion. Order will be overdue after this date.'), - ) - - class Meta: - model = SalesOrder - fields = [ - 'reference', - 'customer', - 'customer_reference', - 'description', - 'target_date', - 'link', - 'responsible', - ] - - -class EditPurchaseOrderAttachmentForm(HelperForm): - """ Form for editing a PurchaseOrderAttachment object """ - - class Meta: - model = PurchaseOrderAttachment - fields = [ - 'order', - 'attachment', - 'comment' - ] - - -class EditSalesOrderAttachmentForm(HelperForm): - """ Form for editing a SalesOrderAttachment object """ - - class Meta: - model = SalesOrderAttachment - fields = [ - 'order', - 'attachment', - 'comment' - ] - - -class EditPurchaseOrderLineItemForm(HelperForm): - """ Form for editing a PurchaseOrderLineItem object """ - - quantity = RoundingDecimalFormField(max_digits=10, decimal_places=5, label=_('Quantity')) - - class Meta: - model = PurchaseOrderLineItem - fields = [ - 'order', - 'part', - 'quantity', - 'reference', - 'purchase_price', - 'destination', - 'notes', - ] - - -class EditSalesOrderLineItemForm(HelperForm): - """ Form for editing a SalesOrderLineItem object """ - - quantity = RoundingDecimalFormField(max_digits=10, decimal_places=5, label=_('Quantity')) - - class Meta: - model = SalesOrderLineItem - fields = [ - 'order', - 'part', - 'quantity', - 'reference', - 'sale_price', - 'notes' - ] - - class AllocateSerialsToSalesOrderForm(forms.Form): """ Form for assigning stock to a sales order, diff --git a/InvenTree/order/migrations/0048_auto_20210702_2321.py b/InvenTree/order/migrations/0048_auto_20210702_2321.py new file mode 100644 index 0000000000..d6785e669e --- /dev/null +++ b/InvenTree/order/migrations/0048_auto_20210702_2321.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.4 on 2021-07-02 13:21 + +from django.db import migrations, models +import order.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0047_auto_20210701_0509'), + ] + + operations = [ + migrations.AlterField( + model_name='purchaseorder', + name='reference', + field=models.CharField(default=order.models.get_next_po_number, help_text='Order reference', max_length=64, unique=True, verbose_name='Reference'), + ), + migrations.AlterField( + model_name='salesorder', + name='reference', + field=models.CharField(default=order.models.get_next_so_number, help_text='Order reference', max_length=64, unique=True, verbose_name='Reference'), + ), + ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 669603f5ec..22f70d0f3c 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -31,6 +31,60 @@ from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus, StockS from InvenTree.models import InvenTreeAttachment +def get_next_po_number(): + """ + Returns the next available PurchaseOrder reference number + """ + + if PurchaseOrder.objects.count() == 0: + return + + order = PurchaseOrder.objects.exclude(reference=None).last() + + attempts = set([order.reference]) + + while 1: + reference = increment(order.reference) + + if reference in attempts: + # Escape infinite recursion + return reference + + if PurchaseOrder.objects.filter(reference=reference).exists(): + attempts.add(reference) + else: + break + + return reference + + +def get_next_so_number(): + """ + Returns the next available SalesOrder reference number + """ + + if SalesOrder.objects.count() == 0: + return + + order = SalesOrder.objects.exclude(reference=None).last() + + attempts = set([order.reference]) + + while 1: + reference = increment(order.reference) + + if reference in attempts: + # Escape infinite recursion + return reference + + if SalesOrder.objects.filter(reference=reference).exists(): + attempts.add(reference) + else: + break + + return reference + + class Order(models.Model): """ Abstract model for an order. @@ -72,6 +126,8 @@ class Order(models.Model): while 1: new_ref = increment(ref) + print("Reference:", new_ref) + if new_ref in tries: # We are in a looping situation - simply return the original one return ref @@ -95,8 +151,6 @@ class Order(models.Model): class Meta: abstract = True - reference = models.CharField(unique=True, max_length=64, blank=False, verbose_name=_('Reference'), help_text=_('Order reference')) - description = models.CharField(max_length=250, verbose_name=_('Description'), help_text=_('Order description')) link = models.URLField(blank=True, verbose_name=_('Link'), help_text=_('Link to external page')) @@ -132,6 +186,10 @@ class PurchaseOrder(Order): target_date: Expected delivery target date for PurchaseOrder completion (optional) """ + @staticmethod + def get_api_url(): + return reverse('api-po-list') + OVERDUE_FILTER = Q(status__in=PurchaseOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date()) @staticmethod @@ -177,6 +235,15 @@ class PurchaseOrder(Order): return f"{prefix}{self.reference} - {self.supplier.name}" + reference = models.CharField( + unique=True, + max_length=64, + blank=False, + verbose_name=_('Reference'), + help_text=_('Order reference'), + default=get_next_po_number, + ) + status = models.PositiveIntegerField(default=PurchaseOrderStatus.PENDING, choices=PurchaseOrderStatus.items(), help_text=_('Purchase order status')) @@ -403,6 +470,10 @@ class SalesOrder(Order): target_date: Target date for SalesOrder completion (optional) """ + @staticmethod + def get_api_url(): + return reverse('api-so-list') + OVERDUE_FILTER = Q(status__in=SalesOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date()) @staticmethod @@ -451,6 +522,15 @@ class SalesOrder(Order): def get_absolute_url(self): return reverse('so-detail', kwargs={'pk': self.id}) + reference = models.CharField( + unique=True, + max_length=64, + blank=False, + verbose_name=_('Reference'), + help_text=_('Order reference'), + default=get_next_so_number, + ) + customer = models.ForeignKey( Company, on_delete=models.SET_NULL, @@ -581,6 +661,10 @@ class PurchaseOrderAttachment(InvenTreeAttachment): Model for storing file attachments against a PurchaseOrder object """ + @staticmethod + def get_api_url(): + return reverse('api-po-attachment-list') + def getSubdir(self): return os.path.join("po_files", str(self.order.id)) @@ -592,6 +676,10 @@ class SalesOrderAttachment(InvenTreeAttachment): Model for storing file attachments against a SalesOrder object """ + @staticmethod + def get_api_url(): + return reverse('api-so-attachment-list') + def getSubdir(self): return os.path.join("so_files", str(self.order.id)) @@ -610,7 +698,13 @@ class OrderLineItem(models.Model): class Meta: abstract = True - quantity = RoundingDecimalField(max_digits=15, decimal_places=5, validators=[MinValueValidator(0)], default=1, verbose_name=_('Quantity'), help_text=_('Item quantity')) + quantity = RoundingDecimalField( + verbose_name=_('Quantity'), + help_text=_('Item quantity'), + default=1, + max_digits=15, decimal_places=5, + validators=[MinValueValidator(0)], + ) reference = models.CharField(max_length=100, blank=True, verbose_name=_('Reference'), help_text=_('Line item reference')) @@ -625,6 +719,10 @@ class PurchaseOrderLineItem(OrderLineItem): """ + @staticmethod + def get_api_url(): + return reverse('api-po-line-list') + class Meta: unique_together = ( ('order', 'part') @@ -707,6 +805,10 @@ class SalesOrderLineItem(OrderLineItem): sale_price: The unit sale price for this OrderLineItem """ + @staticmethod + def get_api_url(): + return reverse('api-so-line-list') + order = models.ForeignKey(SalesOrder, on_delete=models.CASCADE, related_name='lines', verbose_name=_('Order'), help_text=_('Sales Order')) part = models.ForeignKey('part.Part', on_delete=models.SET_NULL, related_name='sales_order_line_items', null=True, verbose_name=_('Part'), help_text=_('Part'), limit_choices_to={'salable': True}) @@ -768,6 +870,10 @@ class SalesOrderAllocation(models.Model): """ + @staticmethod + def get_api_url(): + return reverse('api-so-allocation-list') + class Meta: unique_together = [ # Cannot allocate any given StockItem to the same line more than once diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index e527b3cec9..809dd0e8fb 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -5,14 +5,16 @@ JSON serializers for the Order API # -*- coding: utf-8 -*- from __future__ import unicode_literals -from rest_framework import serializers - -from sql_util.utils import SubqueryCount +from django.utils.translation import ugettext_lazy as _ from django.db.models import Case, When, Value from django.db.models import BooleanField +from rest_framework import serializers +from sql_util.utils import SubqueryCount + from InvenTree.serializers import InvenTreeModelSerializer +from InvenTree.serializers import InvenTreeMoneySerializer from InvenTree.serializers import InvenTreeAttachmentSerializerField from company.serializers import CompanyBriefSerializer, SupplierPartSerializer @@ -24,6 +26,8 @@ from .models import PurchaseOrderAttachment, SalesOrderAttachment from .models import SalesOrder, SalesOrderLineItem from .models import SalesOrderAllocation +from common.settings import currency_code_mappings + class POSerializer(InvenTreeModelSerializer): """ Serializer for a PurchaseOrder object """ @@ -69,6 +73,8 @@ class POSerializer(InvenTreeModelSerializer): overdue = serializers.BooleanField(required=False, read_only=True) + reference = serializers.CharField(required=True) + class Meta: model = PurchaseOrder @@ -82,6 +88,7 @@ class POSerializer(InvenTreeModelSerializer): 'link', 'overdue', 'reference', + 'responsible', 'supplier', 'supplier_detail', 'supplier_reference', @@ -118,10 +125,20 @@ class POLineItemSerializer(InvenTreeModelSerializer): part_detail = PartBriefSerializer(source='get_base_part', many=False, read_only=True) supplier_part_detail = SupplierPartSerializer(source='part', many=False, read_only=True) + purchase_price = InvenTreeMoneySerializer( + max_digits=19, decimal_places=4, + allow_null=True + ) + purchase_price_string = serializers.CharField(source='purchase_price', read_only=True) destination = LocationBriefSerializer(source='get_destination', read_only=True) + purchase_price_currency = serializers.ChoiceField( + choices=currency_code_mappings(), + help_text=_('Purchase price currency'), + ) + class Meta: model = PurchaseOrderLineItem @@ -157,6 +174,11 @@ class POAttachmentSerializer(InvenTreeModelSerializer): 'order', 'attachment', 'comment', + 'upload_date', + ] + + read_only_fields = [ + 'upload_date', ] @@ -206,6 +228,8 @@ class SalesOrderSerializer(InvenTreeModelSerializer): overdue = serializers.BooleanField(required=False, read_only=True) + reference = serializers.CharField(required=True) + class Meta: model = SalesOrder @@ -221,6 +245,7 @@ class SalesOrderSerializer(InvenTreeModelSerializer): 'notes', 'overdue', 'reference', + 'responsible', 'status', 'status_text', 'shipment_date', @@ -316,13 +341,24 @@ class SOLineItemSerializer(InvenTreeModelSerializer): part_detail = PartBriefSerializer(source='part', many=False, read_only=True) allocations = SalesOrderAllocationSerializer(many=True, read_only=True) - # TODO: Once https://github.com/inventree/InvenTree/issues/1687 is fixed, remove default values - quantity = serializers.FloatField(default=1) + quantity = serializers.FloatField() allocated = serializers.FloatField(source='allocated_quantity', read_only=True) fulfilled = serializers.FloatField(source='fulfilled_quantity', read_only=True) + + sale_price = InvenTreeMoneySerializer( + max_digits=19, + decimal_places=4, + allow_null=True + ) + sale_price_string = serializers.CharField(source='sale_price', read_only=True) + sale_price_currency = serializers.ChoiceField( + choices=currency_code_mappings(), + help_text=_('Sale price currency'), + ) + class Meta: model = SalesOrderLineItem @@ -359,4 +395,9 @@ class SOAttachmentSerializer(InvenTreeModelSerializer): 'order', 'attachment', 'comment', + 'upload_date', + ] + + read_only_fields = [ + 'upload_date', ] diff --git a/InvenTree/order/templates/order/order_base.html b/InvenTree/order/templates/order/order_base.html index c7ba6be8a4..85d8fd5c51 100644 --- a/InvenTree/order/templates/order/order_base.html +++ b/InvenTree/order/templates/order/order_base.html @@ -164,11 +164,30 @@ $('#print-order-report').click(function() { }); $("#edit-order").click(function() { - launchModalForm("{% url 'po-edit' order.id %}", - { - reload: true, - } - ); + + constructForm('{% url "api-po-detail" order.pk %}', { + fields: { + reference: { + prefix: "{% settings_value 'PURCHASEORDER_REFERENCE_PREFIX' %}", + }, + {% if order.lines.count == 0 and order.status == PurchaseOrderStatus.PENDING %} + supplier: { + }, + {% endif %} + description: {}, + target_date: { + icon: 'fa-calendar-alt', + }, + link: { + icon: 'fa-link', + }, + responsible: { + icon: 'fa-user', + }, + }, + title: '{% trans "Edit Purchase Order" %}', + reload: true, + }); }); $("#receive-order").click(function() { diff --git a/InvenTree/order/templates/order/po_attachments.html b/InvenTree/order/templates/order/po_attachments.html index 40052c1ec6..07e425016b 100644 --- a/InvenTree/order/templates/order/po_attachments.html +++ b/InvenTree/order/templates/order/po_attachments.html @@ -22,7 +22,7 @@ enableDragAndDrop( '#attachment-dropzone', - "{% url 'po-attachment-create' %}", + '{% url "api-po-attachment-list" %}', { data: { order: {{ order.id }}, @@ -34,35 +34,50 @@ enableDragAndDrop( } ); -$("#new-attachment").click(function() { - launchModalForm("{% url 'po-attachment-create' %}?order={{ order.id }}", - { - reload: true, +loadAttachmentTable( + '{% url "api-po-attachment-list" %}', + { + filters: { + order: {{ order.pk }}, + }, + onEdit: function(pk) { + var url = `/api/order/po/attachment/${pk}/`; + + constructForm(url, { + fields: { + comment: {}, + }, + onSuccess: reloadAttachmentTable, + title: '{% trans "Edit Attachment" %}', + }); + }, + onDelete: function(pk) { + + constructForm(`/api/order/po/attachment/${pk}/`, { + method: 'DELETE', + confirmMessage: '{% trans "Confirm Delete Operation" %}', + title: '{% trans "Delete Attachment" %}', + onSuccess: reloadAttachmentTable, + }); } - ); -}); + } +); -$("#attachment-table").on('click', '.attachment-edit-button', function() { - var button = $(this); +$("#new-attachment").click(function() { - var url = `/order/purchase-order/attachment/${button.attr('pk')}/edit/`; - - launchModalForm(url, { + constructForm('{% url "api-po-attachment-list" %}', { + method: 'POST', + fields: { + attachment: {}, + comment: {}, + order: { + value: {{ order.pk }}, + hidden: true, + }, + }, reload: true, + title: '{% trans "Add Attachment" %}', }); }); -$("#attachment-table").on('click', '.attachment-delete-button', function() { - var button = $(this); - - var url = `/order/purchase-order/attachment/${button.attr('pk')}/delete/`; - - launchModalForm(url, { - reload: true, - }); -}); - -$("#attachment-table").inventreeTable({ -}); - {% endblock %} \ No newline at end of file diff --git a/InvenTree/order/templates/order/po_lineitem_delete.html b/InvenTree/order/templates/order/po_lineitem_delete.html deleted file mode 100644 index 1d9f80d137..0000000000 --- a/InvenTree/order/templates/order/po_lineitem_delete.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "modal_delete_form.html" %} -{% load i18n %} - -{% block pre_form_content %} -{% trans "Are you sure you wish to delete this line item?" %} -{% endblock %} \ No newline at end of file diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index 0ad73923a2..9746103c89 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -21,7 +21,8 @@
                  {% if order.status == PurchaseOrderStatus.PENDING and roles.purchase_order.change %} + {% trans "Add Line Item" %} + {% endif %}
                  @@ -37,26 +38,34 @@ {% if order.status == PurchaseOrderStatus.PENDING %} $('#new-po-line').click(function() { - launchModalForm("{% url 'po-line-item-create' %}", - { - reload: true, - data: { - order: {{ order.id }}, + + + constructForm('{% url "api-po-line-list" %}', { + fields: { + order: { + value: {{ order.pk }}, + hidden: true, }, - secondary: [ - { - field: 'part', - label: '{% trans "New Supplier Part" %}', - title: '{% trans "Create new supplier part" %}', - url: "{% url 'supplier-part-create' %}", - data: { - supplier: {{ order.supplier.id }}, - }, + part: { + filters: { + part_detail: true, + supplier_detail: true, + supplier: {{ order.supplier.pk }}, }, - ], - } - ); + }, + quantity: {}, + reference: {}, + purchase_price: {}, + purchase_price_currency: {}, + destination: {}, + notes: {}, + }, + method: 'POST', + title: '{% trans "Add Line Item" %}', + onSuccess: reloadTable, + }); }); + {% endif %} function reloadTable() { @@ -72,16 +81,34 @@ function setupCallbacks() { table.find(".button-line-edit").click(function() { var pk = $(this).attr('pk'); - launchModalForm(`/order/purchase-order/line/${pk}/edit/`, { - success: reloadTable, + constructForm(`/api/order/po-line/${pk}/`, { + fields: { + part: { + filters: { + part_detail: true, + supplier_detail: true, + supplier: {{ order.supplier.pk }}, + } + }, + quantity: {}, + reference: {}, + purchase_price: {}, + purchase_price_currency: {}, + destination: {}, + notes: {}, + }, + title: '{% trans "Edit Line Item" %}', + onSuccess: reloadTable, }); }); table.find(".button-line-delete").click(function() { var pk = $(this).attr('pk'); - launchModalForm(`/order/purchase-order/line/${pk}/delete/`, { - success: reloadTable, + constructForm(`/api/order/po-line/${pk}/`, { + method: 'DELETE', + title: '{% trans "Delete Line Item" %}', + onSuccess: reloadTable, }); }); {% endif %} diff --git a/InvenTree/order/templates/order/purchase_orders.html b/InvenTree/order/templates/order/purchase_orders.html index a2a5d5d0fa..de1c0dd8a9 100644 --- a/InvenTree/order/templates/order/purchase_orders.html +++ b/InvenTree/order/templates/order/purchase_orders.html @@ -176,19 +176,7 @@ $("#order-print").click(function() { }) $("#po-create").click(function() { - launchModalForm("{% url 'po-create' %}", - { - follow: true, - secondary: [ - { - field: 'supplier', - label: '{% trans "New Supplier" %}', - title: '{% trans "Create new Supplier" %}', - url: '{% url "supplier-create" %}', - } - ] - } - ); + createPurchaseOrder(); }); loadPurchaseOrderTable("#purchase-order-table", { diff --git a/InvenTree/order/templates/order/sales_order_base.html b/InvenTree/order/templates/order/sales_order_base.html index b342cefe66..7a2c63c5a6 100644 --- a/InvenTree/order/templates/order/sales_order_base.html +++ b/InvenTree/order/templates/order/sales_order_base.html @@ -153,7 +153,28 @@ enableNavbar({ }); $("#edit-order").click(function() { - launchModalForm("{% url 'so-edit' order.id %}", { + + constructForm('{% url "api-so-detail" order.pk %}', { + fields: { + reference: { + prefix: "{% settings_value 'SALESORDER_REFERENCE_PREFIX' %}", + }, + {% if order.lines.count == 0 and order.status == SalesOrderStatus.PENDING %} + customer: { + }, + {% endif %} + description: {}, + target_date: { + icon: 'fa-calendar-alt', + }, + link: { + icon: 'fa-link', + }, + responsible: { + icon: 'fa-user', + }, + }, + title: '{% trans "Edit Sales Order" %}', reload: true, }); }); diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html index b760409fe4..4af0e219d6 100644 --- a/InvenTree/order/templates/order/sales_order_detail.html +++ b/InvenTree/order/templates/order/sales_order_detail.html @@ -38,13 +38,23 @@ function reloadTable() { } $("#new-so-line").click(function() { - launchModalForm("{% url 'so-line-item-create' %}", { - success: reloadTable, - data: { - order: {{ order.id }}, + + constructForm('{% url "api-so-line-list" %}', { + fields: { + order: { + value: {{ order.pk }}, + hidden: true, + }, + part: {}, + quantity: {}, + reference: {}, + sale_price: {}, + sale_price_currency: {}, + notes: {}, }, - secondary: [ - ] + method: 'POST', + title: '{% trans "Add Line Item" %}', + onSuccess: reloadTable, }); }); @@ -377,16 +387,26 @@ function setupCallbacks() { var pk = $(this).attr('pk'); - launchModalForm(`/order/sales-order/line/${pk}/edit/`, { - success: reloadTable, + constructForm(`/api/order/so-line/${pk}/`, { + fields: { + quantity: {}, + reference: {}, + sale_price: {}, + sale_price_currency: {}, + notes: {}, + }, + title: '{% trans "Edit Line Item" %}', + onSuccess: reloadTable, }); }); table.find(".button-delete").click(function() { var pk = $(this).attr('pk'); - launchModalForm(`/order/sales-order/line/${pk}/delete/`, { - success: reloadTable, + constructForm(`/api/order/so-line/${pk}/`, { + method: 'DELETE', + title: '{% trans "Delete Line Item" %}', + onSuccess: reloadTable, }); }); diff --git a/InvenTree/order/templates/order/sales_orders.html b/InvenTree/order/templates/order/sales_orders.html index 448ab4b095..d4ebbd4ca8 100644 --- a/InvenTree/order/templates/order/sales_orders.html +++ b/InvenTree/order/templates/order/sales_orders.html @@ -178,19 +178,7 @@ $("#order-print").click(function() { }) $("#so-create").click(function() { - launchModalForm("{% url 'so-create' %}", - { - follow: true, - secondary: [ - { - field: 'customer', - label: '{% trans "New Customer" %}', - title: '{% trans "Create new Customer" %}', - url: '{% url "customer-create" %}', - } - ] - } - ); + createSalesOrder(); }); {% endblock %} \ No newline at end of file diff --git a/InvenTree/order/templates/order/so_attachments.html b/InvenTree/order/templates/order/so_attachments.html index b868aea48e..9c29fe5abe 100644 --- a/InvenTree/order/templates/order/so_attachments.html +++ b/InvenTree/order/templates/order/so_attachments.html @@ -23,7 +23,7 @@ enableDragAndDrop( '#attachment-dropzone', - "{% url 'so-attachment-create' %}", + '{% url "api-so-attachment-list" %}', { data: { order: {{ order.id }}, @@ -35,35 +35,49 @@ enableDragAndDrop( } ); -$("#new-attachment").click(function() { - launchModalForm("{% url 'so-attachment-create' %}?order={{ order.id }}", - { - reload: true, +loadAttachmentTable( + '{% url "api-so-attachment-list" %}', + { + filters: { + order: {{ order.pk }}, + }, + onEdit: function(pk) { + var url = `/api/order/so/attachment/${pk}/`; + + constructForm(url, { + fields: { + comment: {}, + }, + onSuccess: reloadAttachmentTable, + title: '{% trans "Edit Attachment" %}', + }); + }, + onDelete: function(pk) { + constructForm(`/api/order/so/attachment/${pk}/`, { + method: 'DELETE', + confirmMessage: '{% trans "Confirm Delete Operation" %}', + title: '{% trans "Delete Attachment" %}', + onSuccess: reloadAttachmentTable, + }); } - ); -}); + } +); -$("#attachment-table").on('click', '.attachment-edit-button', function() { - var button = $(this); +$("#new-attachment").click(function() { - var url = `/order/sales-order/attachment/${button.attr('pk')}/edit/`; - - launchModalForm(url, { - reload: true, + constructForm('{% url "api-so-attachment-list" %}', { + method: 'POST', + fields: { + attachment: {}, + comment: {}, + order: { + value: {{ order.pk }}, + hidden: true + } + }, + onSuccess: reloadAttachmentTable, + title: '{% trans "Add Attachment" %}' }); }); -$("#attachment-table").on('click', '.attachment-delete-button', function() { - var button = $(this); - - var url = `/order/sales-order/attachment/${button.attr('pk')}/delete/`; - - launchModalForm(url, { - reload: true, - }); -}); - -$("#attachment-table").inventreeTable({ -}); - {% endblock %} \ No newline at end of file diff --git a/InvenTree/order/templates/order/so_lineitem_delete.html b/InvenTree/order/templates/order/so_lineitem_delete.html deleted file mode 100644 index 1d9f80d137..0000000000 --- a/InvenTree/order/templates/order/so_lineitem_delete.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "modal_delete_form.html" %} -{% load i18n %} - -{% block pre_form_content %} -{% trans "Are you sure you wish to delete this line item?" %} -{% endblock %} \ No newline at end of file diff --git a/InvenTree/order/test_views.py b/InvenTree/order/test_views.py index 23122d079d..4b49b6c94e 100644 --- a/InvenTree/order/test_views.py +++ b/InvenTree/order/test_views.py @@ -11,7 +11,6 @@ from django.contrib.auth.models import Group from InvenTree.status_codes import PurchaseOrderStatus from .models import PurchaseOrder, PurchaseOrderLineItem -from .models import SalesOrder import json @@ -60,88 +59,6 @@ class OrderListTest(OrderViewTestCase): self.assertEqual(response.status_code, 200) -class SalesOrderCreate(OrderViewTestCase): - """ - Create a SalesOrder using the form view - """ - - URL = reverse('so-create') - - def test_create_view(self): - """ - Retrieve the view for creating a sales order' - """ - - response = self.client.get(self.URL, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - - self.assertEqual(response.status_code, 200) - - def post(self, data, **kwargs): - - return self.client.post(self.URL, data, HTTP_X_REQUESTED_WITH='XMLHttpRequest', **kwargs) - - def test_post_error(self): - """ - POST with errors - """ - - n = SalesOrder.objects.count() - - data = { - 'reference': '12345678', - } - - response = self.post(data) - - data = json.loads(response.content) - - self.assertIn('form_valid', data.keys()) - - # Customer is not specified - should return False - self.assertFalse(data['form_valid']) - - errors = json.loads(data['form_errors']) - - self.assertIn('customer', errors.keys()) - self.assertIn('description', errors.keys()) - - # No new SalesOrder objects should have been created - self.assertEqual(SalesOrder.objects.count(), n) - - def test_post_valid(self): - """ - POST a valid SalesOrder - """ - - n = SalesOrder.objects.count() - - data = { - 'reference': '12345678', - 'customer': 4, - 'description': 'A description', - } - - response = self.post(data) - - json_data = json.loads(response.content) - - self.assertTrue(json_data['form_valid']) - - # Create another SalesOrder, this time with a target date - data = { - 'reference': '12345679', - 'customer': 4, - 'description': 'Another order, this one with a target date!', - 'target_date': '2020-12-25', - } - - response = self.post(data) - - json_data = json.loads(response.content) - - self.assertEqual(SalesOrder.objects.count(), n + 2) - - class POTests(OrderViewTestCase): """ Tests for PurchaseOrder views """ @@ -152,28 +69,6 @@ class POTests(OrderViewTestCase): keys = response.context.keys() self.assertIn('PurchaseOrderStatus', keys) - def test_po_create(self): - """ Launch forms to create new PurchaseOrder""" - url = reverse('po-create') - - # Without a supplier ID - response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - - # With a valid supplier ID - response = self.client.get(url, {'supplier': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - - # With an invalid supplier ID - response = self.client.get(url, {'supplier': 'goat'}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - - def test_po_edit(self): - """ Launch form to edit a PurchaseOrder """ - - response = self.client.get(reverse('po-edit', args=(1,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - def test_po_export(self): """ Export PurchaseOrder """ @@ -209,65 +104,6 @@ class POTests(OrderViewTestCase): order = PurchaseOrder.objects.get(pk=1) self.assertEqual(order.status, PurchaseOrderStatus.PLACED) - def test_line_item_create(self): - """ Test the form for adding a new LineItem to a PurchaseOrder """ - - # Record the number of line items in the PurchaseOrder - po = PurchaseOrder.objects.get(pk=1) - n = po.lines.count() - self.assertEqual(po.status, PurchaseOrderStatus.PENDING) - - url = reverse('po-line-item-create') - - # GET the form (pass the correct info) - response = self.client.get(url, {'order': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - - post_data = { - 'part': 100, - 'quantity': 45, - 'reference': 'Test reference field', - 'notes': 'Test notes field' - } - - # POST with an invalid purchase order - post_data['order'] = 99 - response = self.client.post(url, post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - data = json.loads(response.content) - self.assertFalse(data['form_valid']) - - # POST with a part that does not match the purchase order - post_data['order'] = 1 - post_data['part'] = 7 - response = self.client.post(url, post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - data = json.loads(response.content) - self.assertFalse(data['form_valid']) - - # POST with an invalid part - post_data['part'] = 12345 - response = self.client.post(url, post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - data = json.loads(response.content) - self.assertFalse(data['form_valid']) - - # POST the form with valid data - post_data['part'] = 100 - response = self.client.post(url, post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - data = json.loads(response.content) - self.assertTrue(data['form_valid']) - - self.assertEqual(n + 1, PurchaseOrder.objects.get(pk=1).lines.count()) - - line = PurchaseOrderLineItem.objects.get(order=1, part=100) - self.assertEqual(line.quantity, 45) - - def test_line_item_edit(self): - """ Test editing form for PO line item """ - - url = reverse('po-line-item-edit', args=(22,)) - - response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - class TestPOReceive(OrderViewTestCase): """ Tests for receiving a purchase order """ diff --git a/InvenTree/order/tests.py b/InvenTree/order/tests.py index 5452aec383..b68e0c3ff1 100644 --- a/InvenTree/order/tests.py +++ b/InvenTree/order/tests.py @@ -60,12 +60,6 @@ class OrderTest(TestCase): order.save() self.assertFalse(order.is_overdue) - def test_increment(self): - - next_ref = PurchaseOrder.getNextOrderNumber() - - self.assertEqual(next_ref, '0008') - def test_on_order(self): """ There should be 3 separate items on order for the M2x4 LPHS part """ diff --git a/InvenTree/order/urls.py b/InvenTree/order/urls.py index 112a8cf297..16be6e77ce 100644 --- a/InvenTree/order/urls.py +++ b/InvenTree/order/urls.py @@ -12,7 +12,6 @@ from . import views purchase_order_detail_urls = [ url(r'^cancel/', views.PurchaseOrderCancel.as_view(), name='po-cancel'), - url(r'^edit/', views.PurchaseOrderEdit.as_view(), name='po-edit'), url(r'^issue/', views.PurchaseOrderIssue.as_view(), name='po-issue'), url(r'^receive/', views.PurchaseOrderReceive.as_view(), name='po-receive'), url(r'^complete/', views.PurchaseOrderComplete.as_view(), name='po-complete'), @@ -29,35 +28,17 @@ purchase_order_detail_urls = [ purchase_order_urls = [ - url(r'^new/', views.PurchaseOrderCreate.as_view(), name='po-create'), - url(r'^order-parts/', views.OrderParts.as_view(), name='order-parts'), url(r'^pricing/', views.LineItemPricing.as_view(), name='line-pricing'), # Display detail view for a single purchase order url(r'^(?P\d+)/', include(purchase_order_detail_urls)), - url(r'^line/', include([ - url(r'^new/', views.POLineItemCreate.as_view(), name='po-line-item-create'), - url(r'^(?P\d+)/', include([ - url(r'^edit/', views.POLineItemEdit.as_view(), name='po-line-item-edit'), - url(r'^delete/', views.POLineItemDelete.as_view(), name='po-line-item-delete'), - ])), - ])), - - url(r'^attachment/', include([ - url(r'^new/', views.PurchaseOrderAttachmentCreate.as_view(), name='po-attachment-create'), - url(r'^(?P\d+)/edit/', views.PurchaseOrderAttachmentEdit.as_view(), name='po-attachment-edit'), - url(r'^(?P\d+)/delete/', views.PurchaseOrderAttachmentDelete.as_view(), name='po-attachment-delete'), - ])), - # Display complete list of purchase orders url(r'^.*$', views.PurchaseOrderIndex.as_view(), name='po-index'), ] sales_order_detail_urls = [ - - url(r'^edit/', views.SalesOrderEdit.as_view(), name='so-edit'), url(r'^cancel/', views.SalesOrderCancel.as_view(), name='so-cancel'), url(r'^ship/', views.SalesOrderShip.as_view(), name='so-ship'), @@ -69,17 +50,6 @@ sales_order_detail_urls = [ ] sales_order_urls = [ - - url(r'^new/', views.SalesOrderCreate.as_view(), name='so-create'), - - url(r'^line/', include([ - url(r'^new/', views.SOLineItemCreate.as_view(), name='so-line-item-create'), - url(r'^(?P\d+)/', include([ - url(r'^edit/', views.SOLineItemEdit.as_view(), name='so-line-item-edit'), - url(r'^delete/', views.SOLineItemDelete.as_view(), name='so-line-item-delete'), - ])), - ])), - # URLs for sales order allocations url(r'^allocation/', include([ url(r'^new/', views.SalesOrderAllocationCreate.as_view(), name='so-allocation-create'), @@ -90,12 +60,6 @@ sales_order_urls = [ ])), ])), - url(r'^attachment/', include([ - url(r'^new/', views.SalesOrderAttachmentCreate.as_view(), name='so-attachment-create'), - url(r'^(?P\d+)/edit/', views.SalesOrderAttachmentEdit.as_view(), name='so-attachment-edit'), - url(r'^(?P\d+)/delete/', views.SalesOrderAttachmentDelete.as_view(), name='so-attachment-delete'), - ])), - # Display detail view for a single SalesOrder url(r'^(?P\d+)/', include(sales_order_detail_urls)), diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index 98f3384ca9..2ec06e600e 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -20,8 +20,8 @@ from django.forms import HiddenInput, IntegerField import logging from decimal import Decimal, InvalidOperation -from .models import PurchaseOrder, PurchaseOrderLineItem, PurchaseOrderAttachment -from .models import SalesOrder, SalesOrderLineItem, SalesOrderAttachment +from .models import PurchaseOrder, PurchaseOrderLineItem +from .models import SalesOrder, SalesOrderLineItem from .models import SalesOrderAllocation from .admin import POLineItemResource from build.models import Build @@ -42,7 +42,8 @@ from InvenTree.helpers import DownloadFile, str2bool from InvenTree.helpers import extract_serial_numbers from InvenTree.views import InvenTreeRoleMixin -from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus, StockStatus +from InvenTree.status_codes import PurchaseOrderStatus, StockStatus + logger = logging.getLogger("inventree") @@ -96,167 +97,6 @@ class SalesOrderDetail(InvenTreeRoleMixin, DetailView): template_name = 'order/sales_order_detail.html' -class PurchaseOrderAttachmentCreate(AjaxCreateView): - """ - View for creating a new PurchaseOrderAttachment - """ - - model = PurchaseOrderAttachment - form_class = order_forms.EditPurchaseOrderAttachmentForm - ajax_form_title = _("Add Purchase Order Attachment") - ajax_template_name = "modal_form.html" - - def save(self, form, **kwargs): - - attachment = form.save(commit=False) - attachment.user = self.request.user - attachment.save() - - def get_data(self): - return { - "success": _("Added attachment") - } - - def get_initial(self): - """ - Get initial data for creating a new PurchaseOrderAttachment object. - - - Client must request this form with a parent PurchaseOrder in midn. - - e.g. ?order= - """ - - initials = super(AjaxCreateView, self).get_initial() - - try: - initials["order"] = PurchaseOrder.objects.get(id=self.request.GET.get('order', -1)) - except (ValueError, PurchaseOrder.DoesNotExist): - pass - - return initials - - def get_form(self): - """ - Create a form to upload a new PurchaseOrderAttachment - - - Hide the 'order' field - """ - - form = super(AjaxCreateView, self).get_form() - - form.fields['order'].widget = HiddenInput() - - return form - - -class SalesOrderAttachmentCreate(AjaxCreateView): - """ View for creating a new SalesOrderAttachment """ - - model = SalesOrderAttachment - form_class = order_forms.EditSalesOrderAttachmentForm - ajax_form_title = _('Add Sales Order Attachment') - - def save(self, form, **kwargs): - """ - Save the user that uploaded the attachment - """ - - attachment = form.save(commit=False) - attachment.user = self.request.user - attachment.save() - - def get_data(self): - return { - 'success': _('Added attachment') - } - - def get_initial(self): - initials = super().get_initial().copy() - - try: - initials['order'] = SalesOrder.objects.get(id=self.request.GET.get('order', None)) - except (ValueError, SalesOrder.DoesNotExist): - pass - - return initials - - def get_form(self): - """ Hide the 'order' field """ - - form = super().get_form() - form.fields['order'].widget = HiddenInput() - - return form - - -class PurchaseOrderAttachmentEdit(AjaxUpdateView): - """ View for editing a PurchaseOrderAttachment object """ - - model = PurchaseOrderAttachment - form_class = order_forms.EditPurchaseOrderAttachmentForm - ajax_form_title = _("Edit Attachment") - - def get_data(self): - return { - 'success': _('Attachment updated') - } - - def get_form(self): - form = super(AjaxUpdateView, self).get_form() - - # Hide the 'order' field - form.fields['order'].widget = HiddenInput() - - return form - - -class SalesOrderAttachmentEdit(AjaxUpdateView): - """ View for editing a SalesOrderAttachment object """ - - model = SalesOrderAttachment - form_class = order_forms.EditSalesOrderAttachmentForm - ajax_form_title = _("Edit Attachment") - - def get_data(self): - return { - 'success': _('Attachment updated') - } - - def get_form(self): - form = super().get_form() - - form.fields['order'].widget = HiddenInput() - - return form - - -class PurchaseOrderAttachmentDelete(AjaxDeleteView): - """ View for deleting a PurchaseOrderAttachment """ - - model = PurchaseOrderAttachment - ajax_form_title = _("Delete Attachment") - ajax_template_name = "order/delete_attachment.html" - context_object_name = "attachment" - - def get_data(self): - return { - "danger": _("Deleted attachment") - } - - -class SalesOrderAttachmentDelete(AjaxDeleteView): - """ View for deleting a SalesOrderAttachment """ - - model = SalesOrderAttachment - ajax_form_title = _("Delete Attachment") - ajax_template_name = "order/delete_attachment.html" - context_object_name = "attachment" - - def get_data(self): - return { - "danger": _("Deleted attachment") - } - - class PurchaseOrderNotes(InvenTreeRoleMixin, UpdateView): """ View for updating the 'notes' field of a PurchaseOrder """ @@ -304,114 +144,6 @@ class SalesOrderNotes(InvenTreeRoleMixin, UpdateView): return ctx -class PurchaseOrderCreate(AjaxCreateView): - """ - View for creating a new PurchaseOrder object using a modal form - """ - - model = PurchaseOrder - ajax_form_title = _("Create Purchase Order") - form_class = order_forms.EditPurchaseOrderForm - - def get_initial(self): - initials = super().get_initial().copy() - - initials['reference'] = PurchaseOrder.getNextOrderNumber() - initials['status'] = PurchaseOrderStatus.PENDING - - supplier_id = self.request.GET.get('supplier', None) - - if supplier_id: - try: - supplier = Company.objects.get(id=supplier_id) - initials['supplier'] = supplier - except (Company.DoesNotExist, ValueError): - pass - - return initials - - def save(self, form, **kwargs): - """ - Record the user who created this PurchaseOrder - """ - - order = form.save(commit=False) - order.created_by = self.request.user - - return super().save(form) - - -class SalesOrderCreate(AjaxCreateView): - """ View for creating a new SalesOrder object """ - - model = SalesOrder - ajax_form_title = _("Create Sales Order") - form_class = order_forms.EditSalesOrderForm - - def get_initial(self): - initials = super().get_initial().copy() - - initials['reference'] = SalesOrder.getNextOrderNumber() - initials['status'] = SalesOrderStatus.PENDING - - customer_id = self.request.GET.get('customer', None) - - if customer_id is not None: - try: - customer = Company.objects.get(id=customer_id) - initials['customer'] = customer - except (Company.DoesNotExist, ValueError): - pass - - return initials - - def save(self, form, **kwargs): - """ - Record the user who created this SalesOrder - """ - - order = form.save(commit=False) - order.created_by = self.request.user - - return super().save(form) - - -class PurchaseOrderEdit(AjaxUpdateView): - """ View for editing a PurchaseOrder using a modal form """ - - model = PurchaseOrder - ajax_form_title = _('Edit Purchase Order') - form_class = order_forms.EditPurchaseOrderForm - - def get_form(self): - - form = super(AjaxUpdateView, self).get_form() - - order = self.get_object() - - # Prevent user from editing supplier if there are already lines in the order - if order.lines.count() > 0 or not order.status == PurchaseOrderStatus.PENDING: - form.fields['supplier'].widget = HiddenInput() - - return form - - -class SalesOrderEdit(AjaxUpdateView): - """ View for editing a SalesOrder """ - - model = SalesOrder - ajax_form_title = _('Edit Sales Order') - form_class = order_forms.EditSalesOrderForm - - def get_form(self): - form = super().get_form() - - # Prevent user from editing customer - form.fields['customer'].widget = HiddenInput() - - return form - - class PurchaseOrderCancel(AjaxUpdateView): """ View for cancelling a purchase order """ @@ -1317,214 +1049,6 @@ class OrderParts(AjaxView): order.add_line_item(supplier_part, quantity, purchase_price=purchase_price) -class POLineItemCreate(AjaxCreateView): - """ AJAX view for creating a new PurchaseOrderLineItem object - """ - - model = PurchaseOrderLineItem - context_object_name = 'line' - form_class = order_forms.EditPurchaseOrderLineItemForm - ajax_form_title = _('Add Line Item') - - def validate(self, item, form, **kwargs): - - order = form.cleaned_data.get('order', None) - - part = form.cleaned_data.get('part', None) - - if not part: - form.add_error('part', _('Supplier part must be specified')) - - if part and order: - if not part.supplier == order.supplier: - form.add_error( - 'part', - _('Supplier must match for Part and Order') - ) - - def get_form(self): - """ Limit choice options based on the selected order, etc - """ - - form = super().get_form() - - # Limit the available to orders to ones that are PENDING - query = form.fields['order'].queryset - query = query.filter(status=PurchaseOrderStatus.PENDING) - form.fields['order'].queryset = query - - order_id = form['order'].value() - - try: - order = PurchaseOrder.objects.get(id=order_id) - - query = form.fields['part'].queryset - - # Only allow parts from the selected supplier - query = query.filter(supplier=order.supplier.id) - - exclude = [] - - for line in order.lines.all(): - if line.part and line.part.id not in exclude: - exclude.append(line.part.id) - - # Remove parts that are already in the order - query = query.exclude(id__in=exclude) - - form.fields['part'].queryset = query - form.fields['order'].widget = HiddenInput() - except (ValueError, PurchaseOrder.DoesNotExist): - pass - - return form - - def get_initial(self): - """ Extract initial data for the line item. - - - The 'order' will be passed as a query parameter - - Use this to set the 'order' field and limit the options for 'part' - """ - - initials = super().get_initial().copy() - - order_id = self.request.GET.get('order', None) - - if order_id: - try: - order = PurchaseOrder.objects.get(id=order_id) - initials['order'] = order - - except (PurchaseOrder.DoesNotExist, ValueError): - pass - - return initials - - -class SOLineItemCreate(AjaxCreateView): - """ Ajax view for creating a new SalesOrderLineItem object """ - - model = SalesOrderLineItem - context_order_name = 'line' - form_class = order_forms.EditSalesOrderLineItemForm - ajax_form_title = _('Add Line Item') - - def get_form(self, *args, **kwargs): - - form = super().get_form(*args, **kwargs) - - # If the order is specified, hide the widget - order_id = form['order'].value() - - if SalesOrder.objects.filter(id=order_id).exists(): - form.fields['order'].widget = HiddenInput() - - return form - - def get_initial(self): - """ - Extract initial data for this line item: - - Options: - order: The SalesOrder object - part: The Part object - """ - - initials = super().get_initial().copy() - - order_id = self.request.GET.get('order', None) - part_id = self.request.GET.get('part', None) - - if order_id: - try: - order = SalesOrder.objects.get(id=order_id) - initials['order'] = order - except (SalesOrder.DoesNotExist, ValueError): - pass - - if part_id: - try: - part = Part.objects.get(id=part_id) - if part.salable: - initials['part'] = part - except (Part.DoesNotExist, ValueError): - pass - - return initials - - def save(self, form): - ret = form.save() - # check if price s set in form - else autoset - if not ret.sale_price: - price = ret.part.get_price(ret.quantity) - # only if price is avail - if price: - ret.sale_price = price / ret.quantity - ret.save() - self.object = ret - return ret - - -class SOLineItemEdit(AjaxUpdateView): - """ View for editing a SalesOrderLineItem """ - - model = SalesOrderLineItem - form_class = order_forms.EditSalesOrderLineItemForm - ajax_form_title = _('Edit Line Item') - - def get_form(self): - form = super().get_form() - - form.fields.pop('order') - form.fields.pop('part') - - return form - - -class POLineItemEdit(AjaxUpdateView): - """ View for editing a PurchaseOrderLineItem object in a modal form. - """ - - model = PurchaseOrderLineItem - form_class = order_forms.EditPurchaseOrderLineItemForm - ajax_template_name = 'modal_form.html' - ajax_form_title = _('Edit Line Item') - - def get_form(self): - form = super().get_form() - - # Prevent user from editing order once line item is assigned - form.fields['order'].widget = HiddenInput() - - return form - - -class POLineItemDelete(AjaxDeleteView): - """ View for deleting a PurchaseOrderLineItem object in a modal form - """ - - model = PurchaseOrderLineItem - ajax_form_title = _('Delete Line Item') - ajax_template_name = 'order/po_lineitem_delete.html' - - def get_data(self): - return { - 'danger': _('Deleted line item'), - } - - -class SOLineItemDelete(AjaxDeleteView): - - model = SalesOrderLineItem - ajax_form_title = _("Delete Line Item") - ajax_template_name = "order/so_lineitem_delete.html" - - def get_data(self): - return { - 'danger': _('Deleted line item'), - } - - class SalesOrderAssignSerials(AjaxView, FormMixin): """ View for assigning stock items to a sales order, diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 60cea121a7..337201c95f 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -127,7 +127,10 @@ class CategoryList(generics.ListCreateAPIView): class CategoryDetail(generics.RetrieveUpdateDestroyAPIView): - """ API endpoint for detail view of a single PartCategory object """ + """ + API endpoint for detail view of a single PartCategory object + """ + serializer_class = part_serializers.CategorySerializer queryset = PartCategory.objects.all() @@ -229,6 +232,24 @@ class PartAttachmentList(generics.ListCreateAPIView, AttachmentMixin): ] +class PartAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, AttachmentMixin): + """ + Detail endpoint for PartAttachment model + """ + + queryset = PartAttachment.objects.all() + serializer_class = part_serializers.PartAttachmentSerializer + + +class PartTestTemplateDetail(generics.RetrieveUpdateDestroyAPIView): + """ + Detail endpoint for PartTestTemplate model + """ + + queryset = PartTestTemplate.objects.all() + serializer_class = part_serializers.PartTestTemplateSerializer + + class PartTestTemplateList(generics.ListCreateAPIView): """ API endpoint for listing (and creating) a PartTestTemplate. @@ -337,8 +358,9 @@ class PartDetail(generics.RetrieveUpdateDestroyAPIView): def get_serializer(self, *args, **kwargs): + # By default, include 'category_detail' information in the detail view try: - kwargs['category_detail'] = str2bool(self.request.query_params.get('category_detail', False)) + kwargs['category_detail'] = str2bool(self.request.query_params.get('category_detail', True)) except AttributeError: pass @@ -651,6 +673,15 @@ class PartList(generics.ListCreateAPIView): # Filter items which have an 'in_stock' level higher than 'minimum_stock' queryset = queryset.filter(Q(in_stock__gte=F('minimum_stock'))) + # Filer by 'depleted_stock' status -> has no stock and stock items + depleted_stock = params.get('depleted_stock', None) + + if depleted_stock is not None: + depleted_stock = str2bool(depleted_stock) + + if depleted_stock: + queryset = queryset.filter(Q(in_stock=0) & ~Q(stock_item_count=0)) + # Filter by "parts which need stock to complete build" stock_to_build = params.get('stock_to_build', None) @@ -1023,11 +1054,13 @@ part_api_urls = [ # Base URL for PartTestTemplate API endpoints url(r'^test-template/', include([ + url(r'^(?P\d+)/', PartTestTemplateDetail.as_view(), name='api-part-test-template-detail'), url(r'^$', PartTestTemplateList.as_view(), name='api-part-test-template-list'), ])), # Base URL for PartAttachment API endpoints url(r'^attachment/', include([ + url(r'^(?P\d+)/', PartAttachmentDetail.as_view(), name='api-part-attachment-detail'), url(r'^$', PartAttachmentList.as_view(), name='api-part-attachment-list'), ])), diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index ec799bcf8d..36a49006b0 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -5,21 +5,21 @@ Django Forms for interacting with Part objects # -*- coding: utf-8 -*- from __future__ import unicode_literals +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from mptt.fields import TreeNodeChoiceField + from InvenTree.forms import HelperForm from InvenTree.helpers import GetExportFormats from InvenTree.fields import RoundingDecimalFormField -from mptt.fields import TreeNodeChoiceField -from django import forms -from django.utils.translation import ugettext_lazy as _ - import common.models -from .models import Part, PartCategory, PartAttachment, PartRelated +from .models import Part, PartCategory, PartRelated from .models import BomItem from .models import PartParameterTemplate, PartParameter from .models import PartCategoryParameterTemplate -from .models import PartTestTemplate from .models import PartSellPriceBreak, PartInternalPriceBreak @@ -65,22 +65,6 @@ class PartImageForm(HelperForm): ] -class EditPartTestTemplateForm(HelperForm): - """ Class for creating / editing a PartTestTemplate object """ - - class Meta: - model = PartTestTemplate - - fields = [ - 'part', - 'test_name', - 'description', - 'required', - 'requires_value', - 'requires_attachment', - ] - - class BomExportForm(forms.Form): """ Simple form to let user set BOM export options, before exporting a BOM (bill of materials) file. @@ -185,18 +169,6 @@ class CreatePartRelatedForm(HelperForm): } -class EditPartAttachmentForm(HelperForm): - """ Form for editing a PartAttachment object """ - - class Meta: - model = PartAttachment - fields = [ - 'part', - 'attachment', - 'comment' - ] - - class SetPartCategoryForm(forms.Form): """ Form for setting the category of multiple Part objects """ diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 9f4da436df..b69177c05b 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -75,6 +75,10 @@ class PartCategory(InvenTreeTree): default_keywords = models.CharField(null=True, blank=True, max_length=250, verbose_name=_('Default keywords'), help_text=_('Default keywords for parts in this category')) + @staticmethod + def get_api_url(): + return reverse('api-part-category-list') + def get_absolute_url(self): return reverse('category-detail', kwargs={'pk': self.id}) @@ -329,6 +333,11 @@ class Part(MPTTModel): # For legacy reasons the 'variant_of' field is used to indicate the MPTT parent parent_attr = 'variant_of' + @staticmethod + def get_api_url(): + + return reverse('api-part-list') + def get_context_data(self, request, **kwargs): """ Return some useful context data about this part for template rendering @@ -1968,6 +1977,10 @@ class PartAttachment(InvenTreeAttachment): Model for storing file attachments against a Part object """ + @staticmethod + def get_api_url(): + return reverse('api-part-attachment-list') + def getSubdir(self): return os.path.join("part_files", str(self.part.id)) @@ -1979,6 +1992,10 @@ class PartSellPriceBreak(common.models.PriceBreak): """ Represents a price break for selling this part """ + + @staticmethod + def get_api_url(): + return reverse('api-part-sale-price-list') part = models.ForeignKey( Part, on_delete=models.CASCADE, @@ -1996,6 +2013,10 @@ class PartInternalPriceBreak(common.models.PriceBreak): Represents a price break for internally selling this part """ + @staticmethod + def get_api_url(): + return reverse('api-part-internal-price-list') + part = models.ForeignKey( Part, on_delete=models.CASCADE, related_name='internalpricebreaks', @@ -2040,6 +2061,10 @@ class PartTestTemplate(models.Model): run on the model (refer to the validate_unique function). """ + @staticmethod + def get_api_url(): + return reverse('api-part-test-template-list') + def save(self, *args, **kwargs): self.clean() @@ -2138,6 +2163,10 @@ class PartParameterTemplate(models.Model): units: The units of the Parameter [string] """ + @staticmethod + def get_api_url(): + return reverse('api-part-param-template-list') + def __str__(self): s = str(self.name) if self.units: @@ -2175,6 +2204,10 @@ class PartParameter(models.Model): data: The data (value) of the Parameter [string] """ + @staticmethod + def get_api_url(): + return reverse('api-part-param-list') + def __str__(self): # String representation of a PartParameter (used in the admin interface) return "{part} : {param} = {data}{units}".format( @@ -2266,6 +2299,10 @@ class BomItem(models.Model): allow_variants: Stock for part variants can be substituted for this BomItem """ + @staticmethod + def get_api_url(): + return reverse('api-bom-list') + def save(self, *args, **kwargs): self.clean() diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index 2da2d05d3b..313e2cf920 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -4,6 +4,7 @@ JSON serializers for Part app import imghdr from decimal import Decimal +from django.urls import reverse_lazy from django.db import models from django.db.models import Q from django.db.models.functions import Coalesce @@ -38,6 +39,7 @@ class CategorySerializer(InvenTreeModelSerializer): 'name', 'description', 'default_location', + 'default_keywords', 'pathstring', 'url', 'parent', @@ -59,7 +61,12 @@ class PartAttachmentSerializer(InvenTreeModelSerializer): 'pk', 'part', 'attachment', - 'comment' + 'comment', + 'upload_date', + ] + + read_only_fields = [ + 'upload_date', ] @@ -187,6 +194,9 @@ class PartSerializer(InvenTreeModelSerializer): Used when displaying all details of a single component. """ + def get_api_url(self): + return reverse_lazy('api-part-list') + def __init__(self, *args, **kwargs): """ Custom initialization method for PartSerializer, @@ -326,9 +336,10 @@ class PartSerializer(InvenTreeModelSerializer): 'category', 'category_detail', 'component', - 'description', - 'default_location', 'default_expiry', + 'default_location', + 'default_supplier', + 'description', 'full_name', 'image', 'in_stock', diff --git a/InvenTree/part/templates/part/attachments.html b/InvenTree/part/templates/part/attachments.html index 93440e13ed..7128980472 100644 --- a/InvenTree/part/templates/part/attachments.html +++ b/InvenTree/part/templates/part/attachments.html @@ -19,51 +19,68 @@ {% block js_ready %} {{ block.super }} + loadAttachmentTable( + '{% url "api-part-attachment-list" %}', + { + filters: { + part: {{ part.pk }}, + }, + onEdit: function(pk) { + var url = `/api/part/attachment/${pk}/`; + + constructForm(url, { + fields: { + comment: {}, + }, + title: '{% trans "Edit Attachment" %}', + onSuccess: reloadAttachmentTable, + }); + }, + onDelete: function(pk) { + var url = `/api/part/attachment/${pk}/`; + + constructForm(url, { + method: 'DELETE', + confirmMessage: '{% trans "Confirm Delete Operation" %}', + title: '{% trans "Delete Attachment" %}', + onSuccess: reloadAttachmentTable, + }); + } + } + ); + enableDragAndDrop( '#attachment-dropzone', - "{% url 'part-attachment-create' %}", + '{% url "api-part-attachment-list" %}', { data: { part: {{ part.id }}, }, label: 'attachment', success: function(data, status, xhr) { - location.reload(); + reloadAttachmentTable(); } } ); $("#new-attachment").click(function() { - launchModalForm("{% url 'part-attachment-create' %}?part={{ part.id }}", + + constructForm( + '{% url "api-part-attachment-list" %}', { - reload: true, - }); - }); - - $("#attachment-table").on('click', '.attachment-edit-button', function() { - var button = $(this); - - var url = `/part/attachment/${button.attr('pk')}/edit/`; - - launchModalForm(url, - { - reload: true, - }); - }); - - $("#attachment-table").on('click', '.attachment-delete-button', function() { - var button = $(this); - - var url = `/part/attachment/${button.attr('pk')}/delete/`; - - launchModalForm(url, { - success: function() { - location.reload(); + method: 'POST', + fields: { + attachment: {}, + comment: {}, + part: { + value: {{ part.pk }}, + hidden: true, + } + }, + onSuccess: reloadAttachmentTable, + title: '{% trans "Add Attachment" %}', } - }); - }); - - $("#attachment-table").inventreeTable({ + ) }); {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/bom-delete.html b/InvenTree/part/templates/part/bom-delete.html deleted file mode 100644 index c2db77c040..0000000000 --- a/InvenTree/part/templates/part/bom-delete.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "modal_delete_form.html" %} -{% load i18n %} - -{% block pre_form_content %} - -{% trans "Are you sure you want to delete this BOM item?" %} -
                  -{% trans "Deleting this entry will remove the BOM row from the following part" %}: - -
                    -
                  • - {{ item.part.full_name }} - {{ item.part.description }} -
                  • -
                  - -{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/bom.html b/InvenTree/part/templates/part/bom.html index dc345f9737..ba3e9be2b9 100644 --- a/InvenTree/part/templates/part/bom.html +++ b/InvenTree/part/templates/part/bom.html @@ -124,7 +124,7 @@ // Wait for *all* the requests to complete $.when.apply($, requests).then(function() { - $('#bom-table').bootstrapTable('refresh'); + location.reload(); }); } } diff --git a/InvenTree/part/templates/part/category.html b/InvenTree/part/templates/part/category.html index ef250d4c89..cf7348be76 100644 --- a/InvenTree/part/templates/part/category.html +++ b/InvenTree/part/templates/part/category.html @@ -268,13 +268,25 @@ {% if category %} $("#cat-edit").click(function () { - launchModalForm( - "{% url 'category-edit' category.id %}", + + constructForm( + '{% url "api-part-category-detail" category.pk %}', { + fields: { + name: {}, + description: {}, + parent: { + help_text: '{% trans "Select parent category" %}', + }, + default_location: {}, + default_keywords: { + icon: 'fa-key', + } + }, + title: '{% trans "Edit Part Category" %}', reload: true - }, + } ); - return false; }); {% if category.parent %} diff --git a/InvenTree/part/templates/part/internal_prices.html b/InvenTree/part/templates/part/internal_prices.html deleted file mode 100644 index 2f54f3bb64..0000000000 --- a/InvenTree/part/templates/part/internal_prices.html +++ /dev/null @@ -1,122 +0,0 @@ -{% extends "part/part_base.html" %} -{% load static %} -{% load i18n %} -{% load inventree_extras %} - -{% block menubar %} -{% include 'part/navbar.html' with tab='internal-prices' %} -{% endblock %} - -{% block heading %} -{% trans "Internal Price Information" %} -{% endblock %} - -{% block details %} -{% settings_value "PART_INTERNAL_PRICE" as show_internal_price %} -{% if show_internal_price and roles.sales_order.view %} -
                  - -
                  - - -
                  - -{% else %} -
                  -

                  {% trans "Permission Denied" %}

                  - -
                  - {% trans "You do not have permission to view this page." %} -
                  -
                  -{% endif %} -{% endblock %} - -{% block js_ready %} -{{ block.super }} - -{% settings_value "PART_INTERNAL_PRICE" as show_internal_price %} -{% if show_internal_price and roles.sales_order.view %} -function reloadPriceBreaks() { - $("#internal-price-break-table").bootstrapTable("refresh"); -} - -$('#new-internal-price-break').click(function() { - launchModalForm("{% url 'internal-price-break-create' %}", - { - success: reloadPriceBreaks, - data: { - part: {{ part.id }}, - } - } - ); -}); - -$('#internal-price-break-table').inventreeTable({ - name: 'internalprice', - formatNoMatches: function() { return "{% trans 'No internal price break information found' %}"; }, - queryParams: { - part: {{ part.id }}, - }, - url: "{% url 'api-part-internal-price-list' %}", - onPostBody: function() { - var table = $('#internal-price-break-table'); - - table.find('.button-internal-price-break-delete').click(function() { - var pk = $(this).attr('pk'); - - launchModalForm( - `/part/internal-price/${pk}/delete/`, - { - success: reloadPriceBreaks - } - ); - }); - - table.find('.button-internal-price-break-edit').click(function() { - var pk = $(this).attr('pk'); - - launchModalForm( - `/part/internal-price/${pk}/edit/`, - { - success: reloadPriceBreaks - } - ); - }); - }, - columns: [ - { - field: 'pk', - title: 'ID', - visible: false, - switchable: false, - }, - { - field: 'quantity', - title: '{% trans "Quantity" %}', - sortable: true, - }, - { - field: 'price', - title: '{% trans "Price" %}', - sortable: true, - formatter: function(value, row, index) { - var html = value; - - html += `
                  ` - - html += makeIconButton('fa-edit icon-blue', 'button-internal-price-break-edit', row.pk, '{% trans "Edit internal price break" %}'); - html += makeIconButton('fa-trash-alt icon-red', 'button-internal-price-break-delete', row.pk, '{% trans "Delete internal price break" %}'); - - html += `
                  `; - - return html; - } - }, - ] -}) - -{% endif %} -{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/manufacturer.html b/InvenTree/part/templates/part/manufacturer.html index 82f02ba85f..ba708d70e8 100644 --- a/InvenTree/part/templates/part/manufacturer.html +++ b/InvenTree/part/templates/part/manufacturer.html @@ -51,7 +51,6 @@ field: 'manufacturer', label: '{% trans "New Manufacturer" %}', title: '{% trans "Create new manufacturer" %}', - url: "{% url 'manufacturer-create' %}", } ] }); @@ -61,17 +60,10 @@ var selections = $("#manufacturer-table").bootstrapTable("getSelections"); - var parts = []; - - selections.forEach(function(item) { - parts.push(item.pk); - }); - - launchModalForm("{% url 'manufacturer-part-delete' %}", { - data: { - parts: parts, - }, - reload: true, + deleteManufacturerParts(selections, { + onSuccess: function() { + $("#manufacturer-table").bootstrapTable("refresh"); + } }); }); @@ -81,7 +73,7 @@ { params: { part: {{ part.id }}, - part_detail: false, + part_detail: true, manufacturer_detail: true, }, } diff --git a/InvenTree/part/templates/part/navbar.html b/InvenTree/part/templates/part/navbar.html index 1fae6aaec2..b4c943dcfa 100644 --- a/InvenTree/part/templates/part/navbar.html +++ b/InvenTree/part/templates/part/navbar.html @@ -71,13 +71,13 @@ {% endif %} - {% if part.purchaseable and roles.purchase_order.view %} -
                • - +
                • + - {% trans "Order Price" %} + {% trans "Prices" %}
                • + {% if part.purchaseable and roles.purchase_order.view %}
                • @@ -97,19 +97,7 @@
                • {% endif %} - {% if show_internal_price and roles.sales_order.view %} -
                • - - - {% trans "Internal Price" %} - -
                • -
                • - - - {% trans "Sale Price" %} - -
                • + {% if roles.sales_order.view %}
                • diff --git a/InvenTree/part/templates/part/order_prices.html b/InvenTree/part/templates/part/order_prices.html deleted file mode 100644 index c8f0ea29a0..0000000000 --- a/InvenTree/part/templates/part/order_prices.html +++ /dev/null @@ -1,236 +0,0 @@ -{% extends "part/part_base.html" %} -{% load static %} -{% load i18n %} -{% load crispy_forms_tags %} -{% load inventree_extras %} - -{% block menubar %} -{% include 'part/navbar.html' with tab='order-prices' %} -{% endblock %} - -{% block heading %} -{% trans "Order Price Information" %} -{% endblock %} - -{% block details %} -{% default_currency as currency %} -{% settings_value "PART_INTERNAL_PRICE" as show_internal_price %} - - -
                  - {% csrf_token %} -
                  -
                  {{ form|crispy }}
                  -
                  - -
                  -
                  -
                  -
                  - -
                  -

                  {% trans "Pricing ranges" %}

                  - -{% if part.supplier_count > 0 %} - {% if min_total_buy_price %} - - - - - - - {% if quantity > 1 %} - - - - - - - {% endif %} - {% else %} - - - - {% endif %} -{% endif %} - -{% if part.bom_count > 0 %} - {% if min_total_bom_price %} - - - - - - - {% if quantity > 1 %} - - - - - - - {% endif %} - {% if part.has_complete_bom_pricing == False %} - - - - {% endif %} - {% else %} - - - - {% endif %} -{% endif %} - -{% if show_internal_price and roles.sales_order.view %} -{% if total_internal_part_price %} - - - - - - - - - - -{% endif %} -{% endif %} - -{% if total_part_price %} - - - - - - - - - - -{% endif %} -
                  {% trans 'Supplier Pricing' %}{% trans 'Unit Cost' %}Min: {% include "price.html" with price=min_unit_buy_price %}Max: {% include "price.html" with price=max_unit_buy_price %}
                  {% trans 'Total Cost' %}Min: {% include "price.html" with price=min_total_buy_price %}Max: {% include "price.html" with price=max_total_buy_price %}
                  - {% trans 'No supplier pricing available' %} -
                  {% trans 'BOM Pricing' %}{% trans 'Unit Cost' %}Min: {% include "price.html" with price=min_unit_bom_price %}Max: {% include "price.html" with price=max_unit_bom_price %}
                  {% trans 'Total Cost' %}Min: {% include "price.html" with price=min_total_bom_price %}Max: {% include "price.html" with price=max_total_bom_price %}
                  - {% trans 'Note: BOM pricing is incomplete for this part' %} -
                  - {% trans 'No BOM pricing available' %} -
                  {% trans 'Internal Price' %}{% trans 'Unit Cost' %}{% include "price.html" with price=unit_internal_part_price %}
                  {% trans 'Total Cost' %}{% include "price.html" with price=total_internal_part_price %}
                  {% trans 'Sale Price' %}{% trans 'Unit Cost' %}{% include "price.html" with price=unit_part_price %}
                  {% trans 'Total Cost' %}{% include "price.html" with price=total_part_price %}
                  - -{% if min_unit_buy_price or min_unit_bom_price %} -{% else %} -
                  - {% trans 'No pricing information is available for this part.' %} -
                  -{% endif %} -
                  -{% if part.bom_count > 0 %} -
                  -

                  {% trans 'BOM Pricing' %}

                  -
                  - -
                  -
                  -{% endif %} -
                  - -{% if price_history %} -
                  -

                  {% trans 'Stock Pricing' %}

                  - {% if price_history|length > 0 %} -
                  - -
                  - {% else %} -
                  - {% trans 'No stock pricing history is available for this part.' %} -
                  - {% endif %} -{% endif %} -{% endblock %} - - - - -{% block js_ready %} - {{ block.super }} - - {% default_currency as currency %} - {% if price_history %} - var pricedata = { - labels: [ - {% for line in price_history %}'{{ line.date }}',{% endfor %} - ], - datasets: [{ - label: '{% blocktrans %}Single Price - {{currency}}{% endblocktrans %}', - backgroundColor: 'rgba(255, 99, 132, 0.2)', - borderColor: 'rgb(255, 99, 132)', - yAxisID: 'y', - data: [ - {% for line in price_history %}{{ line.price|stringformat:".2f" }},{% endfor %} - ], - borderWidth: 1, - type: 'line' - }, - {% if 'price_diff' in price_history.0 %} - { - label: '{% blocktrans %}Single Price Difference - {{currency}}{% endblocktrans %}', - backgroundColor: 'rgba(68, 157, 68, 0.2)', - borderColor: 'rgb(68, 157, 68)', - yAxisID: 'y2', - data: [ - {% for line in price_history %}{{ line.price_diff|stringformat:".2f" }},{% endfor %} - ], - borderWidth: 1, - type: 'line', - hidden: true, - }, - { - label: '{% blocktrans %}Part Single Price - {{currency}}{% endblocktrans %}', - backgroundColor: 'rgba(70, 127, 155, 0.2)', - borderColor: 'rgb(70, 127, 155)', - yAxisID: 'y', - data: [ - {% for line in price_history %}{{ line.price_part|stringformat:".2f" }},{% endfor %} - ], - borderWidth: 1, - type: 'line', - hidden: true, - }, - {% endif %} - { - label: '{% trans "Quantity" %}', - backgroundColor: 'rgba(255, 206, 86, 0.2)', - borderColor: 'rgb(255, 206, 86)', - yAxisID: 'y1', - data: [ - {% for line in price_history %}{{ line.qty|stringformat:"f" }},{% endfor %} - ], - borderWidth: 1 - }] - } - var StockPriceChart = loadStockPricingChart(document.getElementById('StockPriceChart'), pricedata) - var bom_colors = randomColor({hue: 'green', count: {{ bom_parts|length }} }) - var bomdata = { - labels: [{% for line in bom_parts %}'{{ line.name }}',{% endfor %}], - datasets: [ - { - label: 'Price', - data: [{% for line in bom_parts %}{{ line.min_price }},{% endfor %}], - backgroundColor: bom_colors, - }, - {% if bom_pie_max %} - { - label: 'Max Price', - data: [{% for line in bom_parts %}{{ line.max_price }},{% endfor %}], - backgroundColor: bom_colors, - }, - {% endif %} - ] - }; - var BomChart = loadBomChart(document.getElementById('BomChart'), bomdata) - - {% endif %} - -{% endblock %} diff --git a/InvenTree/part/templates/part/part_base.html b/InvenTree/part/templates/part/part_base.html index b486e2c589..ee9d541762 100644 --- a/InvenTree/part/templates/part/part_base.html +++ b/InvenTree/part/templates/part/part_base.html @@ -237,6 +237,16 @@ }); {% endif %} + function reloadImage(data) { + // If image / thumbnail data present, live update + if (data.image) { + $('#part-image').attr('src', data.image); + } else { + // Otherwise, reload the page + location.reload(); + } + } + enableDragAndDrop( '#part-thumb', "{% url 'api-part-detail' part.id %}", @@ -244,14 +254,7 @@ label: 'image', method: 'PATCH', success: function(data, status, xhr) { - - // If image / thumbnail data present, live update - if (data.image) { - $('#part-image').attr('src', data.image); - } else { - // Otherwise, reload the page - location.reload(); - } + reloadImage(data); } } ); @@ -293,11 +296,20 @@ }); $("#part-image-upload").click(function() { - launchModalForm("{% url 'part-image-upload' part.id %}", + + constructForm( + '{% url "api-part-detail" part.pk %}', { - reload: true + method: 'PATCH', + fields: { + image: {}, + }, + title: '{% trans "Upload Image" %}', + onSuccess: function(data) { + reloadImage(data); + } } - ); + ) }); @@ -357,6 +369,75 @@ }); $("#part-edit").click(function() { + + constructForm('{% url "api-part-detail" part.id %}', { + focus: 'name', + fields: { + category: { + secondary: { + label: '{% trans "New Category" %}', + title: '{% trans "Create New Part Category" %}', + api_url: '{% url "api-part-category-list" %}', + method: 'POST', + fields: { + name: {}, + description: {}, + parent: { + secondary: { + title: '{% trans "New Parent" %}', + api_url: '{% url "api-part-category-list" %}', + method: 'POST', + fields: { + name: {}, + description: {}, + parent: {}, + } + } + }, + } + }, + }, + name: { + placeholder: 'part name', + }, + IPN: {}, + description: {}, + revision: {}, + keywords: { + icon: 'fa-key', + }, + variant_of: {}, + link: { + icon: 'fa-link', + }, + default_location: { + secondary: { + label: '{% trans "New Location" %}', + title: '{% trans "Create new stock location" %}', + + }, + }, + default_supplier: { + filters: { + part: {{ part.pk }}, + part_detail: true, + manufacturer_detail: true, + supplier_detail: true, + }, + secondary: { + label: '{% trans "New Supplier Part" %}', + title: '{% trans "Create new supplier part" %}', + } + }, + units: {}, + minimum_stock: {}, + }, + title: '{% trans "Edit Part" %}', + reload: true, + }); + + return; + launchModalForm( "{% url 'part-edit' part.id %}", { diff --git a/InvenTree/part/templates/part/part_tests.html b/InvenTree/part/templates/part/part_tests.html index dbd439afdb..3c131aa1d4 100644 --- a/InvenTree/part/templates/part/part_tests.html +++ b/InvenTree/part/templates/part/part_tests.html @@ -44,34 +44,52 @@ function reloadTable() { } $("#add-test-template").click(function() { - launchModalForm( - "{% url 'part-test-template-create' %}", - { - data: { - part: {{ part.id }}, - }, - success: reloadTable, - } - ); + + constructForm('{% url "api-part-test-template-list" %}', { + method: 'POST', + fields: { + test_name: {}, + description: {}, + required: {}, + requires_value: {}, + requires_attachment: {}, + part: { + value: {{ part.pk }}, + hidden: true, + } + }, + title: '{% trans "Add Test Result Template" %}', + onSuccess: reloadTable + }); }); $("#test-template-table").on('click', '.button-test-edit', function() { - var button = $(this); + var pk = $(this).attr('pk'); - var url = `/part/test-template/${button.attr('pk')}/edit/`; + var url = `/api/part/test-template/${pk}/`; - launchModalForm(url, { - success: reloadTable, + constructForm(url, { + fields: { + test_name: {}, + description: {}, + required: {}, + requires_value: {}, + requires_attachment: {}, + }, + title: '{% trans "Edit Test Result Template" %}', + onSuccess: reloadTable, }); }); $("#test-template-table").on('click', '.button-test-delete', function() { - var button = $(this); + var pk = $(this).attr('pk'); - var url = `/part/test-template/${button.attr('pk')}/delete/`; + var url = `/api/part/test-template/${pk}/`; - launchModalForm(url, { - success: reloadTable, + constructForm(url, { + method: 'DELETE', + title: '{% trans "Delete Test Result Template" %}', + onSuccess: reloadTable, }); }); diff --git a/InvenTree/part/templates/part/prices.html b/InvenTree/part/templates/part/prices.html new file mode 100644 index 0000000000..6e234d3dba --- /dev/null +++ b/InvenTree/part/templates/part/prices.html @@ -0,0 +1,488 @@ +{% extends "part/part_base.html" %} +{% load static %} +{% load i18n %} +{% load crispy_forms_tags %} +{% load inventree_extras %} + +{% block menubar %} +{% include 'part/navbar.html' with tab='prices' %} +{% endblock %} + +{% block heading %} +{% trans "General Price Information" %} +{% endblock %} + + +{% block details %} +{% default_currency as currency %} + +
                  + +
                  +

                  {% trans "Pricing ranges" %}

                  + + {% if part.supplier_count > 0 %} + {% if min_total_buy_price %} + + + + + + + {% if quantity > 1 %} + + + + + + + {% endif %} + {% else %} + + + + {% endif %} + {% endif %} + + {% if part.bom_count > 0 %} + {% if min_total_bom_price %} + + + + + + + {% if quantity > 1 %} + + + + + + + {% endif %} + {% if part.has_complete_bom_pricing == False %} + + + + {% endif %} + {% else %} + + + + {% endif %} + {% endif %} + + {% if show_internal_price and roles.sales_order.view %} + {% if total_internal_part_price %} + + + + + + + + + + + {% endif %} + {% endif %} + + {% if total_part_price %} + + + + + + + + + + + {% endif %} +
                  {% trans 'Supplier Pricing' %} + + + {% trans 'Unit Cost' %}Min: {% include "price.html" with price=min_unit_buy_price %}Max: {% include "price.html" with price=max_unit_buy_price %}
                  {% trans 'Total Cost' %}Min: {% include "price.html" with price=min_total_buy_price %}Max: {% include "price.html" with price=max_total_buy_price %}
                  + {% trans 'No supplier pricing available' %} +
                  {% trans 'BOM Pricing' %} + + {% trans 'Unit Cost' %}Min: {% include "price.html" with price=min_unit_bom_price %}Max: {% include "price.html" with price=max_unit_bom_price %}
                  {% trans 'Total Cost' %}Min: {% include "price.html" with price=min_total_bom_price %}Max: {% include "price.html" with price=max_total_bom_price %}
                  + {% trans 'Note: BOM pricing is incomplete for this part' %} +
                  + {% trans 'No BOM pricing available' %} +
                  {% trans 'Internal Price' %}{% trans 'Unit Cost' %}{% include "price.html" with price=unit_internal_part_price %}
                  {% trans 'Total Cost' %}{% include "price.html" with price=total_internal_part_price %}
                  {% trans 'Sale Price' %} + + + {% trans 'Unit Cost' %}{% include "price.html" with price=unit_part_price %}
                  {% trans 'Total Cost' %}{% include "price.html" with price=total_part_price %}
                  + + {% if min_unit_buy_price or min_unit_bom_price %} + {% else %} +
                  + {% trans 'No pricing information is available for this part.' %} +
                  + {% endif %} +
                  + +
                  +

                  {% trans "Calculation parameters" %}

                  +
                  + {% csrf_token %} + {{ form|crispy }} + +
                  +
                  +
                  +{% endblock %} + +{% block post_content_panel %} +{% default_currency as currency %} +{% settings_value "PART_INTERNAL_PRICE" as show_internal_price %} + + +{% if part.purchaseable and roles.purchase_order.view %} +
                  + +
                  +

                  {% trans "Supplier Cost" %} + +

                  +
                  + +
                  +
                  +

                  {% trans "Suppliers" %}

                  +
                  +
                  +
                  +

                  {% trans "Manufacturers" %}

                  +
                  +
                  +
                  +
                  + +
                  + +
                  +

                  {% trans "Purchase Price" %} + +

                  +
                  + + {% if price_history %} +

                  {% trans 'Stock Pricing' %}

                  + {% if price_history|length > 0 %} +
                  + +
                  + {% else %} +
                  + {% trans 'No stock pricing history is available for this part.' %} +
                  + {% endif %} + {% endif %} +
                  +{% endif %} + + +{% if show_internal_price and roles.sales_order.view %} +
                  + +
                  +

                  {% trans "Internal Cost" %} + +

                  +
                  + +
                  +
                  +
                  + +
                  +
                  +
                  +
                  + +
                  + + +
                  +
                  +
                  +
                  +{% endif %} + + +{% if part.has_bom and roles.sales_order.view %} +
                  + +
                  +

                  {% trans "BOM Cost" %} + +

                  +
                  + +
                  +
                  +
                  +
                  + + {% if part.bom_count > 0 %} +
                  +

                  {% trans 'BOM Pricing' %}

                  +
                  + +
                  +
                  + {% endif %} +
                  +
                  +{% endif %} + + +{% if part.salable and roles.sales_order.view %} +
                  + +
                  +

                  {% trans "Sale Cost" %} + +

                  +
                  + +
                  +
                  +
                  + +
                  +
                  +
                  +
                  + +
                  + + +
                  +
                  +
                  +
                  + +
                  + +
                  +

                  {% trans "Sale Price" %} + +

                  +
                  + +
                  + {% if sale_history|length > 0 %} +
                  + +
                  + {% else %} +
                  + {% trans 'No sale pice history available for this part.' %} +
                  + {% endif %} +
                  +
                  +{% endif %} + +{% endblock %} + + + +{% block js_ready %} + {{ block.super }} + + {% default_currency as currency %} + + + loadSupplierPartTable( + "#supplier-table", + "{% url 'api-supplier-part-list' %}", + { + params: { + part: {{ part.id }}, + part_detail: false, + supplier_detail: true, + manufacturer_detail: true, + }, + } + ); + + loadManufacturerPartTable( + "#manufacturer-table", + "{% url 'api-manufacturer-part-list' %}", + { + params: { + part: {{ part.id }}, + part_detail: false, + manufacturer_detail: true, + }, + } + ); + + + // history graphs + {% if price_history %} + var purchasepricedata = { + labels: [ + {% for line in price_history %}'{{ line.date }}',{% endfor %} + ], + datasets: [{ + label: '{% blocktrans %}Single Price - {{currency}}{% endblocktrans %}', + backgroundColor: 'rgba(255, 99, 132, 0.2)', + borderColor: 'rgb(255, 99, 132)', + yAxisID: 'y', + data: [ + {% for line in price_history %}{{ line.price|stringformat:".2f" }},{% endfor %} + ], + borderWidth: 1, + type: 'line' + }, + {% if 'price_diff' in price_history.0 %} + { + label: '{% blocktrans %}Single Price Difference - {{currency}}{% endblocktrans %}', + backgroundColor: 'rgba(68, 157, 68, 0.2)', + borderColor: 'rgb(68, 157, 68)', + yAxisID: 'y2', + data: [ + {% for line in price_history %}{{ line.price_diff|stringformat:".2f" }},{% endfor %} + ], + borderWidth: 1, + type: 'line', + hidden: true, + }, + { + label: '{% blocktrans %}Part Single Price - {{currency}}{% endblocktrans %}', + backgroundColor: 'rgba(70, 127, 155, 0.2)', + borderColor: 'rgb(70, 127, 155)', + yAxisID: 'y', + data: [ + {% for line in price_history %}{{ line.price_part|stringformat:".2f" }},{% endfor %} + ], + borderWidth: 1, + type: 'line', + hidden: true, + }, + {% endif %} + { + label: '{% trans "Quantity" %}', + backgroundColor: 'rgba(255, 206, 86, 0.2)', + borderColor: 'rgb(255, 206, 86)', + yAxisID: 'y1', + data: [ + {% for line in price_history %}{{ line.qty|stringformat:"f" }},{% endfor %} + ], + borderWidth: 1 + }] + } + var StockPriceChart = loadStockPricingChart($('#StockPriceChart'), purchasepricedata) + {% endif %} + + {% if bom_parts %} + var bom_colors = randomColor({hue: 'green', count: {{ bom_parts|length }} }) + var bomdata = { + labels: [{% for line in bom_parts %}'{{ line.name }}',{% endfor %}], + datasets: [ + { + label: 'Price', + data: [{% for line in bom_parts %}{{ line.min_price }},{% endfor %}], + backgroundColor: bom_colors, + }, + {% if bom_pie_max %} + { + label: 'Max Price', + data: [{% for line in bom_parts %}{{ line.max_price }},{% endfor %}], + backgroundColor: bom_colors, + }, + {% endif %} + ] + }; + var BomChart = loadBomChart(document.getElementById('BomChart'), bomdata) + {% endif %} + + + // Internal pricebreaks + {% settings_value "PART_INTERNAL_PRICE" as show_internal_price %} + {% if show_internal_price and roles.sales_order.view %} + initPriceBreakSet( + $('#internal-price-break-table'), + { + part_id: {{part.id}}, + pb_human_name: 'internal price break', + pb_url_slug: 'internal-price', + pb_url: '{% url 'api-part-internal-price-list' %}', + pb_new_btn: $('#new-internal-price-break'), + pb_new_url: '{% url 'internal-price-break-create' %}', + linkedGraph: $('#InternalPriceBreakChart'), + }, + ); + {% endif %} + + + // Load the BOM table data + loadBomTable($("#bom-table"), { + editable: {{ editing_enabled }}, + bom_url: "{% url 'api-bom-list' %}", + part_url: "{% url 'api-part-list' %}", + parent_id: {{ part.id }} , + sub_part_detail: true, + }); + + + // Sales pricebreaks + {% if part.salable and roles.sales_order.view %} + initPriceBreakSet( + $('#price-break-table'), + { + part_id: {{part.id}}, + pb_human_name: 'sale price break', + pb_url_slug: 'sale-price', + pb_url: "{% url 'api-part-sale-price-list' %}", + pb_new_btn: $('#new-price-break'), + pb_new_url: '{% url 'sale-price-break-create' %}', + linkedGraph: $('#SalePriceBreakChart'), + }, + ); + {% endif %} + + // Sale price history + {% if sale_history %} + var salepricedata = { + labels: [ + {% for line in sale_history %}'{{ line.date }}',{% endfor %} + ], + datasets: [{ + label: '{% blocktrans %}Unit Price - {{currency}}{% endblocktrans %}', + backgroundColor: 'rgba(255, 99, 132, 0.2)', + borderColor: 'rgb(255, 99, 132)', + yAxisID: 'y', + data: [ + {% for line in sale_history %}{{ line.price|stringformat:".2f" }},{% endfor %} + ], + borderWidth: 1, + }, + { + label: '{% trans "Quantity" %}', + backgroundColor: 'rgba(255, 206, 86, 0.2)', + borderColor: 'rgb(255, 206, 86)', + yAxisID: 'y1', + data: [ + {% for line in sale_history %}{{ line.qty|stringformat:"f" }},{% endfor %} + ], + borderWidth: 1, + type: 'bar', + }] + } + var SalePriceChart = loadSellPricingChart($('#SalePriceChart'), salepricedata) + {% endif %} + +{% endblock %} diff --git a/InvenTree/part/templates/part/sale_prices.html b/InvenTree/part/templates/part/sale_prices.html deleted file mode 100644 index 4ec826e2a6..0000000000 --- a/InvenTree/part/templates/part/sale_prices.html +++ /dev/null @@ -1,108 +0,0 @@ -{% extends "part/part_base.html" %} -{% load static %} -{% load i18n %} - -{% block menubar %} -{% include 'part/navbar.html' with tab='sales-prices' %} -{% endblock %} - -{% block heading %} -{% trans "Sell Price Information" %} -{% endblock %} - -{% block details %} - -
                  - -
                  - - -
                  - -{% endblock %} - -{% block js_ready %} -{{ block.super }} - -function reloadPriceBreaks() { - $("#price-break-table").bootstrapTable("refresh"); -} - -$('#new-price-break').click(function() { - launchModalForm("{% url 'sale-price-break-create' %}", - { - success: reloadPriceBreaks, - data: { - part: {{ part.id }}, - } - } - ); -}); - -$('#price-break-table').inventreeTable({ - name: 'saleprice', - formatNoMatches: function() { return "{% trans 'No price break information found' %}"; }, - queryParams: { - part: {{ part.id }}, - }, - url: "{% url 'api-part-sale-price-list' %}", - onPostBody: function() { - var table = $('#price-break-table'); - - table.find('.button-price-break-delete').click(function() { - var pk = $(this).attr('pk'); - - launchModalForm( - `/part/sale-price/${pk}/delete/`, - { - success: reloadPriceBreaks - } - ); - }); - - table.find('.button-price-break-edit').click(function() { - var pk = $(this).attr('pk'); - - launchModalForm( - `/part/sale-price/${pk}/edit/`, - { - success: reloadPriceBreaks - } - ); - }); - }, - columns: [ - { - field: 'pk', - title: 'ID', - visible: false, - switchable: false, - }, - { - field: 'quantity', - title: '{% trans "Quantity" %}', - sortable: true, - }, - { - field: 'price', - title: '{% trans "Price" %}', - sortable: true, - formatter: function(value, row, index) { - var html = value; - - html += `
                  ` - - html += makeIconButton('fa-edit icon-blue', 'button-price-break-edit', row.pk, '{% trans "Edit price break" %}'); - html += makeIconButton('fa-trash-alt icon-red', 'button-price-break-delete', row.pk, '{% trans "Delete price break" %}'); - - html += `
                  `; - - return html; - } - }, - ] -}) - -{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/stock.html b/InvenTree/part/templates/part/stock.html index 067eda66a8..6bb4c246f0 100644 --- a/InvenTree/part/templates/part/stock.html +++ b/InvenTree/part/templates/part/stock.html @@ -41,6 +41,7 @@ part: {{ part.id }}, location_detail: true, part_detail: false, + supplier_part_detail: true, }, groupByField: 'location', buttons: [ diff --git a/InvenTree/part/templates/part/supplier.html b/InvenTree/part/templates/part/supplier.html index 45d2d1d55c..c0486cc42a 100644 --- a/InvenTree/part/templates/part/supplier.html +++ b/InvenTree/part/templates/part/supplier.html @@ -49,13 +49,11 @@ field: 'supplier', label: '{% trans "New Supplier" %}', title: '{% trans "Create new supplier" %}', - url: "{% url 'supplier-create' %}" }, { field: 'manufacturer', label: '{% trans "New Manufacturer" %}', title: '{% trans "Create new manufacturer" %}', - url: "{% url 'manufacturer-create' %}", } ] }); diff --git a/InvenTree/part/test_api.py b/InvenTree/part/test_api.py index 4922ed4e04..0c1f083383 100644 --- a/InvenTree/part/test_api.py +++ b/InvenTree/part/test_api.py @@ -16,6 +16,106 @@ from company.models import Company from common.models import InvenTreeSetting +class PartOptionsAPITest(InvenTreeAPITestCase): + """ + Tests for the various OPTIONS endpoints in the /part/ API + + Ensure that the required field details are provided! + """ + + roles = [ + 'part.add', + ] + + def setUp(self): + + super().setUp() + + def test_part(self): + """ + Test the Part API OPTIONS + """ + + actions = self.getActions(reverse('api-part-list'))['POST'] + + # Check that a bunch o' fields are contained + for f in ['assembly', 'component', 'description', 'image', 'IPN']: + self.assertTrue(f in actions.keys()) + + # Active is a 'boolean' field + active = actions['active'] + + self.assertTrue(active['default']) + self.assertEqual(active['help_text'], 'Is this part active?') + self.assertEqual(active['type'], 'boolean') + self.assertEqual(active['read_only'], False) + + # String field + ipn = actions['IPN'] + self.assertEqual(ipn['type'], 'string') + self.assertFalse(ipn['required']) + self.assertEqual(ipn['max_length'], 100) + self.assertEqual(ipn['help_text'], 'Internal Part Number') + + # Related field + category = actions['category'] + + self.assertEqual(category['type'], 'related field') + self.assertTrue(category['required']) + self.assertFalse(category['read_only']) + self.assertEqual(category['label'], 'Category') + self.assertEqual(category['model'], 'partcategory') + self.assertEqual(category['api_url'], reverse('api-part-category-list')) + self.assertEqual(category['help_text'], 'Part category') + + def test_category(self): + """ + Test the PartCategory API OPTIONS endpoint + """ + + actions = self.getActions(reverse('api-part-category-list')) + + # actions should *not* contain 'POST' as we do not have the correct role + self.assertFalse('POST' in actions) + + self.assignRole('part_category.add') + + actions = self.getActions(reverse('api-part-category-list'))['POST'] + + name = actions['name'] + + self.assertTrue(name['required']) + self.assertEqual(name['label'], 'Name') + + loc = actions['default_location'] + self.assertEqual(loc['api_url'], reverse('api-location-list')) + + def test_bom_item(self): + """ + Test the BomItem API OPTIONS endpoint + """ + + actions = self.getActions(reverse('api-bom-list'))['POST'] + + inherited = actions['inherited'] + + self.assertEqual(inherited['type'], 'boolean') + + # 'part' reference + part = actions['part'] + + self.assertTrue(part['required']) + self.assertFalse(part['read_only']) + self.assertTrue(part['filters']['assembly']) + + # 'sub_part' reference + sub_part = actions['sub_part'] + + self.assertTrue(sub_part['required']) + self.assertEqual(sub_part['type'], 'related field') + self.assertTrue(sub_part['filters']['component']) + + class PartAPITest(InvenTreeAPITestCase): """ Series of tests for the Part DRF API diff --git a/InvenTree/part/test_views.py b/InvenTree/part/test_views.py index c32753cbbb..3b6b245231 100644 --- a/InvenTree/part/test_views.py +++ b/InvenTree/part/test_views.py @@ -232,29 +232,6 @@ class PartRelatedTests(PartViewTestCase): self.assertEqual(n, 1) -class PartAttachmentTests(PartViewTestCase): - - def test_valid_create(self): - """ test creation of an attachment for a valid part """ - - response = self.client.get(reverse('part-attachment-create'), {'part': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - - # TODO - Create a new attachment using this view - - def test_invalid_create(self): - """ test creation of an attachment for an invalid part """ - - # TODO - pass - - def test_edit(self): - """ test editing an attachment """ - - # TODO - pass - - class PartQRTest(PartViewTestCase): """ Tests for the Part QR Code AJAX view """ @@ -294,11 +271,6 @@ class CategoryTest(PartViewTestCase): # Form should still return OK self.assertEqual(response.status_code, 200) - def test_edit(self): - """ Retrieve the part category editing form """ - response = self.client.get(reverse('category-edit', args=(1,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - def test_set_category(self): """ Test that the "SetCategory" view works """ diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index c35786e5d3..96560a7ad7 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -17,12 +17,6 @@ part_related_urls = [ url(r'^(?P\d+)/delete/?', views.PartRelatedDelete.as_view(), name='part-related-delete'), ] -part_attachment_urls = [ - url(r'^new/?', views.PartAttachmentCreate.as_view(), name='part-attachment-create'), - url(r'^(?P\d+)/edit/?', views.PartAttachmentEdit.as_view(), name='part-attachment-edit'), - url(r'^(?P\d+)/delete/?', views.PartAttachmentDelete.as_view(), name='part-attachment-delete'), -] - sale_price_break_urls = [ url(r'^new/', views.PartSalePriceBreakCreate.as_view(), name='sale-price-break-create'), url(r'^(?P\d+)/edit/', views.PartSalePriceBreakEdit.as_view(), name='sale-price-break-edit'), @@ -65,13 +59,11 @@ part_detail_urls = [ url(r'^bom/?', views.PartDetail.as_view(template_name='part/bom.html'), name='part-bom'), url(r'^build/?', views.PartDetail.as_view(template_name='part/build.html'), name='part-build'), url(r'^used/?', views.PartDetail.as_view(template_name='part/used_in.html'), name='part-used-in'), - url(r'^order-prices/', views.PartPricingView.as_view(template_name='part/order_prices.html'), name='part-order-prices'), + url(r'^prices/', views.PartPricingView.as_view(template_name='part/prices.html'), name='part-prices'), url(r'^manufacturers/?', views.PartDetail.as_view(template_name='part/manufacturer.html'), name='part-manufacturers'), url(r'^suppliers/?', views.PartDetail.as_view(template_name='part/supplier.html'), name='part-suppliers'), url(r'^orders/?', views.PartDetail.as_view(template_name='part/orders.html'), name='part-orders'), url(r'^sales-orders/', views.PartDetail.as_view(template_name='part/sales_orders.html'), name='part-sales-orders'), - url(r'^sale-prices/', views.PartDetail.as_view(template_name='part/sale_prices.html'), name='part-sale-prices'), - url(r'^internal-prices/', views.PartDetail.as_view(template_name='part/internal_prices.html'), name='part-internal-prices'), url(r'^tests/', views.PartDetail.as_view(template_name='part/part_tests.html'), name='part-test-templates'), url(r'^track/?', views.PartDetail.as_view(template_name='part/track.html'), name='part-track'), url(r'^related-parts/?', views.PartDetail.as_view(template_name='part/related.html'), name='part-related'), @@ -81,7 +73,6 @@ part_detail_urls = [ url(r'^qr_code/?', views.PartQRCode.as_view(), name='part-qr'), # Normal thumbnail with form - url(r'^thumbnail/?', views.PartImageUpload.as_view(), name='part-image-upload'), url(r'^thumb-select/?', views.PartImageSelect.as_view(), name='part-image-select'), url(r'^thumb-download/', views.PartImageDownloadFromURL.as_view(), name='part-image-download'), @@ -105,7 +96,6 @@ category_urls = [ # Category detail views url(r'(?P\d+)/', include([ - url(r'^edit/', views.CategoryEdit.as_view(), name='category-edit'), url(r'^delete/', views.CategoryDelete.as_view(), name='category-delete'), url(r'^parameters/', include(category_parameter_urls)), @@ -119,7 +109,6 @@ category_urls = [ part_bom_urls = [ url(r'^edit/?', views.BomItemEdit.as_view(), name='bom-item-edit'), - url('^delete/?', views.BomItemDelete.as_view(), name='bom-item-delete'), ] # URL list for part web interface @@ -150,22 +139,12 @@ part_urls = [ # Part related url(r'^related-parts/', include(part_related_urls)), - # Part attachments - url(r'^attachment/', include(part_attachment_urls)), - # Part price breaks url(r'^sale-price/', include(sale_price_break_urls)), # Part internal price breaks url(r'^internal-price/', include(internal_price_break_urls)), - # Part test templates - url(r'^test-template/', include([ - url(r'^new/', views.PartTestTemplateCreate.as_view(), name='part-test-template-create'), - url(r'^(?P\d+)/edit/', views.PartTestTemplateEdit.as_view(), name='part-test-template-edit'), - url(r'^(?P\d+)/delete/', views.PartTestTemplateDelete.as_view(), name='part-test-template-delete'), - ])), - # Part parameters url(r'^parameter/', include(part_parameter_urls)), diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 294f89223e..d9f79262d1 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -31,12 +31,11 @@ import io from rapidfuzz import fuzz from decimal import Decimal, InvalidOperation -from .models import PartCategory, Part, PartAttachment, PartRelated +from .models import PartCategory, Part, PartRelated from .models import PartParameterTemplate, PartParameter from .models import PartCategoryParameterTemplate from .models import BomItem from .models import match_part_names -from .models import PartTestTemplate from .models import PartSellPriceBreak, PartInternalPriceBreak from common.models import InvenTreeSetting @@ -50,6 +49,7 @@ import common.settings as inventree_settings from . import forms as part_forms from .bom import MakeBomTemplate, BomUploadManager, ExportBom, IsValidBOMFormat +from order.models import PurchaseOrderLineItem from .admin import PartResource @@ -154,146 +154,6 @@ class PartRelatedDelete(AjaxDeleteView): role_required = 'part.change' -class PartAttachmentCreate(AjaxCreateView): - """ View for creating a new PartAttachment object - - - The view only makes sense if a Part object is passed to it - """ - model = PartAttachment - form_class = part_forms.EditPartAttachmentForm - ajax_form_title = _("Add part attachment") - ajax_template_name = "modal_form.html" - - def save(self, form, **kwargs): - """ - Record the user that uploaded this attachment - """ - - attachment = form.save(commit=False) - attachment.user = self.request.user - attachment.save() - - def get_data(self): - return { - 'success': _('Added attachment') - } - - def get_initial(self): - """ Get initial data for new PartAttachment object. - - - Client should have requested this form with a parent part in mind - - e.g. ?part= - """ - - initials = super(AjaxCreateView, self).get_initial() - - # TODO - If the proper part was not sent, return an error message - try: - initials['part'] = Part.objects.get(id=self.request.GET.get('part', None)) - except (ValueError, Part.DoesNotExist): - pass - - return initials - - def get_form(self): - """ Create a form to upload a new PartAttachment - - - Hide the 'part' field - """ - - form = super(AjaxCreateView, self).get_form() - - form.fields['part'].widget = HiddenInput() - - return form - - -class PartAttachmentEdit(AjaxUpdateView): - """ View for editing a PartAttachment object """ - - model = PartAttachment - form_class = part_forms.EditPartAttachmentForm - ajax_template_name = 'modal_form.html' - ajax_form_title = _('Edit attachment') - - def get_data(self): - return { - 'success': _('Part attachment updated') - } - - def get_form(self): - form = super(AjaxUpdateView, self).get_form() - - form.fields['part'].widget = HiddenInput() - - return form - - -class PartAttachmentDelete(AjaxDeleteView): - """ View for deleting a PartAttachment """ - - model = PartAttachment - ajax_form_title = _("Delete Part Attachment") - ajax_template_name = "attachment_delete.html" - context_object_name = "attachment" - - role_required = 'part.change' - - def get_data(self): - return { - 'danger': _('Deleted part attachment') - } - - -class PartTestTemplateCreate(AjaxCreateView): - """ View for creating a PartTestTemplate """ - - model = PartTestTemplate - form_class = part_forms.EditPartTestTemplateForm - ajax_form_title = _("Create Test Template") - - def get_initial(self): - - initials = super().get_initial() - - try: - part_id = self.request.GET.get('part', None) - initials['part'] = Part.objects.get(pk=part_id) - except (ValueError, Part.DoesNotExist): - pass - - return initials - - def get_form(self): - - form = super().get_form() - form.fields['part'].widget = HiddenInput() - - return form - - -class PartTestTemplateEdit(AjaxUpdateView): - """ View for editing a PartTestTemplate """ - - model = PartTestTemplate - form_class = part_forms.EditPartTestTemplateForm - ajax_form_title = _("Edit Test Template") - - def get_form(self): - - form = super().get_form() - form.fields['part'].widget = HiddenInput() - - return form - - -class PartTestTemplateDelete(AjaxDeleteView): - """ View for deleting a PartTestTemplate """ - - model = PartTestTemplate - ajax_form_title = _("Delete Test Template") - - class PartSetCategory(AjaxUpdateView): """ View for settings the part category for multiple parts at once """ @@ -979,18 +839,20 @@ class PartPricingView(PartDetail): """ returns context with pricing information """ ctx = PartPricing.get_pricing(self, quantity, currency) part = self.get_part() + default_currency = inventree_settings.currency_code_default() + # Stock history if part.total_stock > 1: price_history = [] - stock = part.stock_entries(include_variants=False, in_stock=True) # .order_by('purchase_order__date') - stock = stock.prefetch_related('purchase_order', 'supplier_part') + stock = part.stock_entries(include_variants=False, in_stock=True).\ + order_by('purchase_order__issue_date').prefetch_related('purchase_order', 'supplier_part') for stock_item in stock: if None in [stock_item.purchase_price, stock_item.quantity]: continue # convert purchase price to current currency - only one currency in the graph - price = convert_money(stock_item.purchase_price, inventree_settings.currency_code_default()) + price = convert_money(stock_item.purchase_price, default_currency) line = { 'price': price.amount, 'qty': stock_item.quantity @@ -1036,6 +898,36 @@ class PartPricingView(PartDetail): # add to global context ctx['bom_parts'] = ctx_bom_parts + # Sale price history + sale_items = PurchaseOrderLineItem.objects.filter(part__part=part).order_by('order__issue_date').\ + prefetch_related('order', ).all() + + if sale_items: + sale_history = [] + + for sale_item in sale_items: + # check for not fully defined elements + if None in [sale_item.purchase_price, sale_item.quantity]: + continue + + price = convert_money(sale_item.purchase_price, default_currency) + line = { + 'price': price.amount if price else 0, + 'qty': sale_item.quantity, + } + + # set date for graph labels + if sale_item.order.issue_date: + line['date'] = sale_item.order.issue_date.strftime('%d.%m.%Y') + elif sale_item.order.creation_date: + line['date'] = sale_item.order.creation_date.strftime('%d.%m.%Y') + else: + line['date'] = _('None') + + sale_history.append(line) + + ctx['sale_history'] = sale_history + return ctx def get_initials(self): @@ -1186,21 +1078,6 @@ class PartImageDownloadFromURL(AjaxUpdateView): ) -class PartImageUpload(AjaxUpdateView): - """ View for uploading a new Part image """ - - model = Part - ajax_template_name = 'modal_form.html' - ajax_form_title = _('Upload Part Image') - - form_class = part_forms.PartImageForm - - def get_data(self): - return { - 'success': _('Updated part image'), - } - - class PartImageSelect(AjaxUpdateView): """ View for selecting Part image from existing images. """ @@ -2901,17 +2778,10 @@ class BomItemEdit(AjaxUpdateView): return form -class BomItemDelete(AjaxDeleteView): - """ Delete view for removing BomItem """ - - model = BomItem - ajax_template_name = 'part/bom-delete.html' - context_object_name = 'item' - ajax_form_title = _('Confim BOM item deletion') - - class PartSalePriceBreakCreate(AjaxCreateView): - """ View for creating a sale price break for a part """ + """ + View for creating a sale price break for a part + """ model = PartSellPriceBreak form_class = part_forms.EditPartSalePriceBreakForm diff --git a/InvenTree/report/models.py b/InvenTree/report/models.py index ecb4d91492..c33347f643 100644 --- a/InvenTree/report/models.py +++ b/InvenTree/report/models.py @@ -11,6 +11,7 @@ import logging import datetime +from django.urls import reverse from django.db import models from django.conf import settings from django.core.exceptions import ValidationError, FieldError @@ -307,6 +308,10 @@ class TestReport(ReportTemplateBase): Render a TestReport against a StockItem object. """ + @staticmethod + def get_api_url(): + return reverse('api-stockitem-testreport-list') + @classmethod def getSubdir(cls): return 'test' @@ -361,6 +366,10 @@ class BuildReport(ReportTemplateBase): Build order / work order report """ + @staticmethod + def get_api_url(): + return reverse('api-build-report-list') + @classmethod def getSubdir(cls): return 'build' @@ -400,6 +409,10 @@ class BillOfMaterialsReport(ReportTemplateBase): Render a Bill of Materials against a Part object """ + @staticmethod + def get_api_url(): + return reverse('api-bom-report-list') + @classmethod def getSubdir(cls): return 'bom' @@ -430,6 +443,10 @@ class PurchaseOrderReport(ReportTemplateBase): Render a report against a PurchaseOrder object """ + @staticmethod + def get_api_url(): + return reverse('api-po-report-list') + @classmethod def getSubdir(cls): return 'purchaseorder' @@ -464,6 +481,10 @@ class SalesOrderReport(ReportTemplateBase): Render a report against a SalesOrder object """ + @staticmethod + def get_api_url(): + return reverse('api-so-report-list') + @classmethod def getSubdir(cls): return 'salesorder' diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 3fc440cae4..cf13811c8c 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -2,17 +2,21 @@ JSON API for the Stock app """ -from django_filters.rest_framework import FilterSet, DjangoFilterBackend -from django_filters import NumberFilter - -from rest_framework import status - from django.conf.urls import url, include from django.urls import reverse from django.http import JsonResponse from django.db.models import Q from django.utils.translation import ugettext_lazy as _ +from rest_framework import status +from rest_framework.serializers import ValidationError +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import generics, filters, permissions + +from django_filters.rest_framework import FilterSet, DjangoFilterBackend +from django_filters import NumberFilter + from .models import StockLocation, StockItem from .models import StockItemTracking from .models import StockItemAttachment @@ -44,11 +48,6 @@ from decimal import Decimal, InvalidOperation from datetime import datetime, timedelta -from rest_framework.serializers import ValidationError -from rest_framework.views import APIView -from rest_framework.response import Response -from rest_framework import generics, filters, permissions - class StockCategoryTree(TreeSerializer): title = _('Stock') @@ -858,6 +857,17 @@ class StockList(generics.ListCreateAPIView): print("After error:", str(updated_after)) pass + # Filter stock items which have a purchase price set + has_purchase_price = params.get('has_purchase_price', None) + + if has_purchase_price is not None: + has_purchase_price = str2bool(has_purchase_price) + + if has_purchase_price: + queryset = queryset.exclude(purchase_price=None) + else: + queryset = queryset.filter(purchase_price=None) + # Optionally, limit the maximum number of returned results max_results = params.get('max_results', None) @@ -931,6 +941,24 @@ class StockAttachmentList(generics.ListCreateAPIView, AttachmentMixin): ] +class StockAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, AttachmentMixin): + """ + Detail endpoint for StockItemAttachment + """ + + queryset = StockItemAttachment.objects.all() + serializer_class = StockItemAttachmentSerializer + + +class StockItemTestResultDetail(generics.RetrieveUpdateDestroyAPIView): + """ + Detail endpoint for StockItemTestResult + """ + + queryset = StockItemTestResult.objects.all() + serializer_class = StockItemTestResultSerializer + + class StockItemTestResultList(generics.ListCreateAPIView): """ API endpoint for listing (and creating) a StockItemTestResult object. @@ -979,6 +1007,15 @@ class StockItemTestResultList(generics.ListCreateAPIView): test_result.save() +class StockTrackingDetail(generics.RetrieveAPIView): + """ + Detail API endpoint for StockItemTracking model + """ + + queryset = StockItemTracking.objects.all() + serializer_class = StockTrackingSerializer + + class StockTrackingList(generics.ListAPIView): """ API endpoint for list view of StockItemTracking objects. @@ -1133,6 +1170,7 @@ stock_api_urls = [ url(r'location/', include(location_endpoints)), # These JSON endpoints have been replaced (for now) with server-side form rendering - 02/06/2019 + # TODO: Remove server-side forms for stock adjustment!!! url(r'count/?', StockCount.as_view(), name='api-stock-count'), url(r'add/?', StockAdd.as_view(), name='api-stock-add'), url(r'remove/?', StockRemove.as_view(), name='api-stock-remove'), @@ -1140,15 +1178,20 @@ stock_api_urls = [ # Base URL for StockItemAttachment API endpoints url(r'^attachment/', include([ + url(r'^(?P\d+)/', StockAttachmentDetail.as_view(), name='api-stock-attachment-detail'), url(r'^$', StockAttachmentList.as_view(), name='api-stock-attachment-list'), ])), # Base URL for StockItemTestResult API endpoints url(r'^test/', include([ - url(r'^$', StockItemTestResultList.as_view(), name='api-stock-test-result-list'), + url(r'^(?P\d+)/', StockItemTestResultDetail.as_view(), name='api-stock-test-result-detail'), + url(r'^.*$', StockItemTestResultList.as_view(), name='api-stock-test-result-list'), ])), - url(r'track/?', StockTrackingList.as_view(), name='api-stock-track'), + url(r'^track/', include([ + url(r'^(?P\d+)/', StockTrackingDetail.as_view(), name='api-stock-tracking-detail'), + url(r'^.*$', StockTrackingList.as_view(), name='api-stock-tracking-list'), + ])), url(r'^tree/?', StockCategoryTree.as_view(), name='api-stock-tree'), diff --git a/InvenTree/stock/forms.py b/InvenTree/stock/forms.py index 92089623f9..ec3eee09d5 100644 --- a/InvenTree/stock/forms.py +++ b/InvenTree/stock/forms.py @@ -23,22 +23,6 @@ from report.models import TestReport from part.models import Part from .models import StockLocation, StockItem, StockItemTracking -from .models import StockItemAttachment -from .models import StockItemTestResult - - -class EditStockItemAttachmentForm(HelperForm): - """ - Form for creating / editing a StockItemAttachment object - """ - - class Meta: - model = StockItemAttachment - fields = [ - 'stock_item', - 'attachment', - 'comment' - ] class AssignStockItemToCustomerForm(HelperForm): @@ -65,23 +49,6 @@ class ReturnStockItemForm(HelperForm): ] -class EditStockItemTestResultForm(HelperForm): - """ - Form for creating / editing a StockItemTestResult object. - """ - - class Meta: - model = StockItemTestResult - fields = [ - 'stock_item', - 'test', - 'result', - 'value', - 'attachment', - 'notes', - ] - - class EditStockLocationForm(HelperForm): """ Form for editing a StockLocation """ diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 446dce5c75..9b3a95a20c 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -48,6 +48,10 @@ class StockLocation(InvenTreeTree): Stock locations can be heirarchical as required """ + @staticmethod + def get_api_url(): + return reverse('api-location-list') + owner = models.ForeignKey(Owner, on_delete=models.SET_NULL, blank=True, null=True, verbose_name=_('Owner'), help_text=_('Select Owner'), @@ -157,6 +161,10 @@ class StockItem(MPTTModel): packaging: Description of how the StockItem is packaged (e.g. "reel", "loose", "tape" etc) """ + @staticmethod + def get_api_url(): + return reverse('api-stock-list') + # A Query filter which will be re-used in multiple places to determine if a StockItem is actually "in stock" IN_STOCK_FILTER = Q( quantity__gt=0, @@ -1603,6 +1611,10 @@ class StockItemAttachment(InvenTreeAttachment): Model for storing file attachments against a StockItem object. """ + @staticmethod + def get_api_url(): + return reverse('api-stock-attachment-list') + def getSubdir(self): return os.path.join("stock_files", str(self.stock_item.id)) @@ -1634,6 +1646,10 @@ class StockItemTracking(models.Model): deltas: The changes associated with this history item """ + @staticmethod + def get_api_url(): + return reverse('api-stock-tracking-list') + def get_absolute_url(self): return '/stock/track/{pk}'.format(pk=self.id) @@ -1692,6 +1708,10 @@ class StockItemTestResult(models.Model): date: Date the test result was recorded """ + @staticmethod + def get_api_url(): + return reverse('api-stock-test-result-list') + def save(self, *args, **kwargs): super().clean() diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index a0b7e3403a..38301bdd1f 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -288,6 +288,8 @@ class StockItemAttachmentSerializer(InvenTreeModelSerializer): attachment = InvenTreeAttachmentSerializerField(required=True) + # TODO: Record the uploading user when creating or updating an attachment! + class Meta: model = StockItemAttachment diff --git a/InvenTree/stock/templates/stock/item.html b/InvenTree/stock/templates/stock/item.html index 5d551c29fb..7564e7864e 100644 --- a/InvenTree/stock/templates/stock/item.html +++ b/InvenTree/stock/templates/stock/item.html @@ -57,7 +57,7 @@ item: {{ item.pk }}, user_detail: true, }, - url: "{% url 'api-stock-track' %}", + url: "{% url 'api-stock-tracking-list' %}", }); {% endblock %} \ No newline at end of file diff --git a/InvenTree/stock/templates/stock/item_attachments.html b/InvenTree/stock/templates/stock/item_attachments.html index a022403d02..34ceecc550 100644 --- a/InvenTree/stock/templates/stock/item_attachments.html +++ b/InvenTree/stock/templates/stock/item_attachments.html @@ -21,49 +21,66 @@ enableDragAndDrop( '#attachment-dropzone', - "{% url 'stock-item-attachment-create' %}", + "{% url 'api-stock-attachment-list' %}", { data: { stock_item: {{ item.id }}, }, label: 'attachment', success: function(data, status, xhr) { - location.reload(); + reloadAttachmentTable(); } } ); -$("#new-attachment").click(function() { - launchModalForm("{% url 'stock-item-attachment-create' %}?item={{ item.id }}", - { - reload: true, - }); -}); +loadAttachmentTable( + '{% url "api-stock-attachment-list" %}', + { + filters: { + item: {{ item.pk }}, + }, + onEdit: function(pk) { + var url = `/api/stock/attachment/${pk}/`; -$("#attachment-table").on('click', '.attachment-edit-button', function() { - var button = $(this); + constructForm(url, { + fields: { + comment: {}, + }, + title: '{% trans "Edit Attachment" %}', + onSuccess: reloadAttachmentTable + }); + }, + onDelete: function(pk) { + var url = `/api/stock/attachment/${pk}/`; - var url = `/stock/item/attachment/${button.attr('pk')}/edit/`; - - launchModalForm(url, - { - reload: true, - }); -}); - -$("#attachment-table").on('click', '.attachment-delete-button', function() { - var button = $(this); - - var url = `/stock/item/attachment/${button.attr('pk')}/delete/`; - - launchModalForm(url, { - success: function() { - location.reload(); + constructForm(url, { + method: 'DELETE', + confirmMessage: '{% trans "Confirm Delete Operation" %}', + title: '{% trans "Delete Attachment" %}', + onSuccess: reloadAttachmentTable, + }); } - }); -}); + } +); -$("#attachment-table").inventreeTable({ +$("#new-attachment").click(function() { + + constructForm( + '{% url "api-stock-attachment-list" %}', + { + method: 'POST', + fields: { + attachment: {}, + comment: {}, + stock_item: { + value: {{ item.pk }}, + hidden: true, + }, + }, + reload: true, + title: '{% trans "Add Attachment" %}', + } + ); }); {% endblock %} \ No newline at end of file diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index bf9d10590f..b674c5c7fc 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -490,13 +490,14 @@ $("#stock-edit").click(function () { }); $('#stock-edit-status').click(function () { - launchModalForm( - "{% url 'stock-item-edit-status' item.id %}", - { - reload: true, - submit_text: '{% trans "Save" %}', - } - ); + + constructForm('{% url "api-stock-detail" item.pk %}', { + fields: { + status: {}, + }, + reload: true, + title: '{% trans "Edit Stock Status" %}', + }); }); {% endif %} diff --git a/InvenTree/stock/templates/stock/item_tests.html b/InvenTree/stock/templates/stock/item_tests.html index 4b3d9dd028..d7d26fcbba 100644 --- a/InvenTree/stock/templates/stock/item_tests.html +++ b/InvenTree/stock/templates/stock/item_tests.html @@ -48,8 +48,7 @@ loadStockTestResultsTable( ); function reloadTable() { - location.reload(); - //$("#test-result-table").bootstrapTable("refresh"); + $("#test-result-table").bootstrapTable("refresh"); } {% if item.has_test_reports %} @@ -70,15 +69,23 @@ $("#delete-test-results").click(function() { {% endif %} $("#add-test-result").click(function() { - launchModalForm( - "{% url 'stock-item-test-create' %}", { - data: { - stock_item: {{ item.id }}, - }, - success: reloadTable, - focus: 'test', - } - ); + + constructForm('{% url "api-stock-test-result-list" %}', { + method: 'POST', + fields: { + test: {}, + result: {}, + value: {}, + attachment: {}, + notes: {}, + stock_item: { + value: {{ item.pk }}, + hidden: true, + } + }, + title: '{% trans "Add Test Result" %}', + onSuccess: reloadTable, + }); }); $("#test-result-table").on('click', '.button-test-add', function() { @@ -86,35 +93,57 @@ $("#test-result-table").on('click', '.button-test-add', function() { var test_name = button.attr('pk'); - launchModalForm( - "{% url 'stock-item-test-create' %}", { - data: { - stock_item: {{ item.id }}, - test: test_name + constructForm('{% url "api-stock-test-result-list" %}', { + method: 'POST', + fields: { + test: { + value: test_name, }, - success: reloadTable, - focus: 'value', - } - ); + result: {}, + value: {}, + attachment: {}, + notes: {}, + stock_item: { + value: {{ item.pk }}, + hidden: true, + } + }, + title: '{% trans "Add Test Result" %}', + onSuccess: reloadTable, + }); }); $("#test-result-table").on('click', '.button-test-edit', function() { var button = $(this); - var url = `/stock/item/test/${button.attr('pk')}/edit/`; + var pk = button.attr('pk'); - launchModalForm(url, { - success: reloadTable, + var url = `/api/stock/test/${pk}/`; + + constructForm(url, { + fields: { + test: {}, + result: {}, + value: {}, + attachment: {}, + notes: {}, + }, + title: '{% trans "Edit Test Result" %}', + onSuccess: reloadTable, }); }); $("#test-result-table").on('click', '.button-test-delete', function() { var button = $(this); - var url = `/stock/item/test/${button.attr('pk')}/delete/`; + var pk = button.attr('pk'); - launchModalForm(url, { - success: reloadTable, + var url = `/api/stock/test/${pk}/`; + + constructForm(url, { + method: 'DELETE', + title: '{% trans "Delete Test Result" %}', + onSuccess: reloadTable, }); }); diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py index dbdbdda317..ac9474f805 100644 --- a/InvenTree/stock/urls.py +++ b/InvenTree/stock/urls.py @@ -24,7 +24,6 @@ location_urls = [ ] stock_item_detail_urls = [ - url(r'^edit_status/', views.StockItemEditStatus.as_view(), name='stock-item-edit-status'), url(r'^edit/', views.StockItemEdit.as_view(), name='stock-item-edit'), url(r'^convert/', views.StockItemConvert.as_view(), name='stock-item-convert'), url(r'^serialize/', views.StockItemSerialize.as_view(), name='stock-item-serialize'), @@ -63,20 +62,6 @@ stock_urls = [ url(r'^item/uninstall/', views.StockItemUninstall.as_view(), name='stock-item-uninstall'), - # URLs for StockItem attachments - url(r'^item/attachment/', include([ - url(r'^new/', views.StockItemAttachmentCreate.as_view(), name='stock-item-attachment-create'), - url(r'^(?P\d+)/edit/', views.StockItemAttachmentEdit.as_view(), name='stock-item-attachment-edit'), - url(r'^(?P\d+)/delete/', views.StockItemAttachmentDelete.as_view(), name='stock-item-attachment-delete'), - ])), - - # URLs for StockItem tests - url(r'^item/test/', include([ - url(r'^new/', views.StockItemTestResultCreate.as_view(), name='stock-item-test-create'), - url(r'^(?P\d+)/edit/', views.StockItemTestResultEdit.as_view(), name='stock-item-test-edit'), - url(r'^(?P\d+)/delete/', views.StockItemTestResultDelete.as_view(), name='stock-item-test-delete'), - ])), - url(r'^track/', include(stock_tracking_urls)), url(r'^adjust/?', views.StockAdjust.as_view(), name='stock-adjust'), diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 9a47576442..280b1bb533 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -32,7 +32,7 @@ from datetime import datetime, timedelta from company.models import Company, SupplierPart from part.models import Part -from .models import StockItem, StockLocation, StockItemTracking, StockItemAttachment, StockItemTestResult +from .models import StockItem, StockLocation, StockItemTracking import common.settings from common.models import InvenTreeSetting @@ -255,85 +255,6 @@ class StockLocationQRCode(QRCodeView): return None -class StockItemAttachmentCreate(AjaxCreateView): - """ - View for adding a new attachment for a StockItem - """ - - model = StockItemAttachment - form_class = StockForms.EditStockItemAttachmentForm - ajax_form_title = _("Add Stock Item Attachment") - ajax_template_name = "modal_form.html" - - def save(self, form, **kwargs): - """ Record the user that uploaded the attachment """ - - attachment = form.save(commit=False) - attachment.user = self.request.user - attachment.save() - - def get_data(self): - return { - 'success': _("Added attachment") - } - - def get_initial(self): - """ - Get initial data for the new StockItem attachment object. - - - Client must provide a valid StockItem ID - """ - - initials = super().get_initial() - - try: - initials['stock_item'] = StockItem.objects.get(id=self.request.GET.get('item', None)) - except (ValueError, StockItem.DoesNotExist): - pass - - return initials - - def get_form(self): - - form = super().get_form() - form.fields['stock_item'].widget = HiddenInput() - - return form - - -class StockItemAttachmentEdit(AjaxUpdateView): - """ - View for editing a StockItemAttachment object. - """ - - model = StockItemAttachment - form_class = StockForms.EditStockItemAttachmentForm - ajax_form_title = _("Edit Stock Item Attachment") - - def get_form(self): - - form = super().get_form() - form.fields['stock_item'].widget = HiddenInput() - - return form - - -class StockItemAttachmentDelete(AjaxDeleteView): - """ - View for deleting a StockItemAttachment object. - """ - - model = StockItemAttachment - ajax_form_title = _("Delete Stock Item Attachment") - ajax_template_name = "attachment_delete.html" - context_object_name = "attachment" - - def get_data(self): - return { - 'danger': _("Deleted attachment"), - } - - class StockItemAssignToCustomer(AjaxUpdateView): """ View for manually assigning a StockItem to a Customer @@ -434,74 +355,6 @@ class StockItemDeleteTestData(AjaxUpdateView): return self.renderJsonResponse(request, form, data) -class StockItemTestResultCreate(AjaxCreateView): - """ - View for adding a new StockItemTestResult - """ - - model = StockItemTestResult - form_class = StockForms.EditStockItemTestResultForm - ajax_form_title = _("Add Test Result") - - def save(self, form, **kwargs): - """ - Record the user that uploaded the test result - """ - - result = form.save(commit=False) - result.user = self.request.user - result.save() - - def get_initial(self): - - initials = super().get_initial() - - try: - stock_id = self.request.GET.get('stock_item', None) - initials['stock_item'] = StockItem.objects.get(pk=stock_id) - except (ValueError, StockItem.DoesNotExist): - pass - - initials['test'] = self.request.GET.get('test', '') - - return initials - - def get_form(self): - - form = super().get_form() - form.fields['stock_item'].widget = HiddenInput() - - return form - - -class StockItemTestResultEdit(AjaxUpdateView): - """ - View for editing a StockItemTestResult - """ - - model = StockItemTestResult - form_class = StockForms.EditStockItemTestResultForm - ajax_form_title = _("Edit Test Result") - - def get_form(self): - - form = super().get_form() - - form.fields['stock_item'].widget = HiddenInput() - - return form - - -class StockItemTestResultDelete(AjaxDeleteView): - """ - View for deleting a StockItemTestResult - """ - - model = StockItemTestResult - ajax_form_title = _("Delete Test Result") - context_object_name = "result" - - class StockExportOptions(AjaxView): """ Form for selecting StockExport options """ @@ -1212,27 +1065,6 @@ class StockAdjust(AjaxView, FormMixin): return _("Deleted {n} stock items").format(n=count) -class StockItemEditStatus(AjaxUpdateView): - """ - View for editing stock item status field - """ - - model = StockItem - form_class = StockForms.EditStockItemStatusForm - ajax_form_title = _('Edit Stock Item Status') - - def save(self, object, form, **kwargs): - """ - Override the save method, to track the user who updated the model - """ - - item = form.save(commit=False) - - item.save(user=self.request.user) - - return item - - class StockItemEdit(AjaxUpdateView): """ View for editing details of a single StockItem diff --git a/InvenTree/templates/InvenTree/index.html b/InvenTree/templates/InvenTree/index.html index 434d652728..a3d793dd26 100644 --- a/InvenTree/templates/InvenTree/index.html +++ b/InvenTree/templates/InvenTree/index.html @@ -128,6 +128,7 @@ loadSimplePartTable("#table-bom-validation", "{% url 'api-part-list' %}", { addHeaderTitle('{% trans "Stock" %}'); addHeaderAction('recently-updated-stock', '{% trans "Recently Updated" %}', 'fa-clock'); addHeaderAction('low-stock', '{% trans "Low Stock" %}', 'fa-shopping-cart'); +addHeaderAction('depleted-stock', '{% trans "Depleted Stock" %}', 'fa-times'); addHeaderAction('stock-to-build', '{% trans "Required for Build Orders" %}', 'fa-bullhorn'); loadStockTable($('#table-recently-updated-stock'), { @@ -170,6 +171,13 @@ loadSimplePartTable("#table-low-stock", "{% url 'api-part-list' %}", { name: "low_stock_parts", }); +loadSimplePartTable("#table-depleted-stock", "{% url 'api-part-list' %}", { + params: { + depleted_stock: true, + }, + name: "depleted_stock_parts", +}); + loadSimplePartTable("#table-stock-to-build", "{% url 'api-part-list' %}", { params: { stock_to_build: true, diff --git a/InvenTree/templates/attachment_table.html b/InvenTree/templates/attachment_table.html index 35b114cc05..18a4da9acc 100644 --- a/InvenTree/templates/attachment_table.html +++ b/InvenTree/templates/attachment_table.html @@ -10,35 +10,6 @@
                  - - - - - - - - - - {% for attachment in attachments %} - - - - - - - {% endfor %} - +
                  {% trans "File" %}{% trans "Comment" %}{% trans "Uploaded" %}
                  {{ attachment.basename }}{{ attachment.comment }} - {% if attachment.upload_date %}{{ attachment.upload_date }}{% endif %} - {% if attachment.user %}{{ attachment.user.username }}{% endif %} - -
                  - - -
                  -
                  \ No newline at end of file diff --git a/InvenTree/templates/base.html b/InvenTree/templates/base.html index 65712b7394..76104d8fe2 100644 --- a/InvenTree/templates/base.html +++ b/InvenTree/templates/base.html @@ -40,8 +40,8 @@ - - + + @@ -136,7 +136,7 @@ - + @@ -144,11 +144,14 @@ - + + + + diff --git a/InvenTree/InvenTree/static/script/inventree/api.js b/InvenTree/templates/js/api.js similarity index 89% rename from InvenTree/InvenTree/static/script/inventree/api.js rename to InvenTree/templates/js/api.js index b43bcc8419..5e8905a1dd 100644 --- a/InvenTree/InvenTree/static/script/inventree/api.js +++ b/InvenTree/templates/js/api.js @@ -18,7 +18,15 @@ function getCookie(name) { } function inventreeGet(url, filters={}, options={}) { + + // Middleware token required for data update + //var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val(); + var csrftoken = getCookie('csrftoken'); + return $.ajax({ + beforeSend: function(xhr, settings) { + xhr.setRequestHeader('X-CSRFToken', csrftoken); + }, url: url, type: 'GET', data: filters, @@ -103,10 +111,11 @@ function inventreePut(url, data={}, options={}) { } }, error: function(xhr, ajaxOptions, thrownError) { - console.error('Error on UPDATE to ' + url); - console.error(thrownError); if (options.error) { options.error(xhr, ajaxOptions, thrownError); + } else { + console.error(`Error on ${method} to '${url}' - STATUS ${xhr.status}`); + console.error(thrownError); } }, complete: function(xhr, status) { diff --git a/InvenTree/templates/js/attachment.js b/InvenTree/templates/js/attachment.js new file mode 100644 index 0000000000..4b9d522a59 --- /dev/null +++ b/InvenTree/templates/js/attachment.js @@ -0,0 +1,86 @@ +{% load i18n %} + +function reloadAttachmentTable() { + + $('#attachment-table').bootstrapTable("refresh"); +} + + +function loadAttachmentTable(url, options) { + + var table = options.table || '#attachment-table'; + + $(table).inventreeTable({ + url: url, + name: options.name || 'attachments', + formatNoMatches: function() { return '{% trans "No attachments found" %}'}, + sortable: true, + search: false, + queryParams: options.filters || {}, + onPostBody: function() { + // Add callback for 'edit' button + $(table).find('.button-attachment-edit').click(function() { + var pk = $(this).attr('pk'); + + if (options.onEdit) { + options.onEdit(pk); + } + }); + + // Add callback for 'delete' button + $(table).find('.button-attachment-delete').click(function() { + var pk = $(this).attr('pk'); + + if (options.onDelete) { + options.onDelete(pk); + } + }); + }, + columns: [ + { + field: 'attachment', + title: '{% trans "File" %}', + formatter: function(value, row) { + + var split = value.split('/'); + + return renderLink(split[split.length - 1], value); + } + }, + { + field: 'comment', + title: '{% trans "Comment" %}', + }, + { + field: 'upload_date', + title: '{% trans "Upload Date" %}', + }, + { + field: 'actions', + formatter: function(value, row) { + var html = ''; + + html = `
                  `; + + html += makeIconButton( + 'fa-edit icon-blue', + 'button-attachment-edit', + row.pk, + '{% trans "Edit attachment" %}', + ); + + html += makeIconButton( + 'fa-trash-alt icon-red', + 'button-attachment-delete', + row.pk, + '{% trans "Delete attachment" %}', + ); + + html += `
                  `; + + return html; + } + } + ] + }); +} \ No newline at end of file diff --git a/InvenTree/templates/js/bom.js b/InvenTree/templates/js/bom.js index 665379d8d5..980dd82ccc 100644 --- a/InvenTree/templates/js/bom.js +++ b/InvenTree/templates/js/bom.js @@ -514,14 +514,13 @@ function loadBomTable(table, options) { var pk = $(this).attr('pk'); var url = `/part/bom/${pk}/delete/`; - launchModalForm( - url, - { - success: function() { - reloadBomTable(table); - } + constructForm(`/api/bom/${pk}/`, { + method: 'DELETE', + title: '{% trans "Delete BOM Item" %}', + onSuccess: function() { + reloadBomTable(table); } - ); + }); }); table.on('click', '.bom-edit-button', function() { diff --git a/InvenTree/templates/js/company.js b/InvenTree/templates/js/company.js index 078b40f4b9..d28bca5547 100644 --- a/InvenTree/templates/js/company.js +++ b/InvenTree/templates/js/company.js @@ -1,5 +1,74 @@ {% load i18n %} + +// Returns a default form-set for creating / editing a Company object +function companyFormFields(options={}) { + + return { + name: {}, + description: {}, + website: { + icon: 'fa-globe', + }, + address: { + icon: 'fa-envelope', + }, + currency: { + icon: 'fa-dollar-sign', + }, + phone: { + icon: 'fa-phone', + }, + email: { + icon: 'fa-at', + }, + contact: { + icon: 'fa-address-card', + }, + is_supplier: {}, + is_manufacturer: {}, + is_customer: {} + }; +} + + +function editCompany(pk, options={}) { + + var fields = options.fields || companyFormFields(); + + constructForm( + `/api/company/${pk}/`, + { + method: 'PATCH', + fields: fields, + reload: true, + title: '{% trans "Edit Company" %}', + } + ); +}; + +/* + * Launches a form to create a new company. + * As this can be called from many different contexts, + * we abstract it here! + */ +function createCompany(options={}) { + + // Default field set + var fields = options.fields || companyFormFields(); + + constructForm( + '{% url "api-company-list" %}', + { + method: 'POST', + fields: fields, + follow: true, + title: '{% trans "Add new Company" %}', + } + ); +} + + function loadCompanyTable(table, url, options={}) { /* * Load company listing data into specified table. @@ -101,6 +170,61 @@ function loadCompanyTable(table, url, options={}) { } +function deleteManufacturerParts(selections, options={}) { + + if (selections.length == 0) { + return; + } + + var parts = []; + + var text = ` +
                  +

                  {% trans "The following manufacturer parts will be deleted" %}:

                  +
                    `; + + selections.forEach(function(item) { + parts.push(item.pk); + + text += ` +
                  • +

                    ${item.MPN} - ${item.part_detail.full_name}

                    +
                  • `; + }); + + text += ` +
                  +
                  `; + + showQuestionDialog( + '{% trans "Delete Manufacturer Parts" %}', + text, + { + accept_text: '{% trans "Delete" %}', + accept: function() { + + // Delete each manufacturer part + var requests = []; + + parts.forEach(function(pk) { + var url = `/api/company/part/manufacturer/${pk}`; + + requests.push(inventreeDelete(url)); + }); + + // Wait for all the requests to complete + $.when.apply($, requests).then(function() { + + if (options.onSuccess) { + options.onSuccess(); + } + }) + } + } + ); +} + + function loadManufacturerPartTable(table, url, options) { /* * Load manufacturer part table @@ -228,7 +352,7 @@ function loadManufacturerPartParameterTable(table, url, options) { { checkbox: true, switchable: false, - visible: false, + visible: true, }, { field: 'name', @@ -273,27 +397,28 @@ function loadManufacturerPartParameterTable(table, url, options) { $(table).find('.button-parameter-edit').click(function() { var pk = $(this).attr('pk'); - launchModalForm( - `/manufacturer-part/parameter/${pk}/edit/`, - { - success: function() { - $(table).bootstrapTable('refresh'); - } + constructForm(`/api/company/part/manufacturer/parameter/${pk}/`, { + fields: { + name: {}, + value: {}, + units: {}, + }, + title: '{% trans "Edit Parameter" %}', + onSuccess: function() { + $(table).bootstrapTable('refresh'); } - ); - + }); }); $(table).find('.button-parameter-delete').click(function() { var pk = $(this).attr('pk'); - launchModalForm( - `/manufacturer-part/parameter/${pk}/delete/`, - { - success: function() { - $(table).bootstrapTable('refresh'); - } + constructForm(`/api/company/part/manufacturer/parameter/${pk}/`, { + method: 'DELETE', + title: '{% trans "Delete Parameter" %}', + onSuccess: function() { + $(table).bootstrapTable('refresh'); } - ); + }); }); } }); diff --git a/InvenTree/templates/js/forms.js b/InvenTree/templates/js/forms.js new file mode 100644 index 0000000000..ac3bcefd04 --- /dev/null +++ b/InvenTree/templates/js/forms.js @@ -0,0 +1,1629 @@ +{% load i18n %} +{% load inventree_extras %} + +/** + * + * This file contains code for rendering (and managing) HTML forms + * which are served via the django-drf API. + * + * The django DRF library provides an OPTIONS method for each API endpoint, + * which allows us to introspect the available fields at any given endpoint. + * + * The OPTIONS method provides the following information for each available field: + * + * - Field name + * - Field label (translated) + * - Field help text (translated) + * - Field type + * - Read / write status + * - Field required status + * - min_value / max_value + * + */ + +/* + * Return true if the OPTIONS specify that the user + * can perform a GET method at the endpoint. + */ +function canView(OPTIONS) { + + if ('actions' in OPTIONS) { + return ('GET' in OPTIONS.actions); + } else { + return false; + } +} + + +/* + * Return true if the OPTIONS specify that the user + * can perform a POST method at the endpoint + */ +function canCreate(OPTIONS) { + + if ('actions' in OPTIONS) { + return ('POST' in OPTIONS.actions); + } else { + return false; + } +} + + +/* + * Return true if the OPTIONS specify that the user + * can perform a PUT or PATCH method at the endpoint + */ +function canChange(OPTIONS) { + + if ('actions' in OPTIONS) { + return ('PUT' in OPTIONS.actions || 'PATCH' in OPTIONS.actions); + } else { + return false; + } +} + + +/* + * Return true if the OPTIONS specify that the user + * can perform a DELETE method at the endpoint + */ +function canDelete(OPTIONS) { + + if ('actions' in OPTIONS) { + return ('DELETE' in OPTIONS.actions); + } else { + return false; + } +} + + +/* + * Get the API endpoint options at the provided URL, + * using a HTTP options request. + */ +function getApiEndpointOptions(url, callback, options) { + + // Return the ajax request object + $.ajax({ + url: url, + type: 'OPTIONS', + contentType: 'application/json', + dataType: 'json', + accepts: { + json: 'application/json', + }, + success: callback, + error: function(request, status, error) { + // TODO: Handle error + console.log(`ERROR in getApiEndpointOptions at '${url}'`); + } + }); +} + + +/* + * Construct a 'creation' (POST) form, to create a new model in the database. + * + * arguments: + * - fields: The 'actions' object provided by the OPTIONS endpoint + * + * options: + * - + */ +function constructCreateForm(fields, options) { + + // Check if default values were provided for any fields + for (const name in fields) { + + var field = fields[name]; + + var field_options = options.fields[name] || {}; + + // If a 'value' is not provided for the field, + if (field.value == null) { + + if ('value' in field_options) { + // Client has specified the default value for the field + field.value = field_options.value; + } else if (field.default != null) { + // OPTIONS endpoint provided default value for this field + field.value = field.default; + } + } + } + + // We should have enough information to create the form! + constructFormBody(fields, options); +} + + +/* + * Construct a 'change' (PATCH) form, to create a new model in the database. + * + * arguments: + * - fields: The 'actions' object provided by the OPTIONS endpoint + * + * options: + * - + */ +function constructChangeForm(fields, options) { + + // Request existing data from the API endpoint + $.ajax({ + url: options.url, + type: 'GET', + contentType: 'application/json', + dataType: 'json', + accepts: { + json: 'application/json', + }, + success: function(data) { + + // Push existing 'value' to each field + for (const field in data) { + + if (field in fields) { + fields[field].value = data[field]; + } + } + + // Store the entire data object + options.instance = data; + + constructFormBody(fields, options); + }, + error: function(request, status, error) { + // TODO: Handle error here + console.log(`ERROR in constructChangeForm at '${options.url}'`); + } + }); +} + + +/* + * Construct a 'delete' form, to remove a model instance from the database. + * + * arguments: + * - fields: The 'actions' object provided by the OPTIONS request + * - options: The 'options' object provided by the client + */ +function constructDeleteForm(fields, options) { + + // Force the "confirm" property if not set + if (!('confirm' in options)) { + options.confirm = true; + } + + // Request existing data from the API endpoint + // This data can be used to render some information on the form + $.ajax({ + url: options.url, + type: 'GET', + contentType: 'application/json', + dataType: 'json', + accepts: { + json: 'application/json', + }, + success: function(data) { + + // Store the instance data + options.instance = data; + + constructFormBody(fields, options); + }, + error: function(request, status, error) { + // TODO: Handle error here + console.log(`ERROR in constructDeleteForm at '${options.url}`); + } + }); +} + + +/* + * Request API OPTIONS data from the server, + * and construct a modal form based on the response. + * + * url: API URL which defines form data + * options: + * - method: The HTTP method e.g. 'PUT', 'POST', 'DELETE' (default='PATCH') + * - title: The form title + * - submitText: Text for the "submit" button + * - closeText: Text for the "close" button + * - fields: list of fields to display, with the following options + * - filters: API query filters + * - onEdit: callback when field is edited + * - secondary: Define a secondary modal form for this field + * - label: Specify custom label + * - help_text: Specify custom help_text + * - placeholder: Specify custom placeholder text + * - value: Specify initial value + * - hidden: Set to true to hide the field + * - icon: font-awesome icon to display before the field + * - prefix: Custom HTML prefix to display before the field + * - focus: Name of field to focus on when modal is displayed + * - preventClose: Set to true to prevent form from closing on success + * - onSuccess: callback function when form action is successful + * - follow: If a 'url' is provided by the API on success, redirect to it + * - redirect: A URL to redirect to after form success + * - reload: Set to true to reload the current page after form success + * - confirm: Set to true to require a "confirm" button + * - confirmText: Text for confirm button (default = "Confirm") + * + */ +function constructForm(url, options) { + + // Save the URL + options.url = url; + + // Default HTTP method + options.method = options.method || 'PATCH'; + + // Request OPTIONS endpoint from the API + getApiEndpointOptions(url, function(OPTIONS) { + + /* + * Determine what "type" of form we want to construct, + * based on the requested action. + * + * First we must determine if the user has the correct permissions! + */ + + switch (options.method) { + case 'POST': + if (canCreate(OPTIONS)) { + constructCreateForm(OPTIONS.actions.POST, options); + } else { + // User does not have permission to POST to the endpoint + showAlertDialog( + '{% trans "Action Prohibited" %}', + '{% trans "Create operation not allowed" %}' + ); + console.log(`'POST action unavailable at ${url}`); + } + break; + case 'PUT': + case 'PATCH': + if (canChange(OPTIONS)) { + constructChangeForm(OPTIONS.actions.PUT, options); + } else { + // User does not have permission to PUT/PATCH to the endpoint + showAlertDialog( + '{% trans "Action Prohibited" %}', + '{% trans "Update operation not allowed" %}' + ); + console.log(`${options.method} action unavailable at ${url}`); + } + break; + case 'DELETE': + if (canDelete(OPTIONS)) { + constructDeleteForm(OPTIONS.actions.DELETE, options); + } else { + // User does not have permission to DELETE to the endpoint + showAlertDialog( + '{% trans "Action Prohibited" %}', + '{% trans "Delete operation not allowed" %}' + ); + console.log(`DELETE action unavailable at ${url}`); + } + break; + case 'GET': + if (canView(OPTIONS)) { + // TODO? + } else { + // User does not have permission to GET to the endpoint + showAlertDialog( + '{% trans "Action Prohibited" %}', + '{% trans "View operation not allowed" %}' + ); + console.log(`GET action unavailable at ${url}`); + } + break; + default: + console.log(`constructForm() called with invalid method '${options.method}'`); + break; + } + }); +} + + +/* + * Construct a modal form based on the provided options + * + * arguments: + * - fields: The endpoint description returned from the OPTIONS request + * - options: form options object provided by the client. + */ +function constructFormBody(fields, options) { + + var html = ''; + + // Client must provide set of fields to be displayed, + // otherwise *all* fields will be displayed + var displayed_fields = options.fields || fields; + + // Provide each field object with its own name + for(field in fields) { + fields[field].name = field; + + var field_options = displayed_fields[field]; + + // Copy custom options across to the fields object + if (field_options) { + + // Override existing query filters (if provided!) + fields[field].filters = Object.assign(fields[field].filters || {}, field_options.filters); + + // Secondary modal options + fields[field].secondary = field_options.secondary; + + // Edit callback + fields[field].onEdit = field_options.onEdit; + + // Custom help_text + if (field_options.help_text) { + fields[field].help_text = field_options.help_text; + } + + // Custom label + if (field_options.label) { + fields[field].label = field_options.label; + } + + // Custom placeholder + if (field_options.placeholder) { + fields[field].placeholder = field_options.placeholder; + } + + // Field prefix + if (field_options.prefix) { + fields[field].prefix = field_options.prefix; + } else if (field_options.icon) { + // Specify icon like 'fa-user' + fields[field].prefix = ``; + } + + fields[field].hidden = field_options.hidden; + + if (field_options.read_only != null) { + fields[field].read_only = field_options.read_only; + } + } + } + + // Construct an ordered list of field names + var field_names = []; + + for (var name in displayed_fields) { + + // Only push names which are actually in the set of fields + if (name in fields) { + field_names.push(name); + } else { + console.log(`WARNING: '${name}' does not match a valid field name.`); + } + } + + // Push the ordered field names into the options, + // allowing successive functions to access them. + options.field_names = field_names; + + // Render selected fields + + for (var idx = 0; idx < field_names.length; idx++) { + + var name = field_names[idx]; + + var field = fields[name]; + + switch (field.type) { + // Skip field types which are simply not supported + case 'nested object': + continue; + default: + break; + } + + var f = constructField(name, field, options); + + html += f; + } + + // TODO: Dynamically create the modals, + // so that we can have an infinite number of stacks! + + // Create a new modal if one does not exists + if (!options.modal) { + options.modal = createNewModal(options); + } + + var modal = options.modal; + + modalEnable(modal, true); + + // Insert generated form content + $(modal).find('.modal-form-content').html(html); + + // Clear any existing buttons from the modal + $(modal).find('#modal-footer-buttons').html(''); + + // Insert "confirm" button (if required) + if (options.confirm) { + insertConfirmButton(options); + } + + // Display the modal + $(modal).modal('show'); + + updateFieldValues(fields, options); + + // Setup related fields + initializeRelatedFields(fields, options); + + // Attach edit callbacks (if required) + addFieldCallbacks(fields, options); + + // Attach clear callbacks (if required) + addClearCallbacks(fields, options); + + attachToggle(modal); + + $(modal + ' .select2-container').addClass('select-full-width'); + $(modal + ' .select2-container').css('width', '100%'); + + modalShowSubmitButton(modal, true); + + $(modal).on('click', '#modal-form-submit', function() { + + submitFormData(fields, options); + }); +} + + +// Add a "confirm" checkbox to the modal +// The "submit" button will be disabled unless "confirm" is checked +function insertConfirmButton(options) { + + var message = options.confirmMessage || '{% trans "Confirm" %}'; + + var confirm = ` + + ${message} + + `; + + $(options.modal).find('#modal-footer-buttons').append(confirm); + + // Disable the 'submit' button + $(options.modal).find('#modal-form-submit').prop('disabled', true); + + // Trigger event + $(options.modal).find('#modal-confirm').change(function() { + var enabled = this.checked; + + $(options.modal).find('#modal-form-submit').prop('disabled', !enabled); + }); +} + + +/* + * Submit form data to the server. + * + */ +function submitFormData(fields, options) { + + // Form data to be uploaded to the server + // Only used if file / image upload is required + var form_data = new FormData(); + + var data = {}; + + var has_files = false; + + // Extract values for each field + options.field_names.forEach(function(name) { + + var field = fields[name] || null; + + if (field) { + + var value = getFormFieldValue(name, field, options); + + // Handle file inputs + if (field.type == 'image upload' || field.type == 'file upload') { + + var field_el = $(options.modal).find(`#id_${name}`)[0]; + + var field_files = field_el.files; + + if (field_files.length > 0) { + // One file per field, please! + var file = field_files[0]; + + form_data.append(name, file); + + has_files = true; + } + } else { + + // Normal field (not a file or image) + form_data.append(name, value); + + data[name] = value; + } + } else { + console.log(`WARNING: Could not find field matching '${name}'`); + } + }); + + var upload_func = inventreePut; + + if (has_files) { + upload_func = inventreeFormDataUpload; + data = form_data; + } + + // Submit data + upload_func( + options.url, + data, + { + method: options.method, + success: function(response, status) { + handleFormSuccess(response, options); + }, + error: function(xhr, status, thrownError) { + + switch (xhr.status) { + case 400: // Bad request + handleFormErrors(xhr.responseJSON, fields, options); + break; + case 0: // No response + $(options.modal).modal('hide'); + showAlertDialog( + '{% trans "No Response" %}', + '{% trans "No response from the InvenTree server" %}', + ); + break; + case 401: // Not authenticated + $(options.modal).modal('hide'); + showAlertDialog( + '{% trans "Error 401: Not Authenticated" %}', + '{% trans "Authentication credentials not supplied" %}', + ); + break; + case 403: // Permission denied + $(options.modal).modal('hide'); + showAlertDialog( + '{% trans "Error 403: Permission Denied" %}', + '{% trans "You do not have the required permissions to access this function" %}', + ); + break; + case 404: // Resource not found + $(options.modal).modal('hide'); + showAlertDialog( + '{% trans "Error 404: Resource Not Found" %}', + '{% trans "The requested resource could not be located on the server" %}', + ); + break; + case 408: // Timeout + $(options.modal).modal('hide'); + showAlertDialog( + '{% trans "Error 408: Timeout" %}', + '{% trans "Connection timeout while requesting data from server" %}', + ); + break; + default: + $(options.modal).modal('hide'); + + showAlertDialog('{% trans "Error requesting form data" %}', renderErrorMessage(xhr)); + + console.log(`WARNING: Unhandled response code - ${xhr.status}`); + break; + } + } + } + ); +} + + +/* + * Update (set) the field values based on the specified data. + * + * Iterate through each of the displayed fields, + * and set the 'val' attribute of each one. + * + */ +function updateFieldValues(fields, options) { + + for (var idx = 0; idx < options.field_names.length; idx++) { + + var name = options.field_names[idx]; + + var field = fields[name] || null; + + if (field == null) { continue; } + + var value = field.value; + + if (value == null) { + value = field.default; + } + + if (value == null) { continue; } + + updateFieldValue(name, value, field, options); + } +} + + +function updateFieldValue(name, value, field, options) { + var el = $(options.modal).find(`#id_${name}`); + + switch (field.type) { + case 'boolean': + el.prop('checked', value); + break; + case 'related field': + // Clear? + if (value == null && !field.required) { + el.val(null).trigger('change'); + } + // TODO - Specify an actual value! + break; + case 'file upload': + case 'image upload': + break; + default: + el.val(value); + break; + } +} + + +/* + * Extract and field value before sending back to the server + * + * arguments: + * - name: The name of the field + * - field: The field specification provided from the OPTIONS request + * - options: The original options object provided by the client + */ +function getFormFieldValue(name, field, options) { + + // Find the HTML element + var el = $(options.modal).find(`#id_${name}`); + + var value = null; + + switch (field.type) { + case 'boolean': + value = el.is(":checked"); + break; + case 'date': + case 'datetime': + value = el.val(); + + // Ensure empty values are sent as nulls + if (!value || value.length == 0) { + value = null; + } + break; + default: + value = el.val(); + break; + } + + return value; +} + + +/* + * Handle successful form posting + * + * arguments: + * - response: The JSON response object from the server + * - options: The original options object provided by the client + */ +function handleFormSuccess(response, options) { + + // Close the modal + if (!options.preventClose) { + // TODO: Actually just *delete* the modal, + // rather than hiding it!! + $(options.modal).modal('hide'); + } + + if (options.onSuccess) { + // Callback function + options.onSuccess(response, options); + } + + if (options.follow && response.url) { + // Follow the returned URL + window.location.href = response.url; + } else if (options.reload) { + // Reload the current page + location.reload(); + } else if (options.redirect) { + // Redirect to a specified URL + window.location.href = options.redirect; + } +} + + + +/* + * Remove all error text items from the form + */ +function clearFormErrors(options) { + + // Remove the individual error messages + $(options.modal).find('.form-error-message').remove(); + + // Remove the "has error" class + $(options.modal).find('.has-error').removeClass('has-error'); + + // Hide the 'non field errors' + $(options.modal).find('#non-field-errors').html(''); +} + + +/* + * Display form error messages as returned from the server. + * + * arguments: + * - errors: The JSON error response from the server + * - fields: The form data object + * - options: Form options provided by the client + */ +function handleFormErrors(errors, fields, options) { + + // Remove any existing error messages from the form + clearFormErrors(options); + + var non_field_errors = $(options.modal).find('#non-field-errors'); + + non_field_errors.append( + `
                  + {% trans "Form errors exist" %} +
                  ` + ); + + // Non-field errors? + if ('non_field_errors' in errors) { + + var nfe = errors.non_field_errors; + + for (var idx = 0; idx < nfe.length; idx++) { + var err = nfe[idx]; + + var html = ` +
                  + ${err} +
                  `; + + non_field_errors.append(html); + } + } + + for (field_name in errors) { + if (field_name in fields) { + + // Add the 'has-error' class + $(options.modal).find(`#div_id_${field_name}`).addClass('has-error'); + + var field_dom = $(options.modal).find(`#errors-${field_name}`); // $(options.modal).find(`#id_${field_name}`); + + var field_errors = errors[field_name]; + + // Add an entry for each returned error message + for (var idx = field_errors.length-1; idx >= 0; idx--) { + + var error_text = field_errors[idx]; + + var html = ` + + ${error_text} + `; + + field_dom.append(html); + } + + } else { + console.log(`WARNING: handleFormErrors found no match for field '${field_name}'`); + } + } + +} + + +/* + * Attach callbacks to specified fields, + * triggered after the field value is edited. + * + * Callback function is called with arguments (name, field, options) + */ +function addFieldCallbacks(fields, options) { + + for (var idx = 0; idx < options.field_names.length; idx++) { + + var name = options.field_names[idx]; + + var field = fields[name]; + + if (!field || !field.onEdit) continue; + + addFieldCallback(name, field, options); + } +} + + +function addFieldCallback(name, field, options) { + + $(options.modal).find(`#id_${name}`).change(function() { + field.onEdit(name, field, options); + }); +} + + +function addClearCallbacks(fields, options) { + + for (var idx = 0; idx < options.field_names.length; idx++) { + + var name = options.field_names[idx]; + + var field = fields[name]; + + if (!field || field.required) continue; + + addClearCallback(name, field, options); + } +} + + +function addClearCallback(name, field, options) { + + $(options.modal).find(`#clear_${name}`).click(function() { + updateFieldValue(name, null, field, options); + }); +} + + +function initializeRelatedFields(fields, options) { + + var field_names = options.field_names; + + for (var idx = 0; idx < field_names.length; idx++) { + + var name = field_names[idx]; + + var field = fields[name] || null; + + if (!field || field.hidden) continue; + + switch (field.type) { + case 'related field': + initializeRelatedField(name, field, options); + break; + case 'choice': + initializeChoiceField(name, field, options); + break; + } + } +} + + +/* + * Add a button to launch a secondary modal, to create a new modal instance. + * + * arguments: + * - name: The name of the field + * - field: The field data object + * - options: The options object provided by the client + */ +function addSecondaryModal(name, field, options) { + + var secondary = field.secondary; + + var html = ` + +
                  + ${secondary.label || secondary.title} +
                  +
                  `; + + $(options.modal).find(`label[for="id_${name}"]`).append(html); + + // TODO: Launch a callback + $(options.modal).find(`#btn-new-${name}`).click(function() { + + if (secondary.callback) { + // A "custom" callback can be specified for the button + secondary.callback(field, options); + } else if (secondary.api_url) { + // By default, a new modal form is created, with the parameters specified + // The parameters match the "normal" form creation parameters + + secondary.onSuccess = function(data, opts) { + setRelatedFieldData(name, data, options); + }; + + constructForm(secondary.api_url, secondary); + } + }); +} + + +/* + * Initializea single related-field + * + * argument: + * - modal: DOM identifier for the modal window + * - name: name of the field e.g. 'location' + * - field: Field definition from the OPTIONS request + * - options: Original options object provided by the client + */ +function initializeRelatedField(name, field, options) { + + if (!field.api_url) { + // TODO: Provide manual api_url option? + console.log(`Related field '${name}' missing 'api_url' parameter.`); + return; + } + + // Find the select element and attach a select2 to it + var select = $(options.modal).find(`#id_${name}`); + + // Add a button to launch a 'secondary' modal + if (field.secondary != null) { + addSecondaryModal(name, field, options); + } + + // TODO: Add 'placeholder' support for entry select2 fields + + // limit size for AJAX requests + var pageSize = options.pageSize || 25; + + select.select2({ + placeholder: '', + dropdownParent: $(options.modal), + dropdownAutoWidth: false, + ajax: { + url: field.api_url, + dataType: 'json', + delay: 250, + cache: true, + data: function(params) { + + if (!params.page) { + offset = 0; + } else { + offset = (params.page - 1) * pageSize; + } + + // Custom query filters can be specified against each field + var query = field.filters || {}; + + // Add search and pagination options + query.search = params.term; + query.offset = offset; + query.limit = pageSize; + + return query; + }, + processResults: function(response) { + // Convert the returned InvenTree data into select2-friendly format + + var data = []; + + var more = false; + + if ('count' in response && 'results' in response) { + // Response is paginated + data = response.results; + + // Any more data available? + if (response.next) { + more = true; + } + + } else { + // Non-paginated response + data = response; + } + + // Each 'row' must have the 'id' attribute + for (var idx = 0; idx < data.length; idx++) { + data[idx].id = data[idx].pk; + } + + // Ref: https://select2.org/data-sources/formats + var results = { + results: data, + pagination: { + more: more, + } + }; + + return results; + }, + }, + templateResult: function(item, container) { + + // Extract 'instance' data passed through from an initial value + // Or, use the raw 'item' data as a backup + var data = item; + + if (item.element && item.element.instance) { + data = item.element.instance; + } + + if (!data.pk) { + return $(searching()); + } + + // Custom formatting for the search results + if (field.model) { + // If the 'model' is specified, hand it off to the custom model render + var html = renderModelData(name, field.model, data, field, options); + return $(html); + } else { + // Return a simple renderering + console.log(`WARNING: templateResult() missing 'field.model' for '${name}'`); + return `${name} - ${item.id}`; + } + }, + templateSelection: function(item, container) { + + // Extract 'instance' data passed through from an initial value + // Or, use the raw 'item' data as a backup + var data = item; + + if (item.element && item.element.instance) { + data = item.element.instance; + } + + if (!data.pk) { + return field.placeholder || ''; + return $(searching()); + } + + // Custom formatting for selected item + if (field.model) { + // If the 'model' is specified, hand it off to the custom model render + var html = renderModelData(name, field.model, data, field, options); + return $(html); + } else { + // Return a simple renderering + console.log(`WARNING: templateSelection() missing 'field.model' for '${name}'`); + return `${name} - ${item.id}`; + } + } + }); + + // If a 'value' is already defined, grab the model info from the server + if (field.value) { + var pk = field.value; + var url = `${field.api_url}/${pk}/`.replace('//', '/'); + + inventreeGet(url, {}, { + success: function(data) { + setRelatedFieldData(name, data, options); + } + }); + } +} + + +/* + * Set the value of a select2 instace for a "related field", + * e.g. with data returned from a secondary modal + * + * arguments: + * - name: The name of the field + * - data: JSON data representing the model instance + * - options: The modal form specifications + */ +function setRelatedFieldData(name, data, options) { + + var select = $(options.modal).find(`#id_${name}`); + + var option = new Option(name, data.pk, true, true); + + // Assign the JSON data to the 'instance' attribute, + // so we can access and render it later + option.instance = data; + + select.append(option).trigger('change'); + + select.trigger({ + type: 'select2:select', + params: { + data: data + } + }); +} + + +function initializeChoiceField(name, field, options) { + + var select = $(options.modal).find(`#id_${name}`); + + select.select2({ + dropdownAutoWidth: false, + dropdownParent: $(options.modal), + }); +} + + +// Render a 'no results' element +function searching() { + return `{% trans "Searching" %}...`; +} + +/* + * Render a "foreign key" model reference in a select2 instance. + * Allows custom rendering with access to the entire serialized object. + * + * arguments: + * - name: The name of the field e.g. 'location' + * - model: The name of the InvenTree model e.g. 'stockitem' + * - data: The JSON data representation of the modal instance (GET request) + * - parameters: The field definition (OPTIONS) request + * - options: Other options provided at time of modal creation by the client + */ +function renderModelData(name, model, data, parameters, options) { + + if (!data) { + return parameters.placeholder || ''; + } + + // TODO: Implement this function for various models + + var html = null; + + var renderer = null; + + // Find a custom renderer + switch (model) { + case 'company': + renderer = renderCompany; + break; + case 'stockitem': + renderer = renderStockItem; + break; + case 'stocklocation': + renderer = renderStockLocation; + break; + case 'part': + renderer = renderPart; + break; + case 'partcategory': + renderer = renderPartCategory; + break; + case 'supplierpart': + renderer = renderSupplierPart; + break; + case 'owner': + renderer = renderOwner; + default: + break; + } + + if (renderer != null) { + html = renderer(name, data, parameters, options); + } + + if (html != null) { + return html; + } else { + console.log(`ERROR: Rendering not implemented for model '${model}'`); + // Simple text rendering + return `${model} - ID ${data.id}`; + } +} + + +/* + * Construct a single form 'field' for rendering in a form. + * + * arguments: + * - name: The 'name' of the field + * - parameters: The field parameters supplied by the DRF OPTIONS method + * + * options: + * - + * + * The function constructs a fieldset which mostly replicates django "crispy" forms: + * + * - Field name + * - Field (depends on specified field type) + * - Field description (help text) + * - Field errors + */ +function constructField(name, parameters, options) { + + var field_name = `id_${name}`; + + // Hidden inputs are rendered without label / help text / etc + if (parameters.hidden) { + return constructHiddenInput(name, parameters, options); + } + + var form_classes = 'form-group'; + + if (parameters.errors) { + form_classes += ' has-error'; + } + + var html = `
                  `; + + // Add a label + html += constructLabel(name, parameters); + + html += `
                  `; + + // Does this input deserve "extra" decorators? + var extra = parameters.prefix != null; + + // Some fields can have 'clear' inputs associated with them + if (!parameters.required && !parameters.read_only) { + switch (parameters.type) { + case 'string': + case 'url': + case 'email': + case 'integer': + case 'float': + case 'decimal': + case 'related field': + case 'date': + extra = true; + break; + default: + break; + } + } + + if (extra) { + html += `
                  `; + + if (parameters.prefix) { + html += `${parameters.prefix}`; + } + } + + html += constructInput(name, parameters, options); + + if (extra) { + + if (!parameters.required) { + html += ` + + + `; + } + + html += `
                  `; // input-group + } + + // Div for error messages + html += `
                  `; + + if (parameters.help_text) { + html += constructHelpText(name, parameters, options); + } + + html += `
                  `; // controls + html += `
                  `; // form-group + + return html; +} + + +/* + * Construct a 'label' div + * + * arguments: + * - name: The name of the field + * - required: Is this a required field? + */ +function constructLabel(name, parameters) { + + var label_classes = 'control-label'; + + if (parameters.required) { + label_classes += ' requiredField'; + } + + var html = ``; + + return html; +} + + +/* + * Construct a form input based on the field parameters + * + * arguments: + * - name: The name of the field + * - parameters: Field parameters returned by the OPTIONS method + * + */ +function constructInput(name, parameters, options) { + + var html = ''; + + var func = null; + + switch (parameters.type) { + case 'boolean': + func = constructCheckboxInput; + break; + case 'string': + case 'url': + case 'email': + func = constructTextInput; + break; + case 'integer': + case 'float': + case 'decimal': + func = constructNumberInput; + break; + case 'choice': + func = constructChoiceInput; + break; + case 'related field': + func = constructRelatedFieldInput; + break; + case 'image upload': + case 'file upload': + func = constructFileUploadInput; + break; + case 'date': + func = constructDateInput; + break; + default: + // Unsupported field type! + break; + } + + if (func != null) { + html = func(name, parameters, options); + } else { + console.log(`WARNING: Unhandled form field type: '${parameters.type}'`); + } + + return html; +} + + +// Construct a set of default input options which apply to all input types +function constructInputOptions(name, classes, type, parameters) { + + var opts = []; + + opts.push(`id='id_${name}'`); + + opts.push(`class='${classes}'`); + + opts.push(`name='${name}'`); + + opts.push(`type='${type}'`); + + // Read only? + if (parameters.read_only) { + opts.push(`readonly=''`); + } + + if (parameters.value) { + // Existing value? + opts.push(`value='${parameters.value}'`); + } else if (parameters.default) { + // Otherwise, a defualt value? + opts.push(`value='${parameters.default}'`); + } + + // Maximum input length + if (parameters.max_length) { + opts.push(`maxlength='${parameters.max_length}'`); + } + + // Minimum input length + if (parameters.min_length) { + opts.push(`minlength='${parameters.min_length}'`); + } + + // Maximum value + if (parameters.max_value != null) { + opts.push(`max='${parameters.max_value}'`); + } + + // Minimum value + if (parameters.min_value != null) { + opts.push(`min='${parameters.min_value}'`); + } + + // Field is required? + if (parameters.required) { + opts.push(`required=''`); + } + + // Placeholder? + if (parameters.placeholder) { + opts.push(`placeholder='${parameters.placeholder}'`); + } + + return ``; +} + + +// Construct a "hidden" input +function constructHiddenInput(name, parameters, options) { + + return constructInputOptions( + name, + 'hiddeninput', + 'hidden', + parameters + ); +} + + +// Construct a "checkbox" input +function constructCheckboxInput(name, parameters, options) { + + return constructInputOptions( + name, + 'checkboxinput', + 'checkbox', + parameters + ); +} + + +// Construct a "text" input +function constructTextInput(name, parameters, options) { + + var classes = ''; + var type = ''; + + switch (parameters.type) { + default: + classes = 'textinput textInput form-control'; + type = 'text'; + break; + case 'url': + classes = 'urlinput form-control'; + type = 'url'; + break; + case 'email': + classes = 'emailinput form-control'; + type = 'email'; + break; + } + + return constructInputOptions( + name, + classes, + type, + parameters + ); +} + + +// Construct a "number" field +function constructNumberInput(name, parameters, options) { + + return constructInputOptions( + name, + 'numberinput form-control', + 'number', + parameters + ); +} + + +// Construct a "choice" input +function constructChoiceInput(name, parameters, options) { + + var html = ``; + + return html; +} + + +/* + * Construct a "related field" input. + * This will create a "select" input which will then, (after form is loaded), + * be converted into a select2 input. + * This will then be served custom data from the API (as required)... + */ +function constructRelatedFieldInput(name, parameters, options) { + + var html = ``; + + // Don't load any options - they will be filled via an AJAX request + + return html; +} + + +/* + * Construct a field for file upload + */ +function constructFileUploadInput(name, parameters, options) { + + var cls = 'clearablefileinput'; + + if (parameters.required) { + cls = 'fileinput'; + } + + return constructInputOptions( + name, + cls, + 'file', + parameters + ); +} + + +/* + * Construct a field for a date input + */ +function constructDateInput(name, parameters, options) { + + return constructInputOptions( + name, + 'dateinput form-control', + 'date', + parameters + ); +} + + +/* + * Construct a 'help text' div based on the field parameters + * + * arguments: + * - name: The name of the field + * - parameters: Field parameters returned by the OPTIONS method + * + */ +function constructHelpText(name, parameters, options) { + + var html = `
                  ${parameters.help_text}
                  `; + + return html; +} \ No newline at end of file diff --git a/InvenTree/templates/js/modals.js b/InvenTree/templates/js/modals.js index 03893a47b8..d0f9f742f8 100644 --- a/InvenTree/templates/js/modals.js +++ b/InvenTree/templates/js/modals.js @@ -1,5 +1,114 @@ {% load i18n %} + +/* + * Create and display a new modal dialog + * + * options: + * - title: Form title to render + * - submitText: Text to render on 'submit' button (default = "Submit") + * - closeText: Text to render on 'close' button (default = "Cancel") + * - focus: Name of field to focus on after launching + */ +function createNewModal(options={}) { + + + var id = 1; + + // Check out what modal forms are already being displayed + $('.inventree-modal').each(function() { + + var split = this.id.split('-'); + var modal_id = parseInt(split[2]); + + if (modal_id >= id) { + id = modal_id + 1; + } + }); + + var html = ` + + `; + + $('body').append(html); + + var modal_name = `#modal-form-${id}`; + + $(modal_name).on('shown.bs.modal', function() { + $(modal_name + ' .modal-form-content').scrollTop(0); + + if (options.focus) { + getFieldByName(modal_name, options.focus).focus(); + } + }); + + // Automatically remove the modal when it is deleted! + $(modal_name).on('hidden.bs.modal', function(e) { + $(modal_name).remove(); + }); + + // Capture "enter" key input + $(modal_name).on('keydown', 'input', function(event) { + + + if (event.keyCode == 13) { + event.preventDefault(); + // Simulate a click on the 'Submit' button + $(modal_name).find("#modal-form-submit").click(); + + return false; + } + }); + + $(modal_name).modal({ + backdrop: 'static', + keyboard: false, + }); + + // Set labels based on supplied options + modalSetTitle(modal_name, options.title || '{% trans "Form Title" %}'); + modalSetSubmitText(modal_name, options.submitText || '{% trans "Submit" %}'); + modalSetCloseText(modal_name, options.cancelText || '{% trans "Cancel" %}'); + + // Return the "name" of the modal + return modal_name; +} + + function makeOption(text, value, title) { /* Format an option for a select element */ @@ -991,8 +1100,6 @@ function hideModalImage() { function showModalImage(image_url) { // Display full-screen modal image - console.log('showing modal image: ' + image_url); - var modal = $('#modal-image-dialog'); // Set image content diff --git a/InvenTree/templates/js/model_renderers.js b/InvenTree/templates/js/model_renderers.js new file mode 100644 index 0000000000..5b838f184b --- /dev/null +++ b/InvenTree/templates/js/model_renderers.js @@ -0,0 +1,155 @@ +{% load i18n %} + +/* + * This file contains functions for rendering various InvenTree database models, + * in particular for displaying them in modal forms in a 'select2' context. + * + * Each renderer is provided with three arguments: + * + * - name: The 'name' of the model instance in the referring model + * - data: JSON data which represents the model instance. Returned via a GET request. + * - parameters: The field parameters provided via an OPTIONS request to the endpoint. + * - options: User options provided by the client + */ + + +// Renderer for "Company" model +function renderCompany(name, data, parameters, options) { + + var html = `${data.name} - ${data.description}`; + + html += `{% trans "Company ID" %}: ${data.pk}`; + + return html; +} + + +// Renderer for "StockItem" model +function renderStockItem(name, data, parameters, options) { + + var image = data.part_detail.thumbnail || data.part_detail.image; + + if (!image) { + image = `/static/img/blank_image.png`; + } + + var html = ``; + + html += ` ${data.part_detail.full_name || data.part_detail.name}`; + + if (data.serial && data.quantity == 1) { + html += ` - {% trans "Serial Number" %}: ${data.serial}`; + } else { + html += ` - {% trans "Quantity" %}: ${data.quantity}`; + } + + if (data.part_detail.description) { + html += `

                  ${data.part_detail.description}

                  `; + } + + return html; +} + + +// Renderer for "StockLocation" model +function renderStockLocation(name, data, parameters, options) { + + var html = `${data.name}`; + + if (data.description) { + html += ` - ${data.description}`; + } + + html += `{% trans "Location ID" %}: ${data.pk}`; + + if (data.pathstring) { + html += `

                  ${data.pathstring}

                  `; + } + + return html; +} + + +// Renderer for "Part" model +function renderPart(name, data, parameters, options) { + + var image = data.image; + + if (!image) { + image = `/static/img/blank_image.png`; + } + + var html = ``; + + html += ` ${data.full_name || data.name}`; + + if (data.description) { + html += ` - ${data.description}`; + } + + html += `{% trans "Part ID" %}: ${data.pk}`; + + return html; +} + + +// Renderer for "Owner" model +function renderOwner(name, data, parameters, options) { + + var html = `${data.name}`; + + + switch (data.label) { + case 'user': + html += ``; + break; + case 'group': + html += ``; + break; + default: + break; + } + + return html; +} + + +// Renderer for "PartCategory" model +function renderPartCategory(name, data, parameters, options) { + + var html = `${data.name}`; + + if (data.description) { + html += ` - ${data.description}`; + } + + html += `{% trans "Category ID" %}: ${data.pk}`; + + if (data.pathstring) { + html += `

                  ${data.pathstring}

                  `; + } + + return html; +} + + +// Rendered for "SupplierPart" model +function renderSupplierPart(name, data, parameters, options) { + + var image = data.supplier_detail.image; + + if (!image) { + image = `/static/img/blank_image.png`; + } + + var html = ``; + + html += ` ${data.supplier_detail.name} - ${data.SKU}`; + html += ` - ${data.part_detail.full_name}`; + + html += `{% trans "Supplier Part ID" %}: ${data.pk}`; + + + return html; + +} \ No newline at end of file diff --git a/InvenTree/templates/js/order.js b/InvenTree/templates/js/order.js index 0af54fa43c..5cb286e970 100644 --- a/InvenTree/templates/js/order.js +++ b/InvenTree/templates/js/order.js @@ -1,6 +1,68 @@ {% load i18n %} {% load inventree_extras %} + +// Create a new SalesOrder +function createSalesOrder(options={}) { + + constructForm('{% url "api-so-list" %}', { + method: 'POST', + fields: { + reference: { + prefix: '{% settings_value "SALESORDER_REFERENCE_PREFIX" %}', + }, + customer: { + value: options.customer, + }, + description: {}, + target_date: { + icon: 'fa-calendar-alt', + }, + link: { + icon: 'fa-link', + }, + responsible: { + icon: 'fa-user', + } + }, + onSuccess: function(data) { + location.href = `/order/sales-order/${data.pk}/`; + }, + title: '{% trans "Create Sales Order" %}', + }); +} + +// Create a new PurchaseOrder +function createPurchaseOrder(options={}) { + + constructForm('{% url "api-po-list" %}', { + method: 'POST', + fields: { + reference: { + prefix: "{% settings_value 'PURCHASEORDER_REFERENCE_PREFIX' %}", + }, + supplier: { + value: options.supplier, + }, + description: {}, + target_date: { + icon: 'fa-calendar-alt', + }, + link: { + icon: 'fa-link', + }, + responsible: { + icon: 'fa-user', + } + }, + onSuccess: function(data) { + location.href = `/order/purchase-order/${data.pk}/`; + }, + title: '{% trans "Create Purchase Order" %}', + }); +} + + function removeOrderRowFromOrderWizard(e) { /* Remove a part selection from an order form. */ @@ -266,6 +328,11 @@ function loadSalesOrderTable(table, options) { field: 'customer_detail', title: '{% trans "Customer" %}', formatter: function(value, row, index, field) { + + if (!row.customer_detail) { + return '{% trans "Invalid Customer" %}'; + } + return imageHoverIcon(row.customer_detail.image) + renderLink(row.customer_detail.name, `/company/${row.customer}/sales-orders/`); } }, diff --git a/InvenTree/templates/js/part.js b/InvenTree/templates/js/part.js index 66174e2f15..7fa63098e1 100644 --- a/InvenTree/templates/js/part.js +++ b/InvenTree/templates/js/part.js @@ -769,6 +769,159 @@ function loadPartTestTemplateTable(table, options) { } +function loadPriceBreakTable(table, options) { + /* + * Load PriceBreak table. + */ + + var name = options.name || 'pricebreak'; + var human_name = options.human_name || 'price break'; + var linkedGraph = options.linkedGraph || null; + var chart = null; + + table.inventreeTable({ + name: name, + method: 'get', + formatNoMatches: function() { + return `{% trans "No ${human_name} information found" %}`; + }, + url: options.url, + onLoadSuccess: function(tableData) { + if (linkedGraph) { + // sort array + tableData = tableData.sort((a,b)=>a.quantity-b.quantity); + + // split up for graph definition + var graphLabels = Array.from(tableData, x => x.quantity); + var graphData = Array.from(tableData, x => parseFloat(x.price)); + + // destroy chart if exists + if (chart){ + chart.destroy(); + } + chart = loadLineChart(linkedGraph, + { + labels: graphLabels, + datasets: [ + { + label: '{% trans "Unit Price" %}', + data: graphData, + backgroundColor: 'rgba(255, 206, 86, 0.2)', + borderColor: 'rgb(255, 206, 86)', + stepped: true, + fill: true, + },] + } + ); + } + }, + columns: [ + { + field: 'pk', + title: 'ID', + visible: false, + switchable: false, + }, + { + field: 'quantity', + title: '{% trans "Quantity" %}', + sortable: true, + }, + { + field: 'price', + title: '{% trans "Price" %}', + sortable: true, + formatter: function(value, row, index) { + var html = value; + + html += `
                  ` + + html += makeIconButton('fa-edit icon-blue', `button-${name}-edit`, row.pk, `{% trans "Edit ${human_name}" %}`); + html += makeIconButton('fa-trash-alt icon-red', `button-${name}-delete`, row.pk, `{% trans "Delete ${human_name}" %}`); + + html += `
                  `; + + return html; + } + }, + ] + }); +} + +function loadLineChart(context, data) { + return new Chart(context, { + type: 'line', + data: data, + options: { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: {position: 'bottom'}, + } + } + }); +} + +function initPriceBreakSet(table, options) { + + var part_id = options.part_id; + var pb_human_name = options.pb_human_name; + var pb_url_slug = options.pb_url_slug; + var pb_url = options.pb_url; + var pb_new_btn = options.pb_new_btn; + var pb_new_url = options.pb_new_url; + + var linkedGraph = options.linkedGraph || null; + + loadPriceBreakTable( + table, + { + name: pb_url_slug, + human_name: pb_human_name, + url: pb_url, + linkedGraph: linkedGraph, + } + ); + + function reloadPriceBreakTable(){ + table.bootstrapTable("refresh"); + } + + pb_new_btn.click(function() { + launchModalForm(pb_new_url, + { + success: reloadPriceBreakTable, + data: { + part: part_id, + } + } + ); + }); + + table.on('click', `.button-${pb_url_slug}-delete`, function() { + var pk = $(this).attr('pk'); + + launchModalForm( + `/part/${pb_url_slug}/${pk}/delete/`, + { + success: reloadPriceBreakTable + } + ); + }); + + table.on('click', `.button-${pb_url_slug}-edit`, function() { + var pk = $(this).attr('pk'); + + launchModalForm( + `/part/${pb_url_slug}/${pk}/edit/`, + { + success: reloadPriceBreakTable + } + ); + }); +} + + function loadStockPricingChart(context, data) { return new Chart(context, { type: 'bar', @@ -824,3 +977,36 @@ function loadBomChart(context, data) { } }); } + +function loadSellPricingChart(context, data) { + return new Chart(context, { + type: 'line', + data: data, + options: { + responsive: true, + maintainAspectRatio: false, + plugins: {legend: {position: 'bottom'}}, + scales: { + y: { + type: 'linear', + position: 'left', + grid: {display: false}, + title: { + display: true, + text: '{% trans "Unit Price" %}' + } + }, + y1: { + type: 'linear', + position: 'right', + grid: {display: false}, + titel: { + display: true, + text: '{% trans "Quantity" %}', + position: 'right' + } + }, + }, + } + }); +} diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js index b557f0c327..fba0fc2913 100644 --- a/InvenTree/templates/js/stock.js +++ b/InvenTree/templates/js/stock.js @@ -685,6 +685,20 @@ function loadStockTable(table, options) { return renderLink(text, link); } }, + { + field: 'supplier_part', + title: '{% trans "Supplier Part" %}', + formatter: function(value, row) { + if (!value) { + return '-'; + } + + var link = `/supplier-part/${row.supplier_part}/stock/`; + var text = `${row.supplier_part_detail.SKU}`; + + return renderLink(text, link); + } + }, { field: 'purchase_price', title: '{% trans "Purchase Price" %}', diff --git a/InvenTree/templates/js/table_filters.js b/InvenTree/templates/js/table_filters.js index d02fa50d80..3dfb424edf 100644 --- a/InvenTree/templates/js/table_filters.js +++ b/InvenTree/templates/js/table_filters.js @@ -205,7 +205,12 @@ function getAvailableTableFilters(tableKey) { batch: { title: '{% trans "Batch" %}', description: '{% trans "Batch code" %}', - } + }, + has_purchase_price: { + type: 'bool', + title: '{% trans "Has purchase price" %}', + description: '{% trans "Show stock items which have a purchase price set" %}', + }, }; } diff --git a/InvenTree/templates/modals.html b/InvenTree/templates/modals.html index e0cae3e580..e2bd44554c 100644 --- a/InvenTree/templates/modals.html +++ b/InvenTree/templates/modals.html @@ -7,7 +7,7 @@
                • -