Do some random coding for Distribotr numbers and Component parameters. This is probably not the most ideal solution. Will change this later

This commit is contained in:
Mario Hüttel 2021-11-13 21:05:52 +01:00
parent 5c3197e040
commit ac318ca864
6 changed files with 277 additions and 57 deletions

View File

@ -183,9 +183,25 @@ class EditComponentForm(forms.Form):
raise ValidationError('Invalid Package')
def _save_new(self):
self.instance = parts_models.Component.objects.create(
name=self.cleaned_data['name'],
datasheet_link=self.cleaned_data['datasheet_link'],
description=self.cleaned_data['description'],
package=self.cleaned_data['package_object'],
component_type=self.cleaned_data['component_type_object'],
pref_distri=self.cleaned_data['pref_distri_object'],
manufacturer=self.cleaned_data['manufacturer_object']
)
if bool(self.cleaned_data['image']):
self.instance.image = self.cleaned_data['image']
self.instance.save()
def save(self):
if self.instance is None:
self.instance = parts_models.Component.objects.create()
self._save_new()
return
self.instance.name = self.cleaned_data['name']
self.instance.datasheet_link = self.cleaned_data['datasheet_link']
@ -203,8 +219,8 @@ class EditComponentForm(forms.Form):
self.instance.save()
class EditComponentParameterForm(forms.Form):
parameter_type = forms.CharField() # This must come first. Do not change the order of these elements!
value = forms.CharField()
parameter_type = forms.CharField(initial='') # This must come first. Do not change the order of these elements!
value = forms.CharField(initial='')
def __init__(self, *args, **kwargs):
@ -215,12 +231,12 @@ class EditComponentParameterForm(forms.Form):
self.parameter_type_object = type_instance
kwargs['initial']['parameter_type'] = init_values['parameter_type'].parameter_name
if isinstance(init_values['value'], int) or isinstance(init_values['value'], float):
if type_instance.engineering_unit:
if type_instance.parameter_type == 'E':
(num, prefix) = EngineeringNumberConverter.number_to_engineering(init_values['value'], False)
kwargs['initial']['value'] = f'{num} {prefix}'
elif type_instance.it_unit:
kwargs['initial']['value'] = f'{num}{prefix}'
elif type_instance.parameter_type == 'I':
(num, prefix) = EngineeringNumberConverter.number_to_engineering(init_values['value'], True)
kwargs['initial']['value'] = f'{num} {prefix}'
kwargs['initial']['value'] = f'{num}{prefix}'
super().__init__(*args, **kwargs)
@ -245,12 +261,12 @@ class EditComponentParameterForm(forms.Form):
processed_value = None
if parameter_type.it_unit or parameter_type.engineering_unit:
if parameter_type.parameter_type == 'E' or parameter_type.parameter_type == 'I':
try:
processed_value = EngineeringNumberConverter.engineering_to_number(value_data)
except:
raise ValidationError(f'Cannot not convert Value "{value_data}" to a number')
elif parameter_type.freetext_parameter:
elif parameter_type.parameter_type == 'F':
processed_value = value_data
else:
try:
@ -261,3 +277,18 @@ class EditComponentParameterForm(forms.Form):
self.cleaned_data['processed_value'] = processed_value
return value_data
class DistributorNumberForm(forms.ModelForm):
class Meta:
model = parts_models.DistributorNum
fields = ['distributor', 'distributor_part_number']
class DistributorNumberFormSet(forms.BaseModelFormSet):
def save(self, component, commit=True):
instances = super().save(commit=False)
for instance in instances:
instance.component = component
if commit:
instance.save()
return instances

View File

@ -0,0 +1,30 @@
# Generated by Django 3.2 on 2021-11-13 15:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('parts', '0003_alter_componentparametertype_unit'),
]
operations = [
migrations.RemoveField(
model_name='componentparametertype',
name='engineering_unit',
),
migrations.RemoveField(
model_name='componentparametertype',
name='freetext_parameter',
),
migrations.RemoveField(
model_name='componentparametertype',
name='it_unit',
),
migrations.AddField(
model_name='componentparametertype',
name='parameter_type',
field=models.CharField(choices=[('F', 'Free Text'), ('N', 'Standard float number'), ('E', 'Engineering / SI Unit'), ('I', 'IT Type')], default='N', max_length=1),
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 3.2 on 2021-11-13 19:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('parts', '0004_auto_20211113_1508'),
]
operations = [
migrations.AlterModelOptions(
name='distributornum',
options={'ordering': ['distributor__name']},
),
migrations.AlterField(
model_name='componentparameter',
name='value',
field=models.FloatField(default=0),
),
]

View File

@ -17,19 +17,23 @@ class ComponentParameterType(models.Model):
class Meta:
ordering = ['parameter_name']
TYPE_CHOICES = (
('F', 'Free Text'),
('N', 'Standard float number'),
('E', 'Engineering / SI Unit'),
('I', 'IT Type'),
)
parameter_name = models.CharField(max_length=50, unique=True)
parameter_description = models.TextField(null=True, blank=True)
unit = models.CharField(max_length=10, null=True, blank=True)
freetext_parameter = models.BooleanField()
engineering_unit = models.BooleanField()
it_unit = models.BooleanField()
parameter_type = models.CharField(max_length=1, choices=TYPE_CHOICES, default='N')
def __str__(self):
unit = self.unit
if unit:
return self.parameter_name + ' in ' + unit
else:
return self.parameter_name
unit = ''
if self.unit:
unit = ' in ' + self.unit
return self.parameter_name + unit + ' | ' + self.get_parameter_type_display()
class ComponentType(models.Model):
class Meta:
@ -202,11 +206,16 @@ class ComponentParameter(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
component = models.ForeignKey(Component, on_delete=models.CASCADE) # A target component is required!
parameter_type = models.ForeignKey(ComponentParameterType, on_delete=models.CASCADE)
value = models.FloatField()
value = models.FloatField(default=0)
text_value = models.TextField(null=True, blank=True)
def __str__(self):
return str(self.parameter_type) + ': ' + str(self.value)
if self.parameter_type.parameter_type == 'F':
value = self.text_value
else:
value = str(self.value)
return str(self.component)+ ': '+ str(self.parameter_type) + ': ' + value
class Stock(models.Model):
@ -247,7 +256,7 @@ class Stock(models.Model):
class DistributorNum(models.Model):
class Meta:
unique_together = ('component', 'distributor')
ordering = ['distributor_part_number']
ordering = ['distributor__name']
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
distributor_part_number = models.CharField(max_length=100)
distributor = models.ForeignKey(Distributor, on_delete=models.CASCADE)

View File

@ -11,12 +11,12 @@ from django.views import View
import django.forms as forms
from django.views.generic import TemplateView, DetailView
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from .models import Storage, Stock, Component, Distributor, Manufacturer, Package, ComponentParameter, ComponentParameterType
from .models import Storage, Stock, Component, Distributor, Manufacturer, Package, ComponentParameter, ComponentParameterType, DistributorNum
from .qr_parser import QrCodeValidator
from django.core.paginator import Paginator
from django.core.exceptions import ValidationError
from django.db import IntegrityError
from .forms import MyTestForm, AddSubStorageForm, DeleteStockForm, EditWatermarkForm, EditStockAmountForm, AddStockForm, EditComponentForm, EditComponentParameterForm
from .forms import MyTestForm, AddSubStorageForm, DeleteStockForm, EditWatermarkForm, EditStockAmountForm, AddStockForm, EditComponentForm, EditComponentParameterForm, DistributorNumberForm, DistributorNumberFormSet
from django.db.models import Q
from django.db.models.functions import Lower
import uuid
@ -391,16 +391,18 @@ class ComponentDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
base_title = ''
navbar_selected = 'Components'
def prepare_initial_param_formset_data(self):
parameters = ComponentParameter.objects.filter(component=self.object)
initdata = []
for param in parameters:
param_type = param.parameter_type
if param_type.freetext_parameter:
param_type = param.parameter_type.parameter_type
if param_type == 'F':
value = param.text_value
else:
value = param.value
initdata.append({'parameter_type': param_type, 'value': value})
initdata.append({'parameter_type': param.parameter_type, 'value': value})
return initdata
def get_context_data(self, **kwargs):
@ -409,11 +411,14 @@ class ComponentDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
context['component'] = self.object
context['edit_form'] = EditComponentForm(instance=self.object)
ParameterFormset = forms.formset_factory(EditComponentParameterForm, extra=0, max_num=100)
ParameterFormset = forms.formset_factory(EditComponentParameterForm, extra=1, max_num=100, can_delete=True)
context['param_formset'] = ParameterFormset(
initial=self.prepare_initial_param_formset_data())
context['stocks'] = Stock.objects.filter(component=self.object)
DistriNumFormSet = forms.modelformset_factory(DistributorNum, form=DistributorNumberForm, extra=2)
context['distri_num_formset'] = DistriNumFormSet(queryset=DistributorNum.objects.filter(component=self.object), auto_id='id_fs_distri_no_%s')
return context
def handle_submit_edit_post(self, request, **kwargs):
@ -438,18 +443,76 @@ class ComponentDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
return self.render_to_response(context)
def handle_submit_edit_params_post(self, request, **kwargs):
ParameterFormset = forms.formset_factory(EditComponentParameterForm, extra=1, max_num=100)
fs = ParameterFormset(initial=self.prepare_initial_param_formset_data(), data=request.POST)
errors_set = False
if fs.is_valid():
# Go through all the parameter forms:
for form in fs:
if not form.has_changed():
continue
# Form has changed. Process the new value
try:
parameter_to_change = ComponentParameter.objects.get(component=self.object,
parameter_type__parameter_name=form.initial['parameter_type'])
parameter_to_change.parameter_type = form.cleaned_data['parameter_type_object']
parameter_to_change.value = 0
parameter_to_change.text_value = None
except:
try:
parameter_to_change = ComponentParameter.objects.create(component=self.object,
parameter_type=form.cleaned_data['parameter_type_object'])
except:
form.add_error('parameter_type', 'Parameter could not be saved. Unique?')
errors_set = True
break
parameter_to_change.value = 0
parameter_to_change.text_value = None
if parameter_to_change.parameter_type.parameter_type == 'F':
parameter_to_change.text_value = form.cleaned_data['processed_value']
parameter_to_change.value = 0
else:
parameter_to_change.value = form.cleaned_data['processed_value']
try:
parameter_to_change.save()
except:
form.add_error('parameter_type', 'Parameter could not be saved. Unique?')
errors_set = True
context = self.get_context_data()
if not fs.is_valid() or errors_set:
context['param_formset'] = fs
return self.render_to_response(context)
def handle_submit_edit_distri_nums_post(self, request, **kwargs):
DistriNumFormSet = forms.modelformset_factory(DistributorNum, form=DistributorNumberForm, extra=2, formset=DistributorNumberFormSet)
fs = DistriNumFormSet(queryset=DistributorNum.objects.filter(component=self.object), data=request.POST, auto_id='id_fs_distri_no_%s')
if fs.is_valid():
print('Valid')
fs.save(self.object)
else:
print('Invalid')
context = self.get_context_data()
if not fs.is_valid():
context['distri_num_formset'] = fs
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
if 'submit-edit-comp' in request.POST:
return self.handle_submit_edit_post(request, **kwargs)
elif 'submit-edit-params' in request.POST:
return self.handle_submit_edit_params_post(request, **kwargs)
elif 'submit-edit-distri-nums' in request.POST:
return self.handle_submit_edit_distri_nums_post(request, **kwargs)
return super().post(request, *args, **kwargs)

View File

@ -24,7 +24,7 @@
<button class="btn btn-primary mb-2" data-bs-toggle="modal" data-bs-target="#comp-edit-modal"><i class="bi bi-pencil-square"></i> Edit Component</button>
</div>
</div>
<div class="col">
<div class="col m-1">
<table class="table">
<thead>
<tr>
@ -65,17 +65,36 @@
</tr>
</tbody>
</table>
<h2>Description</h2>
{% if component.description %}
{{component.description|linebreaks}}
{% else %}
<div class="alert alert-secondary" role="alert">
No description available
</div>
{% endif %}
<div class="row">
<div class="col">
<h2>Parameters</h2>
<h2>Description</h2>
{% if component.description %}
{{component.description|linebreaks}}
{% else %}
<div class="alert alert-secondary" role="alert">
No description available
</div>
{% endif %}
</div>
<div class="col-4">
{% if component.pref_distri %}
<h4>Preferred Distributor</h4>
<div class="d-flex align-items-center">
{% if component.pref_distri.image %}
<div class="flex-shrink-0">
<img src="{{component.pref_distri.image.url}}" alt="{{component.pref_distri.name}}" class="component-img-big">
</div>
<div class="flex-grow-1 ms-2">
<h6>{{component.pref_distri.name}}</h6>
</div>
{% endif %}
</div>
{% endif %}
</div>
</div>
<div class="row">
<div class="col">
<h3>Parameters</h3>
<form method="post">
{% csrf_token %}
<table class="table">
@ -87,35 +106,81 @@
<tbody>
{% for f in param_formset %}
<tr>
<td><input type="text" class="form-control" name="{{f.parameter_type.name}}" value="{{f.parameter_type.value}}"></td>
<td><input type="text" class="form-control" name="{{f.value.name}}" value="{{f.value.value}}"></td>
<td>{{f.parameter_type_object.unit|default_if_none:""}}</td>
<td><input type="text" class="form-control{% if f.parameter_type.errors %} is-invalid{% endif %}" name="{{f.parameter_type.html_name}}" value="{{f.parameter_type.value}}"></td>
<td><input type="text" class="form-control{% if f.value.errors %} is-invalid{% endif %}" name="{{f.value.html_name}}" value="{{f.value.value}}"></td>
<td>{{f.parameter_type_object.unit|default_if_none:"-"}}</td>
</tr>
{% if f.errors %}
<tr class="text-danger">
<td>
{% if f.parameter_type.errors %}
{{f.parameter_type.errors}}
{% endif %}
</td>
<td>
{% if f.value.errors %}
{{f.value.errors}}
{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{{param_formset.management_form}}
<input type="submit" class="btn btn-primary" name="submit-edit-params" value="Save Parameters">
</form>
</div>
<div class="col">
<h2>Stocks</h2>
<table class="table">
<thead>
<th scope="col">Storage</th>
<th scope="col">Amount</th>
</thead>
<tbody>
{% for stock in stocks %}
<tr>
<td><a class="text-decoration-none text-primary" href="{% url 'parts-stocks-detail' uuid=stock.storage.id %}">{{stock.storage.get_full_path}}</a></td>
<td>{{stock.amount}}</td>
<tr>
{% endfor %}
</tbody>
</table>
<h3>Distributor Part Numbers</h3>
<form method="post">
{% csrf_token %}
<table class="table">
<thead>
<th scope="col">Distributor</th>
<th scope="col">Part Number</th>
</thead>
<tbody>
{% for form in distri_num_formset %}
<tr>
<td>
{% if form.instance.distributor %}
{{form.instance.distributor.name}}
{% else %}
<input type="text" name="__unused_search" id="{{form.distributor.id_for_label}}-search">
{% endif %}
</td>
<input type="hidden" name="{{form.distributor.html_name}}" id="{{form.distributor.id_for_label}}" value="{{form.distributor.value|default_if_none:""}}">
<input type="hidden" name="{{form.id.html_name}}" value="{{form.id.value|default_if_none:""}}">
<td>
<input class="form-control" type="text" name="{{form.distributor_part_number.html_name}}" id="{{form.distributor_part_number.id_for_label}}" value="{{form.distributor_part_number.value|default_if_none:""}}">
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{distri_num_formset.management_form}}
<input type="submit" class="btn btn-secondary" name="submit-edit-distri-nums" value="Save">
</form>
</div>
</div>
<div class="row mt-2">
<table class="table">
<thead>
<th scope="col">Storage</th>
<th scope="col">Amount</th>
</thead>
<tbody>
{% for stock in stocks %}
<tr>
<td><a class="text-decoration-none text-primary" href="{% url 'parts-stocks-detail' uuid=stock.storage.id %}">{{stock.storage.get_full_path}}</a></td>
<td>{{stock.amount}}</td>
<tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>