diff --git a/InvenTree/InvenTree/fields.py b/InvenTree/InvenTree/fields.py index 462d2b0e0e..71b31c55a8 100644 --- a/InvenTree/InvenTree/fields.py +++ b/InvenTree/InvenTree/fields.py @@ -20,7 +20,6 @@ from djmoney.forms.fields import MoneyField from djmoney.models.validators import MinMoneyValidator import InvenTree.helpers -import common.settings class InvenTreeURLFormField(FormURLField): @@ -42,9 +41,11 @@ class InvenTreeURLField(models.URLField): def money_kwargs(): """ returns the database settings for MoneyFields """ + from common.settings import currency_code_mappings, currency_code_default + kwargs = {} - kwargs['currency_choices'] = common.settings.currency_code_mappings() - kwargs['default_currency'] = common.settings.currency_code_default + kwargs['currency_choices'] = currency_code_mappings() + kwargs['default_currency'] = currency_code_default() return kwargs diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 330bd2bb68..628fd2e646 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -631,13 +631,34 @@ def clean_decimal(number): """ Clean-up decimal value """ # Check if empty - if number is None or number == '': + if number is None or number == '' or number == 0: return Decimal(0) - # Check if decimal type + # Convert to string and remove spaces + number = str(number).replace(' ', '') + + # Guess what type of decimal and thousands separators are used + count_comma = number.count(',') + count_point = number.count('.') + + if count_comma == 1: + # Comma is used as decimal separator + if count_point > 0: + # Points are used as thousands separators: remove them + number = number.replace('.', '') + # Replace decimal separator with point + number = number.replace(',', '.') + elif count_point == 1: + # Point is used as decimal separator + if count_comma > 0: + # Commas are used as thousands separators: remove them + number = number.replace(',', '') + + # Convert to Decimal type try: clean_number = Decimal(number) except InvalidOperation: - clean_number = number + # Number cannot be converted to Decimal (eg. a string containing letters) + return Decimal(0) return clean_number.quantize(Decimal(1)) if clean_number == clean_number.to_integral() else clean_number.normalize() diff --git a/InvenTree/InvenTree/metadata.py b/InvenTree/InvenTree/metadata.py index c22b39dc43..6cf29ab945 100644 --- a/InvenTree/InvenTree/metadata.py +++ b/InvenTree/InvenTree/metadata.py @@ -32,6 +32,9 @@ class InvenTreeMetadata(SimpleMetadata): def determine_metadata(self, request, view): + self.request = request + self.view = view + metadata = super().determine_metadata(request, view) user = request.user @@ -136,6 +139,42 @@ class InvenTreeMetadata(SimpleMetadata): except AttributeError: pass + # Try to extract 'instance' information + instance = None + + # Extract extra information if an instance is available + if hasattr(serializer, 'instance'): + instance = serializer.instance + + if instance is None: + try: + instance = self.view.get_object() + except: + pass + + if instance is not None: + """ + If there is an instance associated with this API View, + introspect that instance to find any specific API info. + """ + + if hasattr(instance, 'api_instance_filters'): + + instance_filters = instance.api_instance_filters() + + for field_name, field_filters in instance_filters.items(): + + if field_name not in serializer_info.keys(): + # The field might be missing, but is added later on + # This function seems to get called multiple times? + continue + + if 'instance_filters' not in serializer_info[field_name].keys(): + serializer_info[field_name]['instance_filters'] = {} + + for key, value in field_filters.items(): + serializer_info[field_name]['instance_filters'][key] = value + return serializer_info def get_field_info(self, field): diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py index 2831a23151..3213838e78 100644 --- a/InvenTree/InvenTree/models.py +++ b/InvenTree/InvenTree/models.py @@ -93,6 +93,17 @@ class InvenTreeTree(MPTTModel): parent: The item immediately above this one. An item with a null parent is a top-level item """ + def api_instance_filters(self): + """ + Instance filters for InvenTreeTree models + """ + + return { + 'parent': { + 'exclude_tree': self.pk, + } + } + def save(self, *args, **kwargs): try: diff --git a/InvenTree/InvenTree/static/css/inventree.css b/InvenTree/InvenTree/static/css/inventree.css index a71e29ab5d..adb5a41ee6 100644 --- a/InvenTree/InvenTree/static/css/inventree.css +++ b/InvenTree/InvenTree/static/css/inventree.css @@ -1037,3 +1037,10 @@ a.anchor { height: 30px; } +.search-menu { + padding-top: 2rem; +} + +.search-menu .ui-menu-item { + margin-top: 0.5rem; +} diff --git a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_444444_256x240.png b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_444444_256x240.png index ed8d9135ca..84220b0da1 100644 Binary files a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_444444_256x240.png and b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_444444_256x240.png differ diff --git a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_555555_256x240.png b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_555555_256x240.png index 67648e3e9e..4ac750dd31 100644 Binary files a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_555555_256x240.png and b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_555555_256x240.png differ diff --git a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_777620_256x240.png b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_777620_256x240.png index f2cc3f0e64..c5f9c9af67 100644 Binary files a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_777620_256x240.png and b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_777620_256x240.png differ diff --git a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_777777_256x240.png b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_777777_256x240.png index 6adf699471..c0891d6de7 100644 Binary files a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_777777_256x240.png and b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_777777_256x240.png differ diff --git a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_cc0000_256x240.png b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_cc0000_256x240.png index a24cde337d..fdaa36b219 100644 Binary files a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_cc0000_256x240.png and b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_cc0000_256x240.png differ diff --git a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_ffffff_256x240.png b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_ffffff_256x240.png index 6766245740..08e2f14488 100644 Binary files a/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_ffffff_256x240.png and b/InvenTree/InvenTree/static/script/jquery-ui/images/ui-icons_ffffff_256x240.png differ diff --git a/InvenTree/InvenTree/static/script/jquery-ui/index.html b/InvenTree/InvenTree/static/script/jquery-ui/index.html index b5ac7218c6..6bc6bf7980 100644 --- a/InvenTree/InvenTree/static/script/jquery-ui/index.html +++ b/InvenTree/InvenTree/static/script/jquery-ui/index.html @@ -59,6 +59,11 @@

YOUR COMPONENTS:

+ +

Autocomplete

+
+ +
@@ -248,6 +253,23 @@ + +

Menu

+ @@ -270,6 +292,33 @@ - + diff --git a/InvenTree/templates/js/forms.js b/InvenTree/templates/js/forms.js index 587ea07a16..4801ec77eb 100644 --- a/InvenTree/templates/js/forms.js +++ b/InvenTree/templates/js/forms.js @@ -350,6 +350,12 @@ function constructFormBody(fields, options) { for(field in fields) { fields[field].name = field; + + // If any "instance_filters" are defined for the endpoint, copy them across (overwrite) + if (fields[field].instance_filters) { + fields[field].filters = Object.assign(fields[field].filters || {}, fields[field].instance_filters); + } + var field_options = displayed_fields[field]; // Copy custom options across to the fields object diff --git a/InvenTree/InvenTree/static/script/inventree/inventree.js b/InvenTree/templates/js/inventree.js similarity index 85% rename from InvenTree/InvenTree/static/script/inventree/inventree.js rename to InvenTree/templates/js/inventree.js index 79e02d7da5..f1e9472910 100644 --- a/InvenTree/InvenTree/static/script/inventree/inventree.js +++ b/InvenTree/templates/js/inventree.js @@ -1,3 +1,5 @@ +{% load inventree_extras %} + function attachClipboard(selector, containerselector, textElement) { // set container if (containerselector){ @@ -13,7 +15,8 @@ function attachClipboard(selector, containerselector, textElement) { } } else { text = function(trigger) { - var content = trigger.parentElement.parentElement.textContent;return content.trim(); + var content = trigger.parentElement.parentElement.textContent; + return content.trim(); } } @@ -80,6 +83,45 @@ function inventreeDocReady() { attachClipboard('.clip-btn'); attachClipboard('.clip-btn', 'modal-about'); // modals attachClipboard('.clip-btn-version', 'modal-about', 'about-copy-text'); // version-text + + // Add autocomplete to the search-bar + $("#search-bar" ).autocomplete({ + source: function (request, response) { + $.ajax({ + url: '/api/part/', + data: { + search: request.term, + limit: {% settings_value 'SEARCH_PREVIEW_RESULTS' %}, + offset: 0 + }, + success: function (data) { + var transformed = $.map(data.results, function (el) { + return { + label: el.name, + id: el.pk, + thumbnail: el.thumbnail + }; + }); + response(transformed); + }, + error: function () { + response([]); + } + }); + }, + create: function () { + $(this).data('ui-autocomplete')._renderItem = function (ul, item) { + return $('
  • ') + .append('' + imageHoverIcon(item.thumbnail) + item.label + '') + .appendTo(ul); + }; + }, + select: function( event, ui ) { + window.location = '/part/' + ui.item.id + '/'; + }, + minLength: 2, + classes: {'ui-autocomplete': 'dropdown-menu search-menu'}, + }); } function isFileTransfer(transfer) { diff --git a/InvenTree/templates/search_form.html b/InvenTree/templates/search_form.html index 51a045a257..037942cb3e 100644 --- a/InvenTree/templates/search_form.html +++ b/InvenTree/templates/search_form.html @@ -3,7 +3,7 @@