From 10758a9626aa4874a48c47b48973348c8b26fc32 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 25 Oct 2020 07:49:38 +1100 Subject: [PATCH 01/14] Improvements for global settings - Name and description are defined in models.py - Lookup functions for name / description / units / default - Shortcut template for rending settings - More unit testing --- InvenTree/common/apps.py | 6 +- InvenTree/common/models.py | 146 +++++++++++++++--- InvenTree/common/tests.py | 27 +++- .../part/templatetags/inventree_extras.py | 29 +++- .../templates/InvenTree/settings/build.html | 13 +- .../templates/InvenTree/settings/part.html | 12 +- .../templates/InvenTree/settings/po.html | 6 + .../templates/InvenTree/settings/setting.html | 15 ++ .../templates/InvenTree/settings/so.html | 8 + InvenTree/templates/js/build.html | 2 +- InvenTree/templates/js/order.html | 4 +- 11 files changed, 229 insertions(+), 39 deletions(-) create mode 100644 InvenTree/templates/InvenTree/settings/setting.html diff --git a/InvenTree/common/apps.py b/InvenTree/common/apps.py index 0535709686..06b825c574 100644 --- a/InvenTree/common/apps.py +++ b/InvenTree/common/apps.py @@ -32,7 +32,7 @@ class CommonConfig(AppConfig): return # Default instance name - instance_name = 'InvenTree Server' + instance_name = InvenTreeSetting.get_default_value('INVENTREE_INSTANCE') # Use the old name if it exists if InvenTreeSetting.objects.filter(key='InstanceName').exists(): @@ -59,12 +59,12 @@ class CommonConfig(AppConfig): from .models import InvenTreeSetting - for key in InvenTreeSetting.DEFAULT_VALUES.keys(): + for key in InvenTreeSetting.GLOBAL_SETTINGS.keys(): try: settings = InvenTreeSetting.objects.filter(key__iexact=key) if settings.count() == 0: - value = InvenTreeSetting.DEFAULT_VALUES[key] + value = InvenTreeSetting.get_default_value(key) print(f"Creating default setting for {key} -> '{value}'") diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 31f8e12260..1c460225c8 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -27,34 +27,144 @@ class InvenTreeSetting(models.Model): even if that key does not exist. """ - # Dict of default values for various internal settings - DEFAULT_VALUES = { - # Global inventree settings - 'INVENTREE_INSTANCE': 'InvenTree Server', + """ + Dict of all global settings values: - # Part settings - 'PART_IPN_REGEX': '', - 'PART_COPY_BOM': True, - 'PART_COPY_PARAMETERS': True, - 'PART_COPY_TESTS': True, + The key of each item is the name of the value as it appears in the database. - # Stock settings + Each global setting has the following parameters: + + - name: Translatable string name of the setting (required) + - description: Translatable string description of the setting (required) + - default: Default value (optional) + - units: Units of the particular setting (optional) + - validator: Validation function for the setting (optional) - # Build Order settings - 'BUILDORDER_REFERENCE_PREFIX': 'BO', - 'BUILDORDER_REFERENCE_REGEX': '', + The keys must be upper-case + """ - # Purchase Order Settings - 'PURCHASEORDER_REFERENCE_PREFIX': 'PO', + GLOBAL_SETTINGS = { - # Sales Order Settings - 'SALESORDER_REFERENCE_PREFIX': 'SO', + 'INVENTREE_INSTANCE': { + 'name': _('InvenTree Instance Name'), + 'default': 'InvenTree server', + 'description': _('String descriptor for the server instance'), + }, + + 'PART_IPN_REGEX': { + 'name': _('IPN Regex'), + 'description': _('Regular expression pattern for matching Part IPN') + }, + + 'PART_COPY_BOM': { + 'name': _('Copy Part BOM Data'), + 'description': _('Copy BOM data by default when duplicating a part'), + 'default': True, + }, + + 'PART_COPY_PARAMETERS': { + 'name': _('Copy Part Parameter Data'), + 'description': _('Copy parameter data by default when duplicating a part'), + 'default': True, + }, + + 'PART_COPY_TESTS': { + 'name': _('Copy Part Test Data'), + 'description': _('Copy test data by default when duplicating a part'), + 'default': True, + }, + + 'BUILDORDER_REFERENCE_PREFIX': { + 'name': _('Build Order Reference Prefix'), + 'description': _('Prefix value for build order reference'), + 'default': 'BO', + }, + + 'BUILDORDER_REFERENCE_REGEX': { + 'name': _('Build Order Reference Regex'), + 'description': _('Regular expression pattern for matching build order reference') + }, + + 'SALESORDER_REFERENCE_PREFIX': { + 'name': _('Sales Order Reference Prefix'), + 'description': _('Prefix value for sales order reference'), + }, + + 'PURCHASEORDER_REFERENCE_PREFIX': { + 'name': _('Purchase Order Reference Prefix'), + 'description': _('Prefix value for purchase order reference'), + }, } class Meta: verbose_name = "InvenTree Setting" verbose_name_plural = "InvenTree Settings" + @classmethod + def get_setting_name(cls, key): + """ + Return the name of a particular setting. + + If it does not exist, return an empty string. + """ + + key = str(key).strip().upper() + + if key in cls.GLOBAL_SETTINGS: + setting = cls.GLOBAL_SETTINGS[key] + return setting.get('name', '') + else: + return '' + + @classmethod + def get_setting_description(cls, key): + """ + Return the description for a particular setting. + + If it does not exist, return an empty string. + """ + + key = str(key).strip().upper() + + if key in cls.GLOBAL_SETTINGS: + setting = cls.GLOBAL_SETTINGS[key] + return setting.get('description', '') + else: + return '' + + @classmethod + def get_setting_units(cls, key): + """ + Return the units for a particular setting. + + If it does not exist, return an empty string. + """ + + key = str(key).strip().upper() + + if key in cls.GLOBAL_SETTINGS: + setting = cls.GLOBAL_SETTINGS[key] + return setting.get('units', '') + else: + return '' + + + @classmethod + def get_default_value(cls, key): + """ + Return the default value for a particular setting. + + If it does not exist, return an empty string + """ + + key = str(key).strip().upper() + + if key in cls.GLOBAL_SETTINGS: + setting = cls.GLOBAL_SETTINGS[key] + return setting.get('default', '') + else: + return '' + @classmethod def get_setting(cls, key, backup_value=None): """ @@ -64,7 +174,7 @@ class InvenTreeSetting(models.Model): # If no backup value is specified, atttempt to retrieve a "default" value if backup_value is None: - backup_value = InvenTreeSetting.DEFAULT_VALUES.get(key, None) + backup_value = cls.get_default_value(key) try: settings = InvenTreeSetting.objects.filter(key__iexact=key) diff --git a/InvenTree/common/tests.py b/InvenTree/common/tests.py index a5d32dc3d6..e0b6812f40 100644 --- a/InvenTree/common/tests.py +++ b/InvenTree/common/tests.py @@ -35,14 +35,37 @@ class SettingsTest(TestCase): self.client.login(username='username', password='password') + def test_required_values(self): + """ + - Ensure that every global setting has a name. + - Ensure that every global setting has a description. + """ + + for key in InvenTreeSetting.GLOBAL_SETTINGS.keys(): + + setting = InvenTreeSetting.GLOBAL_SETTINGS[key] + + name = setting.get('name', None) + + if name is None: + raise ValueError(f'Missing GLOBAL_SETTING name for {key}') + + description = setting.get('description', None) + + if description is None: + raise ValueError(f'Missing GLOBAL_SETTING description for {key}') + + if not key == key.upper(): + raise ValueError(f"GLOBAL_SETTINGS key '{key}' is not uppercase") + def test_defaults(self): """ Populate the settings with default values """ - for key in InvenTreeSetting.DEFAULT_VALUES.keys(): + for key in InvenTreeSetting.GLOBAL_SETTINGS.keys(): - value = InvenTreeSetting.DEFAULT_VALUES[key] + value = InvenTreeSetting.get_default_value(key) InvenTreeSetting.set_setting(key, value, self.user) diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 2c175003d0..228d530934 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -87,7 +87,34 @@ def inventree_docs_url(*args, **kwargs): @register.simple_tag() -def inventree_setting(key, *args, **kwargs): +def settings_name(key, *args, **kwargs): + """ + Returns the name of a GLOBAL_SETTINGS object + """ + + return InvenTreeSetting.get_setting_name(key) + +@register.simple_tag() +def settings_description(key, *args, **kwargs): + """ + Returns the description of a GLOBAL_SETTINGS object + """ + + return InvenTreeSetting.get_setting_description(key) + +@register.simple_tag() +def settings_units(key, *args, **kwargs): + """ + Return the units of a GLOBAL_SETTINGS object + """ + + return InvenTreeSetting.get_setting_units(key) + +@register.simple_tag() +def settings_value(key, *args, **kwargs): + """ + Returns the value of a GLOBAL_SETTINGS object + """ return InvenTreeSetting.get_setting(key, backup_value=kwargs.get('backup', None)) diff --git a/InvenTree/templates/InvenTree/settings/build.html b/InvenTree/templates/InvenTree/settings/build.html index 6d19e21f1a..781402795b 100644 --- a/InvenTree/templates/InvenTree/settings/build.html +++ b/InvenTree/templates/InvenTree/settings/build.html @@ -15,17 +15,8 @@ - - - - - - - - - - - + {% include "InvenTree/settings/setting.html" with key="BUILDORDER_REFERENCE_PREFIX" %} + {% include "InvenTree/settings/setting.html" with key="BUILDORDER_REFERENCE_REGEX" %}
{% trans "Reference Prefix" %}{% inventree_setting 'BUILDORDER_REFERENCE_PREFIX' backup='BO' %}{% trans "Prefix for Build Order reference" %}
{% trans "Reference Regex" %}{% inventree_setting 'BUILDORDER_REFERENCE_REGEX' %}{% trans "Regex validator for Build Order reference" %}
diff --git a/InvenTree/templates/InvenTree/settings/part.html b/InvenTree/templates/InvenTree/settings/part.html index 7c028ca6d6..cac04a60ff 100644 --- a/InvenTree/templates/InvenTree/settings/part.html +++ b/InvenTree/templates/InvenTree/settings/part.html @@ -11,6 +11,16 @@ {% block settings %} + + + + {% include "InvenTree/settings/setting.html" with key="PART_IPN_REGEX" %} + {% include "InvenTree/settings/setting.html" with key="PART_COPY_BOM" %} + {% include "InvenTree/settings/setting.html" with key="PART_COPY_PARAMETERS" %} + {% include "InvenTree/settings/setting.html" with key="PART_COPY_TESTS" %} + +
+

{% trans "Part Parameter Templates" %}

@@ -53,7 +63,7 @@ var bEdit = ""; var bDel = ""; - var html = "
" + bEdit + bDel + "
"; + var html = "
" + bEdit + bDel + "
"; return html; } diff --git a/InvenTree/templates/InvenTree/settings/po.html b/InvenTree/templates/InvenTree/settings/po.html index 7d32611404..a709d40dd3 100644 --- a/InvenTree/templates/InvenTree/settings/po.html +++ b/InvenTree/templates/InvenTree/settings/po.html @@ -10,4 +10,10 @@ {% endblock %} {% block settings %} + + + + {% include "InvenTree/settings/setting.html" with key="PURCHASEORDER_REFERENCE_PREFIX" %} + +
{% endblock %} \ No newline at end of file diff --git a/InvenTree/templates/InvenTree/settings/setting.html b/InvenTree/templates/InvenTree/settings/setting.html new file mode 100644 index 0000000000..347b93553d --- /dev/null +++ b/InvenTree/templates/InvenTree/settings/setting.html @@ -0,0 +1,15 @@ +{% load inventree_extras %} +{% load i18n %} + + + {% settings_name key %} + {% settings_value key %}{% settings_units key %} + {% settings_description key %} + +
+ +
+ + \ No newline at end of file diff --git a/InvenTree/templates/InvenTree/settings/so.html b/InvenTree/templates/InvenTree/settings/so.html index e66fd85148..368374532f 100644 --- a/InvenTree/templates/InvenTree/settings/so.html +++ b/InvenTree/templates/InvenTree/settings/so.html @@ -10,4 +10,12 @@ {% endblock %} {% block settings %} + + + + + {% include "InvenTree/settings/setting.html" with key="SALESORDER_REFERENCE_PREFIX" %} + +
+ {% endblock %} \ No newline at end of file diff --git a/InvenTree/templates/js/build.html b/InvenTree/templates/js/build.html index 6a12b97bfd..1f577802b2 100644 --- a/InvenTree/templates/js/build.html +++ b/InvenTree/templates/js/build.html @@ -42,7 +42,7 @@ function loadBuildTable(table, options) { switchable: false, formatter: function(value, row, index, field) { - var prefix = "{% inventree_setting 'BUILDORDER_REFERENCE_PREFIX' %}"; + var prefix = "{% settings_value 'BUILDORDER_REFERENCE_PREFIX' %}"; if (prefix) { value = `${prefix}${value}`; diff --git a/InvenTree/templates/js/order.html b/InvenTree/templates/js/order.html index 4dbfbefa13..0c958c65a2 100644 --- a/InvenTree/templates/js/order.html +++ b/InvenTree/templates/js/order.html @@ -139,7 +139,7 @@ function loadPurchaseOrderTable(table, options) { title: '{% trans "Purchase Order" %}', formatter: function(value, row, index, field) { - var prefix = "{% inventree_setting 'PURCHASEORDER_REFERENCE_PREFIX' %}"; + var prefix = "{% settings_value 'PURCHASEORDER_REFERENCE_PREFIX' %}"; if (prefix) { value = `${prefix}${value}`; @@ -221,7 +221,7 @@ function loadSalesOrderTable(table, options) { title: '{% trans "Sales Order" %}', formatter: function(value, row, index, field) { - var prefix = "{% inventree_setting 'SALESORDER_REFERENCE_PREFIX' %}"; + var prefix = "{% settings_value 'SALESORDER_REFERENCE_PREFIX' %}"; if (prefix) { value = `${prefix}${value}`; From 3e17bf33167bba7b84a98943d44978a81075d8df Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 25 Oct 2020 08:02:46 +1100 Subject: [PATCH 02/14] Edit setting directly --- InvenTree/InvenTree/urls.py | 4 ++++ InvenTree/common/forms.py | 1 - InvenTree/common/models.py | 16 ++++++++++++++++ InvenTree/part/templatetags/inventree_extras.py | 9 +++++++++ .../templates/InvenTree/settings/setting.html | 2 +- .../templates/InvenTree/settings/settings.html | 17 +++++++++++++++++ 6 files changed, 47 insertions(+), 2 deletions(-) diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 0b4292cbd9..0c5c988ca0 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -39,6 +39,8 @@ from .views import IndexView, SearchView, DatabaseStatsView from .views import SettingsView, EditUserView, SetPasswordView, ColorThemeSelectView from .views import DynamicJsView +from common.views import SettingEdit + from .api import InfoView from .api import ActionPluginView @@ -78,6 +80,8 @@ settings_urls = [ url(r'^purchase-order/?', SettingsView.as_view(template_name='InvenTree/settings/po.html'), name='settings-po'), url(r'^sales-order/?', SettingsView.as_view(template_name='InvenTree/settings/so.html'), name='settings-so'), + url(r'^(?P\d+)/edit/?', SettingEdit.as_view(), name='setting-edit'), + # Catch any other urls url(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings'), ] diff --git a/InvenTree/common/forms.py b/InvenTree/common/forms.py index 53493faff0..ba6289221e 100644 --- a/InvenTree/common/forms.py +++ b/InvenTree/common/forms.py @@ -33,6 +33,5 @@ class SettingEditForm(HelperForm): model = InvenTreeSetting fields = [ - 'key', 'value' ] diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 1c460225c8..434f0571e5 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -165,6 +165,22 @@ class InvenTreeSetting(models.Model): else: return '' + @classmethod + def get_setting_pk(cls, key): + """ + Return the primary-key value for a given setting. + + If the setting does not exist, return None + """ + + key = str(key).strip().upper() + + try: + setting = InvenTreeSetting.objects.filter(key__iexact=key).first() + return setting.pk + except InvenTreeSettingSetting.DoesNotExist: + return None + @classmethod def get_setting(cls, key, backup_value=None): """ diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 228d530934..54e9a0ba24 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -115,8 +115,17 @@ def settings_value(key, *args, **kwargs): """ Returns the value of a GLOBAL_SETTINGS object """ + return InvenTreeSetting.get_setting(key, backup_value=kwargs.get('backup', None)) +@register.simple_tag() +def settings_pk(key, *args, **kwargs): + """ + Return the ID (pk) of a GLOBAL_SETTINGS Object + """ + + return InvenTreeSetting.get_setting_pk(key) + @register.simple_tag() def get_color_theme_css(username): diff --git a/InvenTree/templates/InvenTree/settings/setting.html b/InvenTree/templates/InvenTree/settings/setting.html index 347b93553d..6f6a516b84 100644 --- a/InvenTree/templates/InvenTree/settings/setting.html +++ b/InvenTree/templates/InvenTree/settings/setting.html @@ -7,7 +7,7 @@ {% settings_description key %}
-
diff --git a/InvenTree/templates/InvenTree/settings/settings.html b/InvenTree/templates/InvenTree/settings/settings.html index 90adfd5fed..fe9fd00e53 100644 --- a/InvenTree/templates/InvenTree/settings/settings.html +++ b/InvenTree/templates/InvenTree/settings/settings.html @@ -37,3 +37,20 @@ InvenTree | {% trans "Settings" %} {% block js_load %} {{ block.super }} {% endblock %} + +{% block js_ready %} +{{ block.super }} + +$('table').find('.btn-edit-setting').click(function() { + var setting = $(this).attr('setting'); + var pk = $(this).attr('pk'); + + launchModalForm( + `/settings/${pk}/edit/`, + { + reload: true, + } + ); +}); + +{% endblock %} From e3f5e8fbb16e2a48fe4662d46680212d0898b155 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 25 Oct 2020 08:04:04 +1100 Subject: [PATCH 03/14] PEP fixes --- InvenTree/InvenTree/urls.py | 2 +- InvenTree/common/models.py | 5 ++--- InvenTree/part/templatetags/inventree_extras.py | 4 ++++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 0c5c988ca0..3e8e400729 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -80,7 +80,7 @@ settings_urls = [ url(r'^purchase-order/?', SettingsView.as_view(template_name='InvenTree/settings/po.html'), name='settings-po'), url(r'^sales-order/?', SettingsView.as_view(template_name='InvenTree/settings/so.html'), name='settings-so'), - url(r'^(?P\d+)/edit/?', SettingEdit.as_view(), name='setting-edit'), + url(r'^(?P\d+)/edit/?', SettingEdit.as_view(), name='setting-edit'), # Catch any other urls url(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings'), diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 434f0571e5..ef6ebce8bf 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -34,7 +34,7 @@ class InvenTreeSetting(models.Model): Each global setting has the following parameters: - - name: Translatable string name of the setting (required) + - name: Translatable string name of the setting (required) - description: Translatable string description of the setting (required) - default: Default value (optional) - units: Units of the particular setting (optional) @@ -148,7 +148,6 @@ class InvenTreeSetting(models.Model): else: return '' - @classmethod def get_default_value(cls, key): """ @@ -178,7 +177,7 @@ class InvenTreeSetting(models.Model): try: setting = InvenTreeSetting.objects.filter(key__iexact=key).first() return setting.pk - except InvenTreeSettingSetting.DoesNotExist: + except InvenTreeSetting.DoesNotExist: return None @classmethod diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 54e9a0ba24..c5a45bc836 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -94,6 +94,7 @@ def settings_name(key, *args, **kwargs): return InvenTreeSetting.get_setting_name(key) + @register.simple_tag() def settings_description(key, *args, **kwargs): """ @@ -102,6 +103,7 @@ def settings_description(key, *args, **kwargs): return InvenTreeSetting.get_setting_description(key) + @register.simple_tag() def settings_units(key, *args, **kwargs): """ @@ -110,6 +112,7 @@ def settings_units(key, *args, **kwargs): return InvenTreeSetting.get_setting_units(key) + @register.simple_tag() def settings_value(key, *args, **kwargs): """ @@ -118,6 +121,7 @@ def settings_value(key, *args, **kwargs): return InvenTreeSetting.get_setting(key, backup_value=kwargs.get('backup', None)) + @register.simple_tag() def settings_pk(key, *args, **kwargs): """ From b57a78dea40049cefe19420e2c412a9f02fca9fc Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 25 Oct 2020 08:10:52 +1100 Subject: [PATCH 04/14] Add some context data to the view for editing a setting --- .../common/templates/common/edit_setting.html | 14 ++++++++++++++ InvenTree/common/views.py | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 InvenTree/common/templates/common/edit_setting.html diff --git a/InvenTree/common/templates/common/edit_setting.html b/InvenTree/common/templates/common/edit_setting.html new file mode 100644 index 0000000000..815ac76702 --- /dev/null +++ b/InvenTree/common/templates/common/edit_setting.html @@ -0,0 +1,14 @@ +{% extends "modal_form.html" %} +{% load i18n %} + +{% block pre_form_content %} + +{{ block.super }} + +

+ {{ name }}
+ {{ description }}
+ {% trans "Current value" %}: {{ value }} +

+ +{% endblock %} \ No newline at end of file diff --git a/InvenTree/common/views.py b/InvenTree/common/views.py index a205b8b915..8a91248063 100644 --- a/InvenTree/common/views.py +++ b/InvenTree/common/views.py @@ -46,3 +46,20 @@ class SettingEdit(AjaxUpdateView): model = models.InvenTreeSetting ajax_form_title = _('Change Setting') form_class = forms.SettingEditForm + ajax_template_name = "common/edit_setting.html" + + def get_context_data(self, **kwargs): + """ + Add extra context information about the particular setting object. + """ + + ctx = super().get_context_data(**kwargs) + + setting = self.get_object() + + ctx['key'] = setting.key + ctx['value'] = setting.value + ctx['name'] = models.InvenTreeSetting.get_setting_name(setting.key) + ctx['description'] = models.InvenTreeSetting.get_setting_description(setting.key) + + return ctx From 4d96b385b1e36dc2e4ffed19491a6fc74cfff6ba Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 25 Oct 2020 08:17:41 +1100 Subject: [PATCH 05/14] Add page for global settings --- InvenTree/InvenTree/urls.py | 1 + InvenTree/common/models.py | 6 +++++ .../templates/InvenTree/settings/global.html | 23 +++++++++++++++++++ .../templates/InvenTree/settings/tabs.html | 3 +++ 4 files changed, 33 insertions(+) create mode 100644 InvenTree/templates/InvenTree/settings/global.html diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 3e8e400729..334f285e2c 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -73,6 +73,7 @@ settings_urls = [ url(r'^user/?', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings-user'), url(r'^theme/?', ColorThemeSelectView.as_view(), name='settings-theme'), + url(r'^global/?', SettingsView.as_view(template_name='InvenTree/settings/global.html'), name='settings-global'), url(r'^currency/?', SettingsView.as_view(template_name='InvenTree/settings/currency.html'), name='settings-currency'), url(r'^part/?', SettingsView.as_view(template_name='InvenTree/settings/part.html'), name='settings-part'), url(r'^stock/?', SettingsView.as_view(template_name='InvenTree/settings/stock.html'), name='settings-stock'), diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index ef6ebce8bf..76320edd98 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -51,6 +51,12 @@ class InvenTreeSetting(models.Model): 'description': _('String descriptor for the server instance'), }, + 'INVENTREE_COMPANY_NAME': { + 'name': _('Company name'), + 'description': _('Internal company name'), + 'default': 'My company name', + }, + 'PART_IPN_REGEX': { 'name': _('IPN Regex'), 'description': _('Regular expression pattern for matching Part IPN') diff --git a/InvenTree/templates/InvenTree/settings/global.html b/InvenTree/templates/InvenTree/settings/global.html new file mode 100644 index 0000000000..7dcdd54bea --- /dev/null +++ b/InvenTree/templates/InvenTree/settings/global.html @@ -0,0 +1,23 @@ +{% extends "InvenTree/settings/settings.html" %} +{% load i18n %} +{% load inventree_extras %} + +{% block tabs %} +{% include "InvenTree/settings/tabs.html" with tab='global' %} +{% endblock %} + +{% block subtitle %} +{% trans "Global InvenTree Settings" %} +{% endblock %} + +{% block settings %} + + + + + {% include "InvenTree/settings/setting.html" with key="INVENTREE_INSTANCE" %} + {% include "InvenTree/settings/setting.html" with key="INVENTREE_COMPANY_NAME" %} + +
+ +{% endblock %} \ No newline at end of file diff --git a/InvenTree/templates/InvenTree/settings/tabs.html b/InvenTree/templates/InvenTree/settings/tabs.html index ee402feb4f..30dcec4ddc 100644 --- a/InvenTree/templates/InvenTree/settings/tabs.html +++ b/InvenTree/templates/InvenTree/settings/tabs.html @@ -11,6 +11,9 @@

{% trans "InvenTree Settings" %}

+{% if user.is_staff %}

{% trans "InvenTree Settings" %}

\ No newline at end of file + +{% endif %} \ No newline at end of file From 590889072607974581ee403ecfb70286f039763a Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 25 Oct 2020 22:07:11 +1100 Subject: [PATCH 13/14] Create setting if it does not exist --- InvenTree/common/models.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 3150dad2a4..0d3afbe226 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -204,9 +204,14 @@ class InvenTreeSetting(models.Model): try: setting = InvenTreeSetting.objects.filter(key__iexact=key).first() - return setting except (InvenTreeSetting.DoesNotExist): - return None + # Create the setting if it does not exist + setting = InvenTreeSetting.create( + key=key, + value=InvenTreeSetting.get_default_value(key) + ) + + return setting @classmethod def get_setting_pk(cls, key): From e978e1df52f877dd71e881cac635500a79fc1753 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 25 Oct 2020 22:11:24 +1100 Subject: [PATCH 14/14] Style fixes --- InvenTree/part/templatetags/inventree_extras.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 37a5c3055d..3af495cc1c 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -6,7 +6,7 @@ import os from django import template from InvenTree import version, settings -from InvenTree.helpers import decimal2string +import InvenTree.helpers from common.models import InvenTreeSetting, ColorTheme @@ -17,7 +17,7 @@ register = template.Library() def decimal(x, *args, **kwargs): """ Simplified rendering of a decimal number """ - return decimal2string(x) + return InvenTree.helpers.decimal2string(x) @register.simple_tag() @@ -26,6 +26,7 @@ def str2bool(x, *args, **kwargs): return InvenTree.helpers.str2bool(x) + @register.simple_tag() def inrange(n, *args, **kwargs): """ Return range(n) for iterating through a numeric quantity """ @@ -35,7 +36,7 @@ def inrange(n, *args, **kwargs): @register.simple_tag() def multiply(x, y, *args, **kwargs): """ Multiply two numbers together """ - return decimal2string(x * y) + return InvenTree.helpers.decimal2string(x * y) @register.simple_tag() @@ -48,7 +49,7 @@ def add(x, y, *args, **kwargs): def part_allocation_count(build, part, *args, **kwargs): """ Return the total number of allocated to """ - return decimal2string(build.getAllocatedQuantity(part)) + return InvenTree.helpers.decimal2string(build.getAllocatedQuantity(part)) @register.simple_tag()