mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 13:15:43 +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,16 +4,30 @@ | |||||||
| {% 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 %} | ||||||
|  |  | ||||||
|  | <table class='table table-striped table-condensed'> | ||||||
|  |     <tbody> | ||||||
|  |         {% include "InvenTree/settings/setting.html" with key="PART_PARAMETER_ENFORCE_UNITS" icon="fa-clipboard-check" %} | ||||||
|  |     </tbody> | ||||||
|  | </table> | ||||||
|  |  | ||||||
|  | <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'> |             <button class='btn btn-success' id='new-param'> | ||||||
|                 <span class='fas fa-plus-circle'></span> {% trans "New Parameter" %} |                 <span class='fas fa-plus-circle'></span> {% trans "New Parameter" %} | ||||||
|             </button> |             </button> | ||||||
| {% endblock actions %} |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  |  | ||||||
| {% block content %} | <div class='panel-content'> | ||||||
|     <div id='param-buttons'> |     <div id='param-buttons'> | ||||||
|         <div class='btn-group' role='group'> |         <div class='btn-group' role='group'> | ||||||
|             {% include "filter_list.html" with id="parameter-templates" %} |             {% include "filter_list.html" with id="parameter-templates" %} | ||||||
| @@ -21,5 +35,6 @@ | |||||||
|     </div> |     </div> | ||||||
|     <table class='table table-striped table-condensed' id='param-table' data-toolbar='#param-buttons'> |     <table class='table table-striped table-condensed' id='param-table' data-toolbar='#param-buttons'> | ||||||
|     </table> |     </table> | ||||||
|  | </div> | ||||||
|  |  | ||||||
| {% endblock content %} | {% 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