mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-11-04 07:05:41 +00:00 
			
		
		
		
	Unit check option (#5175)
* Add option to control parameter units * Check setting before validation * Update part parameter settings page * Update unit tests * Update docs
This commit is contained in:
		@@ -1249,6 +1249,13 @@ class InvenTreeSetting(BaseInvenTreeSetting):
 | 
				
			|||||||
            'default': '',
 | 
					            'default': '',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        'PART_PARAMETER_ENFORCE_UNITS': {
 | 
				
			||||||
 | 
					            'name': _('Enforce Parameter Units'),
 | 
				
			||||||
 | 
					            'description': _('If units are provided, parameter values must match the specified units'),
 | 
				
			||||||
 | 
					            'default': True,
 | 
				
			||||||
 | 
					            'validator': bool,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        'PRICING_DECIMAL_PLACES_MIN': {
 | 
					        'PRICING_DECIMAL_PLACES_MIN': {
 | 
				
			||||||
            'name': _('Minimum Pricing Decimal Places'),
 | 
					            'name': _('Minimum Pricing Decimal Places'),
 | 
				
			||||||
            'description': _('Minimum number of decimal places to display when rendering pricing data'),
 | 
					            'description': _('Minimum number of decimal places to display when rendering pricing data'),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3532,6 +3532,16 @@ class PartParameter(MetadataMixin, models.Model):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        super().clean()
 | 
					        super().clean()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Validate the parameter data against the template units
 | 
				
			||||||
 | 
					        if InvenTreeSetting.get_setting('PART_PARAMETER_ENFORCE_UNITS', True, cache=False, create=False):
 | 
				
			||||||
 | 
					            if self.template.units:
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    InvenTree.conversion.convert_physical_value(self.data, self.template.units)
 | 
				
			||||||
 | 
					                except ValidationError as e:
 | 
				
			||||||
 | 
					                    raise ValidationError({
 | 
				
			||||||
 | 
					                        'data': e.message
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Validate the parameter data against the template choices
 | 
					        # Validate the parameter data against the template choices
 | 
				
			||||||
        if choices := self.template.get_choices():
 | 
					        if choices := self.template.get_choices():
 | 
				
			||||||
            if self.data not in choices:
 | 
					            if self.data not in choices:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import django.core.exceptions as django_exceptions
 | 
				
			|||||||
from django.test import TestCase, TransactionTestCase
 | 
					from django.test import TestCase, TransactionTestCase
 | 
				
			||||||
from django.urls import reverse
 | 
					from django.urls import reverse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from common.models import InvenTreeSetting
 | 
				
			||||||
from InvenTree.unit_test import InvenTreeAPITestCase
 | 
					from InvenTree.unit_test import InvenTreeAPITestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import (Part, PartCategory, PartCategoryParameterTemplate,
 | 
					from .models import (Part, PartCategory, PartCategoryParameterTemplate,
 | 
				
			||||||
@@ -168,11 +169,24 @@ class ParameterTests(TestCase):
 | 
				
			|||||||
            param = PartParameter(part=prt, template=template, data=value)
 | 
					            param = PartParameter(part=prt, template=template, data=value)
 | 
				
			||||||
            param.full_clean()
 | 
					            param.full_clean()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bad_values = ['3 Amps', '-3 zogs', '3.14F']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Disable enforcing of part parameter units
 | 
				
			||||||
 | 
					        InvenTreeSetting.set_setting('PART_PARAMETER_ENFORCE_UNITS', False, change_user=None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Invalid units also pass, but will be converted to the template units
 | 
					        # Invalid units also pass, but will be converted to the template units
 | 
				
			||||||
        for value in ['3 Amps', '-3 zogs', '3.14F']:
 | 
					        for value in bad_values:
 | 
				
			||||||
            param = PartParameter(part=prt, template=template, data=value)
 | 
					            param = PartParameter(part=prt, template=template, data=value)
 | 
				
			||||||
            param.full_clean()
 | 
					            param.full_clean()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Enable enforcing of part parameter units
 | 
				
			||||||
 | 
					        InvenTreeSetting.set_setting('PART_PARAMETER_ENFORCE_UNITS', True, change_user=None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for value in bad_values:
 | 
				
			||||||
 | 
					            param = PartParameter(part=prt, template=template, data=value)
 | 
				
			||||||
 | 
					            with self.assertRaises(django_exceptions.ValidationError):
 | 
				
			||||||
 | 
					                param.full_clean()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_param_unit_conversion(self):
 | 
					    def test_param_unit_conversion(self):
 | 
				
			||||||
        """Test that parameters are correctly converted to template units"""
 | 
					        """Test that parameters are correctly converted to template units"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,22 +4,37 @@
 | 
				
			|||||||
{% block label %}part-parameters{% endblock label %}
 | 
					{% block label %}part-parameters{% endblock label %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block heading %}
 | 
					{% block heading %}
 | 
				
			||||||
{% trans "Part Parameter Templates" %}
 | 
					{% trans "Part Parameters" %}
 | 
				
			||||||
{% endblock heading %}
 | 
					{% endblock heading %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block actions %}
 | 
					{% block panel_content %}
 | 
				
			||||||
<button class='btn btn-success' id='new-param'>
 | 
					 | 
				
			||||||
    <span class='fas fa-plus-circle'></span> {% trans "New Parameter" %}
 | 
					 | 
				
			||||||
</button>
 | 
					 | 
				
			||||||
{% endblock actions %}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					<table class='table table-striped table-condensed'>
 | 
				
			||||||
<div id='param-buttons'>
 | 
					    <tbody>
 | 
				
			||||||
    <div class='btn-group' role='group'>
 | 
					        {% include "InvenTree/settings/setting.html" with key="PART_PARAMETER_ENFORCE_UNITS" icon="fa-clipboard-check" %}
 | 
				
			||||||
        {% include "filter_list.html" with id="parameter-templates" %}
 | 
					    </tbody>
 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
<table class='table table-striped table-condensed' id='param-table' data-toolbar='#param-buttons'>
 | 
					 | 
				
			||||||
</table>
 | 
					</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% endblock content %}
 | 
					<div class='panel-heading'>
 | 
				
			||||||
 | 
					    <div class='d-flex flex-wrap'>
 | 
				
			||||||
 | 
					        <h4>{% trans "Part Parameter Templates" %}</h4>
 | 
				
			||||||
 | 
					        {% include "spacer.html" %}
 | 
				
			||||||
 | 
					        <div class='btn-group' role='group'>
 | 
				
			||||||
 | 
					            <button class='btn btn-success' id='new-param'>
 | 
				
			||||||
 | 
					                <span class='fas fa-plus-circle'></span> {% trans "New Parameter" %}
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class='panel-content'>
 | 
				
			||||||
 | 
					    <div id='param-buttons'>
 | 
				
			||||||
 | 
					        <div class='btn-group' role='group'>
 | 
				
			||||||
 | 
					            {% include "filter_list.html" with id="parameter-templates" %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <table class='table table-striped table-condensed' id='param-table' data-toolbar='#param-buttons'>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% endblock panel_content %}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								docs/docs/assets/images/part/part_parameters_enforce.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/docs/assets/images/part/part_parameters_enforce.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 6.1 KiB  | 
@@ -92,6 +92,12 @@ If a part parameter is created with a value which is incompatible with the units
 | 
				
			|||||||
{% include 'img.html' %}
 | 
					{% include 'img.html' %}
 | 
				
			||||||
{% endwith %}
 | 
					{% endwith %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This behaviour can be disabled if required, so that any parameter value is accepted:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% with id="enforce_units", url="part/part_parameters_enforce.png", description="Enforce part parameters" %}
 | 
				
			||||||
 | 
					{% include 'img.html' %}
 | 
				
			||||||
 | 
					{% endwith %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Parameter Sorting
 | 
					### Parameter Sorting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Parameter sorting takes unit conversion into account, meaning that values provided in different (but compatible) units are sorted correctly:
 | 
					Parameter sorting takes unit conversion into account, meaning that values provided in different (but compatible) units are sorted correctly:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user