diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 0f12c57c3c..7444e5b670 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -85,6 +85,13 @@ class InvenTreeSetting(models.Model): 'validator': bool }, + 'PART_COMPONENT': { + 'name': _('Component'), + 'description': _('Parts can be used as sub-components by default'), + 'default': True, + 'validator': bool, + }, + 'PART_PURCHASEABLE': { 'name': _('Purchaseable'), 'description': _('Parts are purchaseable by default'), @@ -264,6 +271,11 @@ class InvenTreeSetting(models.Model): if setting: value = setting.value + + # If the particular setting is defined as a boolean, cast the value to a boolean + if setting.is_bool(): + value = InvenTree.helpers.str2bool(value) + else: value = backup_value diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index c421bbf863..54b67057e5 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -664,7 +664,7 @@ class Part(MPTTModel): ) component = models.BooleanField( - default=True, + default=part_settings.part_component_default, verbose_name=_('Component'), help_text=_('Can this part be used to build other parts?') ) diff --git a/InvenTree/part/settings.py b/InvenTree/part/settings.py index a06ad8473d..8d87cdffe3 100644 --- a/InvenTree/part/settings.py +++ b/InvenTree/part/settings.py @@ -5,17 +5,23 @@ User-configurable settings for the Part app # -*- coding: utf-8 -*- from __future__ import unicode_literals -from InvenTree.helpers import str2bool - from common.models import InvenTreeSetting +def part_component_default(): + """ + Returns the default value for the 'component' field of a Part object + """ + + return InvenTreeSetting.get_setting('PART_COMPONENT') + + def part_purchaseable_default(): """ Returns the default value for the 'purchasable' field for a Part object """ - return str2bool(InvenTreeSetting.get_setting('PART_PURCHASEABLE')) + return InvenTreeSetting.get_setting('PART_PURCHASEABLE') def part_salable_default(): @@ -23,7 +29,7 @@ def part_salable_default(): Returns the default value for the 'salable' field for a Part object """ - return str2bool(InvenTreeSetting.get_setting('PART_SALABLE')) + return InvenTreeSetting.get_setting('PART_SALABLE') def part_trackable_default(): @@ -31,4 +37,4 @@ def part_trackable_default(): Returns the defualt value fro the 'trackable' field for a Part object """ - return str2bool(InvenTreeSetting.get_setting('PART_TRACKABLE')) + return InvenTreeSetting.get_setting('PART_TRACKABLE') diff --git a/InvenTree/part/test_part.py b/InvenTree/part/test_part.py index 1301df3c91..44578331a9 100644 --- a/InvenTree/part/test_part.py +++ b/InvenTree/part/test_part.py @@ -4,6 +4,8 @@ from __future__ import unicode_literals +from django.contrib.auth import get_user_model + from django.test import TestCase from django.core.exceptions import ValidationError @@ -13,6 +15,10 @@ from .models import Part, PartTestTemplate from .models import rename_part_image, match_part_names from .templatetags import inventree_extras +import part.settings + +from common.models import InvenTreeSetting + class TemplateTagTest(TestCase): """ Tests for the custom template tag code """ @@ -164,3 +170,82 @@ class TestTemplateTest(TestCase): PartTestTemplate.objects.create(part=variant, test_name='A Sample Test') self.assertEqual(variant.getTestTemplates().count(), n + 1) + + +class PartSettingsTest(TestCase): + """ + Tests to ensure that the user-configurable default values work as expected. + + Some fields for the Part model can have default values specified by the user. + """ + + def setUp(self): + # Create a user for auth + User = get_user_model() + + self.user = User.objects.create_user( + username='testuser', + email='test@testing.com', + password='password', + is_staff=True + ) + + def make_part(self): + """ + Helper function to create a simple part + """ + + part = Part.objects.create( + name='Test Part', + description='I am but a humble test part', + IPN='IPN-123', + ) + + return part + + def test_defaults(self): + """ + Test that the default values for the part settings are correct + """ + + self.assertTrue(part.settings.part_component_default()) + self.assertFalse(part.settings.part_purchaseable_default()) + self.assertFalse(part.settings.part_salable_default()) + self.assertFalse(part.settings.part_trackable_default()) + + def test_initial(self): + """ + Test the 'initial' default values (no default values have been set) + """ + + part = self.make_part() + + self.assertTrue(part.component) + self.assertFalse(part.purchaseable) + self.assertFalse(part.salable) + self.assertFalse(part.trackable) + + def test_custom(self): + """ + Update some of the part values and re-test + """ + + for val in [True, False]: + InvenTreeSetting.set_setting('PART_COMPONENT', val, self.user) + InvenTreeSetting.set_setting('PART_PURCHASEABLE', val, self.user) + InvenTreeSetting.set_setting('PART_SALABLE', val, self.user) + InvenTreeSetting.set_setting('PART_TRACKABLE', val, self.user) + + self.assertEqual(val, InvenTreeSetting.get_setting('PART_COMPONENT')) + self.assertEqual(val, InvenTreeSetting.get_setting('PART_PURCHASEABLE')) + self.assertEqual(val, InvenTreeSetting.get_setting('PART_SALABLE')) + self.assertEqual(val, InvenTreeSetting.get_setting('PART_TRACKABLE')) + + part = self.make_part() + + self.assertEqual(part.component, val) + self.assertEqual(part.purchaseable, val) + self.assertEqual(part.salable, val) + self.assertEqual(part.trackable, val) + + Part.objects.filter(pk=part.pk).delete() diff --git a/InvenTree/templates/InvenTree/settings/part.html b/InvenTree/templates/InvenTree/settings/part.html index 6b83a62ef2..f6b5f3e4b0 100644 --- a/InvenTree/templates/InvenTree/settings/part.html +++ b/InvenTree/templates/InvenTree/settings/part.html @@ -16,10 +16,12 @@ + {% include "InvenTree/settings/setting.html" with key="PART_IPN_REGEX" %} + {% include "InvenTree/settings/setting.html" with key="PART_COMPONENT" %} {% include "InvenTree/settings/setting.html" with key="PART_PURCHASEABLE" %} {% include "InvenTree/settings/setting.html" with key="PART_SALABLE" %} {% include "InvenTree/settings/setting.html" with key="PART_TRACKABLE" %} - {% 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" %}