mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 20:55:42 +00:00 
			
		
		
		
	PART_NAME_FORMAT is introduced to display the names of parts in custom format. - For Feature Request InvenTree#2085
full_name construction in part.js is obsolete/redundant since the same is constructed in backend and sent through api response
This commit is contained in:
		| @@ -8,6 +8,7 @@ import decimal | |||||||
|  |  | ||||||
| import os | import os | ||||||
| import logging | import logging | ||||||
|  | import re | ||||||
|  |  | ||||||
| from django.utils.translation import gettext_lazy as _ | from django.utils.translation import gettext_lazy as _ | ||||||
| from django.core.exceptions import ValidationError | from django.core.exceptions import ValidationError | ||||||
| @@ -555,7 +556,9 @@ class Part(MPTTModel): | |||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def full_name(self): |     def full_name(self): | ||||||
|         """ Format a 'full name' for this Part. |         """ Format a 'full name' for this Part based on the format PART_NAME_FORMAT defined in part.settings file | ||||||
|  |  | ||||||
|  |         As a failsafe option, the following is done | ||||||
|  |  | ||||||
|         - IPN (if not null) |         - IPN (if not null) | ||||||
|         - Part name |         - Part name | ||||||
| @@ -564,17 +567,45 @@ class Part(MPTTModel): | |||||||
|         Elements are joined by the | character |         Elements are joined by the | character | ||||||
|         """ |         """ | ||||||
|  |  | ||||||
|         elements = [] |         full_name = part_settings.PART_NAME_FORMAT | ||||||
|  |         field_parser_regex_pattern = re.compile('{.*?}') | ||||||
|  |         field_regex_pattern = re.compile('(?<=part\\.)[A-z]*') | ||||||
|  |  | ||||||
|         if self.IPN: |         try: | ||||||
|             elements.append(self.IPN) |  | ||||||
|  |  | ||||||
|         elements.append(self.name) |             for field_parser in field_parser_regex_pattern.findall(part_settings.PART_NAME_FORMAT): | ||||||
|  |  | ||||||
|         if self.revision: |                 # Each parser should contain a single field | ||||||
|             elements.append(self.revision) |                 field_name = field_regex_pattern.findall(field_parser)[0] | ||||||
|  |                 field_value = getattr(self, field_name) | ||||||
|  |  | ||||||
|         return ' | '.join(elements) |                 if field_value: | ||||||
|  |                     # replace the part.$field with field's value and remove the braces | ||||||
|  |                     parsed_value = field_parser.replace(f'part.{field_name}', field_value)[1:-1] | ||||||
|  |                     full_name = full_name.replace(field_parser, parsed_value) | ||||||
|  |  | ||||||
|  |                 else: | ||||||
|  |                     # remove the field parser in full name | ||||||
|  |                     full_name = full_name.replace(field_parser, '') | ||||||
|  |  | ||||||
|  |             return full_name | ||||||
|  |  | ||||||
|  |         except AttributeError as attr_err: | ||||||
|  |  | ||||||
|  |             logger.warning(f"exception while trying to create full name for part {self.name}", attr_err) | ||||||
|  |  | ||||||
|  |             # Fallback to default format | ||||||
|  |             elements = [] | ||||||
|  |  | ||||||
|  |             if self.IPN: | ||||||
|  |                 elements.append(self.IPN) | ||||||
|  |  | ||||||
|  |             elements.append(self.name) | ||||||
|  |  | ||||||
|  |             if self.revision: | ||||||
|  |                 elements.append(self.revision) | ||||||
|  |  | ||||||
|  |             return ' | '.join(elements) | ||||||
|  |  | ||||||
|     def set_category(self, category): |     def set_category(self, category): | ||||||
|  |  | ||||||
|   | |||||||
| @@ -62,3 +62,13 @@ def part_trackable_default(): | |||||||
|     """ |     """ | ||||||
|  |  | ||||||
|     return InvenTreeSetting.get_setting('PART_TRACKABLE') |     return InvenTreeSetting.get_setting('PART_TRACKABLE') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # CONSTANTS | ||||||
|  |  | ||||||
|  | # Every brace pair is a field parser within which a field name of part has to be defined in the format part.$field_name | ||||||
|  | # When full name is constructed, It would be replaced by its value from the database and if the value is None, | ||||||
|  | # the entire field_parser i.e {.*} would be replaced with ''. | ||||||
|  | # Other characters inside and between the brace pairs would be copied as is. | ||||||
|  | PART_NAME_FORMAT = '{part.IPN | }{part.name}{ | part.revision}' | ||||||
|  |  | ||||||
|   | |||||||
| @@ -876,23 +876,7 @@ function loadPartTable(table, url, options={}) { | |||||||
|         switchable: false, |         switchable: false, | ||||||
|         formatter: function(value, row) { |         formatter: function(value, row) { | ||||||
|  |  | ||||||
|             var name = ''; |             var name = row.full_name; | ||||||
|  |  | ||||||
|             if (row.IPN) { |  | ||||||
|                 name += row.IPN; |  | ||||||
|                 name += ' | '; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             name += value; |  | ||||||
|  |  | ||||||
|             if (row.revision) { |  | ||||||
|                 name += ' | '; |  | ||||||
|                 name += row.revision; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (row.is_template) { |  | ||||||
|                 name = '<i>' + name + '</i>'; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             var display = imageHoverIcon(row.thumbnail) + renderLink(name, '/part/' + row.pk + '/'); |             var display = imageHoverIcon(row.thumbnail) + renderLink(name, '/part/' + row.pk + '/'); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user