added template based dynamic description
This commit is contained in:
		@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Generated by Django 5.1.3 on 2025-01-31 21:14
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('parts', '0014_storage_expand_sub_storage_stocks'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='componenttype',
 | 
				
			||||||
 | 
					            name='description_template',
 | 
				
			||||||
 | 
					            field=models.TextField(blank=True),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Generated by Django 5.1.3 on 2025-01-31 21:44
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('parts', '0015_componenttype_description_template'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='componentparametertype',
 | 
				
			||||||
 | 
					            name='interfix',
 | 
				
			||||||
 | 
					            field=models.CharField(blank=True, max_length=10),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -6,6 +6,7 @@ from django.core.exceptions import ValidationError
 | 
				
			|||||||
from django.core.validators import RegexValidator
 | 
					from django.core.validators import RegexValidator
 | 
				
			||||||
from django.dispatch import receiver
 | 
					from django.dispatch import receiver
 | 
				
			||||||
from django.core.validators import MinValueValidator, MaxValueValidator
 | 
					from django.core.validators import MinValueValidator, MaxValueValidator
 | 
				
			||||||
 | 
					from django.template import engines
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import uuid
 | 
					import uuid
 | 
				
			||||||
from shimatta_modules.EngineeringNumberConverter import EngineeringNumberConverter as NumConv
 | 
					from shimatta_modules.EngineeringNumberConverter import EngineeringNumberConverter as NumConv
 | 
				
			||||||
@@ -29,6 +30,7 @@ class ComponentParameterType(models.Model):
 | 
				
			|||||||
	parameter_name = models.CharField(max_length=50, unique=True)
 | 
						parameter_name = models.CharField(max_length=50, unique=True)
 | 
				
			||||||
	parameter_description = models.TextField(null=False, blank=True)
 | 
						parameter_description = models.TextField(null=False, blank=True)
 | 
				
			||||||
	unit = models.CharField(max_length=10, null=False, blank=True)
 | 
						unit = models.CharField(max_length=10, null=False, blank=True)
 | 
				
			||||||
 | 
						interfix = models.CharField(max_length=10, null=False, blank=True, help_text="char to be used as decimal point in dynamic description eg. 2R2")
 | 
				
			||||||
	parameter_type = models.CharField(max_length=1, choices=TYPE_CHOICES, default='N')
 | 
						parameter_type = models.CharField(max_length=1, choices=TYPE_CHOICES, default='N')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def __str__(self):
 | 
						def __str__(self):
 | 
				
			||||||
@@ -49,6 +51,9 @@ class ComponentType(models.Model):
 | 
				
			|||||||
	class_name = models.CharField(max_length=50, unique=True)
 | 
						class_name = models.CharField(max_length=50, unique=True)
 | 
				
			||||||
	passive = models.BooleanField()
 | 
						passive = models.BooleanField()
 | 
				
			||||||
	possible_parameter = models.ManyToManyField(ComponentParameterType, blank=True)
 | 
						possible_parameter = models.ManyToManyField(ComponentParameterType, blank=True)
 | 
				
			||||||
 | 
						description_template = models.TextField(blank=True,
 | 
				
			||||||
 | 
															 help_text="Template to assemble the dynamic description. "
 | 
				
			||||||
 | 
															 "Use template syntax, access the component with 'object', parameters with 'param_*'.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def __str__(self):
 | 
						def __str__(self):
 | 
				
			||||||
		return '[' + self.class_name + ']'
 | 
							return '[' + self.class_name + ']'
 | 
				
			||||||
@@ -269,6 +274,18 @@ class Component(models.Model):
 | 
				
			|||||||
			sum = 0
 | 
								sum = 0
 | 
				
			||||||
		return sum
 | 
							return sum
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						@property
 | 
				
			||||||
 | 
						def dynamic_description(self):
 | 
				
			||||||
 | 
							django_engine = engines["django"]
 | 
				
			||||||
 | 
							template = django_engine.from_string(self.component_type.description_template)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							parameters = list(ComponentParameter.objects.filter(component=self))
 | 
				
			||||||
 | 
							parameters += list(PackageParameter.objects.filter(package=self.package))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							context = {f'param_{param.parameter_type.parameter_name}': param for param in parameters}
 | 
				
			||||||
 | 
							context.update({'object': self})
 | 
				
			||||||
 | 
							return template.render(context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AbstractParameter(models.Model):
 | 
					class AbstractParameter(models.Model):
 | 
				
			||||||
	class Meta:
 | 
						class Meta:
 | 
				
			||||||
		abstract = True
 | 
							abstract = True
 | 
				
			||||||
@@ -302,6 +319,21 @@ class AbstractParameter(models.Model):
 | 
				
			|||||||
		elif my_type == 'F':
 | 
							elif my_type == 'F':
 | 
				
			||||||
			return self.text_value
 | 
								return self.text_value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def resolved_value_as_short_string(self):
 | 
				
			||||||
 | 
							my_type = self.parameter_type.parameter_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if my_type == 'E' or my_type == 'I':
 | 
				
			||||||
 | 
								# Engineering float number
 | 
				
			||||||
 | 
								(num, prefix) = NumConv.number_to_engineering(self.value, it_unit=(True if my_type=='I' else False))
 | 
				
			||||||
 | 
								result = f'{num}'
 | 
				
			||||||
 | 
								result = result.replace('.', prefix if prefix else self.parameter_type.interfix or '.').upper()
 | 
				
			||||||
 | 
								return result
 | 
				
			||||||
 | 
							elif my_type == 'N':
 | 
				
			||||||
 | 
								# Standard float number
 | 
				
			||||||
 | 
								return  f'{self.value:g}{self.parameter_type.unit}'
 | 
				
			||||||
 | 
							else:
 | 
				
			||||||
 | 
								return self.resolved_value_as_string()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ComponentParameter(AbstractParameter):
 | 
					class ComponentParameter(AbstractParameter):
 | 
				
			||||||
	class Meta:
 | 
						class Meta:
 | 
				
			||||||
		unique_together = ('component', 'parameter_type')
 | 
							unique_together = ('component', 'parameter_type')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -101,7 +101,10 @@
 | 
				
			|||||||
                                <span class="text-secondary"><br>Lot: {{stock.lot}}</span>
 | 
					                                <span class="text-secondary"><br>Lot: {{stock.lot}}</span>
 | 
				
			||||||
                            {% endif %}
 | 
					                            {% endif %}
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                        <div class="flex-grow-2 ms-3 d-none d-lg-block">
 | 
					                        <div class="flex-grow-2 ms-3 d-none d-lg-block" style="text-align: center;">
 | 
				
			||||||
 | 
					                            <pre>{{ stock.component.dynamic_description }}</pre>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <div class="flex-grow-2 ms-5 d-none d-lg-block">
 | 
				
			||||||
                            {% qr_from_text stock.get_qr_code size="6" image_format="svg" %}
 | 
					                            {% qr_from_text stock.get_qr_code size="6" image_format="svg" %}
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                        <div class="ms-3">
 | 
					                        <div class="ms-3">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user