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 @@
{% 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" %} | -- |