368 lines
14 KiB
Python
368 lines
14 KiB
Python
from django import forms
|
|
from django.contrib.auth import get_user_model
|
|
from django.core.exceptions import ValidationError
|
|
from django.forms import widgets
|
|
from parts import models as parts_models
|
|
from shimatta_modules.EngineeringNumberConverter import EngineeringNumberConverter
|
|
import uuid
|
|
from django.urls import reverse
|
|
from .qr_parser import QrCodeValidator
|
|
|
|
|
|
from crispy_forms.helper import FormHelper
|
|
from crispy_forms.layout import Layout, Row, Column
|
|
|
|
class AutoCompleteWidget(widgets.Input):
|
|
template_name = 'widgets/autocomplete-foreign-key.html'
|
|
|
|
def __init__(self, api_search_url, image_field_name, foreign_model, name_field_name, prepend=None, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.image_field_name = image_field_name
|
|
self.foreign_model = foreign_model
|
|
self.api_search_url = api_search_url
|
|
self.name_field_name = name_field_name
|
|
self.prepend = prepend
|
|
|
|
def get_context(self, name, value, attrs):
|
|
context = super().get_context(name, value, attrs)
|
|
if value is not None:
|
|
try:
|
|
try:
|
|
my_id = uuid.UUID(value)
|
|
except:
|
|
my_id = int(value)
|
|
instance = self.foreign_model.objects.get(id=my_id)
|
|
except Exception as ex:
|
|
instance = None
|
|
else:
|
|
instance = None
|
|
|
|
image = None
|
|
if instance is not None and self.image_field_name is not None:
|
|
image = getattr(instance, self.image_field_name)
|
|
|
|
display_name = None
|
|
if instance:
|
|
display_name = getattr(instance, self.name_field_name)
|
|
|
|
context['custom'] = {
|
|
'search_url': reverse(self.api_search_url),
|
|
'image_field_name': self.image_field_name,
|
|
'current_instance': instance,
|
|
'image': image,
|
|
'name_field_name': self.name_field_name,
|
|
'prepend': self.prepend,
|
|
'name': display_name,
|
|
}
|
|
return context
|
|
|
|
class AutocompleteForeingKeyField(forms.UUIDField):
|
|
def __init__(self,
|
|
foreign_model=None,
|
|
api_search_url=None,
|
|
image_field_name='image',
|
|
name_field_name='name',
|
|
prepend=None,
|
|
**kwargs):
|
|
super().__init__(**kwargs)
|
|
self.widget = AutoCompleteWidget(api_search_url,
|
|
image_field_name,
|
|
foreign_model,
|
|
name_field_name,
|
|
prepend)
|
|
self.foreign_model = foreign_model
|
|
|
|
|
|
def clean(self, value):
|
|
try:
|
|
pre_cleaned_uuid = super().clean(value)
|
|
except Exception as ex:
|
|
try:
|
|
pre_cleaned_uuid = int(value)
|
|
except:
|
|
raise ex
|
|
if pre_cleaned_uuid is None and not self.required:
|
|
return None
|
|
try:
|
|
obj = self.foreign_model.objects.get(id=pre_cleaned_uuid)
|
|
except self.foreign_model.DoesNotExist:
|
|
raise ValidationError('Given element does not exist')
|
|
return obj
|
|
|
|
class MyTestForm(forms.Form):
|
|
pass
|
|
|
|
class ChangeStorageForm(forms.Form):
|
|
storage_name = forms.CharField(label="Name", initial='')
|
|
verbose_name = forms.CharField(label="Verbose Name", initial='', required=False)
|
|
responsible = AutocompleteForeingKeyField(api_search_url='user-list',
|
|
image_field_name=None,
|
|
name_field_name='username',
|
|
foreign_model=get_user_model(),
|
|
prepend='@')
|
|
|
|
is_template = forms.BooleanField(label='is_template', required=False)
|
|
|
|
class AddSubStorageForm(ChangeStorageForm):
|
|
template = AutocompleteForeingKeyField(api_search_url='storage-template-list',
|
|
image_field_name=None,
|
|
foreign_model=parts_models.Storage,
|
|
required=False)
|
|
|
|
class DeleteStockForm(forms.Form):
|
|
stock_uuid = forms.UUIDField()
|
|
|
|
class EditWatermarkForm(forms.Form):
|
|
stock_uuid = forms.UUIDField()
|
|
watermark_active = forms.BooleanField(required=False) #If it is false, the webbrowser won't send it at all. Therefore we have to set it to required=False
|
|
watermark = forms.IntegerField(min_value=0)
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
id = cleaned_data.get("stock_uuid")
|
|
|
|
if not id:
|
|
raise ValidationError("No stock UUID given")
|
|
|
|
stock = None
|
|
try:
|
|
stock = parts_models.Stock.objects.get(id=id)
|
|
except:
|
|
raise ValidationError("Stock with uuid %s does not exist" % (id))
|
|
cleaned_data['stock'] = stock
|
|
|
|
return cleaned_data
|
|
|
|
def save(self):
|
|
stock = self.cleaned_data['stock']
|
|
active = self.cleaned_data['watermark_active']
|
|
watermark = self.cleaned_data['watermark']
|
|
|
|
if not active:
|
|
watermark = -1
|
|
|
|
stock.watermark = watermark
|
|
stock.save()
|
|
|
|
class EditStockAmountForm(forms.Form):
|
|
stock_uuid = forms.UUIDField()
|
|
amount = forms.IntegerField(min_value=0)
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
id = cleaned_data.get("stock_uuid")
|
|
|
|
if not id:
|
|
raise ValidationError("No stock UUID given")
|
|
|
|
stock = None
|
|
try:
|
|
stock = parts_models.Stock.objects.get(id=id)
|
|
except:
|
|
raise ValidationError("Stock with uuid %s does not exist" % (id))
|
|
cleaned_data['stock'] = stock
|
|
|
|
return cleaned_data
|
|
|
|
def save(self, increase: bool):
|
|
stock = self.cleaned_data['stock']
|
|
amount = self.cleaned_data['amount']
|
|
|
|
if not increase:
|
|
amount = -amount
|
|
|
|
return stock.atomic_increment(amount)
|
|
|
|
class AddStockForm(forms.Form):
|
|
watermark_active = forms.BooleanField(required=False)
|
|
watermark = forms.IntegerField(min_value=0, required=True, initial=0)
|
|
amount = forms.IntegerField(min_value=0, required=True, initial=1)
|
|
component_uuid = forms.UUIDField(required=True)
|
|
lot = forms.CharField(max_length=255, required=False)
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
|
|
id = cleaned_data.get('component_uuid')
|
|
if not id:
|
|
raise ValidationError('No valid component selected!')
|
|
component = None
|
|
try:
|
|
component = parts_models.Component.objects.get(id=id)
|
|
except:
|
|
raise ValidationError("Invalid component selected!")
|
|
cleaned_data['component'] = component
|
|
|
|
return cleaned_data
|
|
|
|
def save(self, storage):
|
|
component = self.cleaned_data.get('component')
|
|
amount = self.cleaned_data.get('amount')
|
|
watermark = -1
|
|
|
|
if self.cleaned_data.get('watermark_active'):
|
|
watermark = self.cleaned_data.get('watermark')
|
|
|
|
new_stock = parts_models.Stock.objects.create(storage=storage, component=component, watermark=watermark, amount=amount, lot=self.cleaned_data['lot'])
|
|
new_stock.save()
|
|
|
|
class ComponentForm(forms.ModelForm):
|
|
manufacturer = AutocompleteForeingKeyField(api_search_url='manufacturer-list', foreign_model=parts_models.Manufacturer, required=False)
|
|
component_type = AutocompleteForeingKeyField(api_search_url='componenttype-list', foreign_model=parts_models.ComponentType, name_field_name='class_name', required=False, image_field_name=None)
|
|
package = AutocompleteForeingKeyField(api_search_url='package-list', foreign_model=parts_models.Package, required=False)
|
|
pref_distri = AutocompleteForeingKeyField(api_search_url='distributor-list', foreign_model=parts_models.Distributor, required=False)
|
|
class Meta:
|
|
model = parts_models.Component
|
|
fields = '__all__'
|
|
|
|
class ImportComponentForm(forms.Form):
|
|
csv_file = forms.FileField(label="CSV File")
|
|
|
|
class PackageForm(forms.ModelForm):
|
|
class Meta:
|
|
model = parts_models.Package
|
|
fields = '__all__'
|
|
|
|
class DistributorForm(forms.ModelForm):
|
|
class Meta:
|
|
model = parts_models.Distributor
|
|
fields = '__all__'
|
|
class ManufacturerForm(forms.ModelForm):
|
|
class Meta:
|
|
model = parts_models.Manufacturer
|
|
fields = '__all__'
|
|
|
|
class DistributorNumberCreateForm(forms.ModelForm):
|
|
distributor = AutocompleteForeingKeyField(api_search_url='distributor-list', foreign_model=parts_models.Distributor, required=True)
|
|
|
|
class Meta:
|
|
model = parts_models.DistributorNum
|
|
fields = ['distributor', 'distributor_part_number']
|
|
|
|
class DistributorNumberDeleteForm(forms.Form):
|
|
distributor_num = forms.UUIDField(required=True)
|
|
|
|
def clean_distributor_num(self):
|
|
my_uuid = self.cleaned_data['distributor_num']
|
|
try:
|
|
distributor_number = parts_models.DistributorNum.objects.get(id=my_uuid)
|
|
except:
|
|
raise ValidationError('distributor number invalid')
|
|
return distributor_number
|
|
|
|
class ComponentParameterDeleteForm(forms.Form):
|
|
param_num = forms.UUIDField(required=True)
|
|
model = parts_models.ComponentParameter
|
|
|
|
def clean_param_num(self):
|
|
my_uuid = self.cleaned_data['param_num']
|
|
try:
|
|
param = self.model.objects.get(id=my_uuid)
|
|
except:
|
|
raise ValidationError('Parameter Number Invalid')
|
|
return param
|
|
|
|
class PackageParameterDeleteForm(ComponentParameterDeleteForm):
|
|
model = parts_models.PackageParameter
|
|
|
|
class AdvancedComponentSearchForm(forms.Form):
|
|
name = forms.CharField(max_length=255, label='Component Name', required=False)
|
|
package = AutocompleteForeingKeyField(required=False, api_search_url='package-list', foreign_model=parts_models.Package)
|
|
package_pin_count = forms.IntegerField(min_value=0, label='Pin Count', required=False)
|
|
distributor_num = forms.CharField(max_length=100, label='Distributor Part Number', required=False)
|
|
distributor = AutocompleteForeingKeyField(required=False, api_search_url='distributor-list', foreign_model=parts_models.Distributor)
|
|
component_type = AutocompleteForeingKeyField(required=False, api_search_url='componenttype-list', foreign_model=parts_models.ComponentType, image_field_name=None, name_field_name='class_name')
|
|
manufacturer = AutocompleteForeingKeyField(required=False, api_search_url='manufacturer-list', foreign_model=parts_models.Manufacturer)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.helper = FormHelper()
|
|
self.helper.form_tag = False
|
|
self.helper.layout = Layout(
|
|
Row(
|
|
Column('name'),
|
|
),
|
|
Row(
|
|
Column('package'),
|
|
Column('package_pin_count'),
|
|
),
|
|
Row(
|
|
Column('component_type'),
|
|
Column('manufacturer'),
|
|
),
|
|
Row(
|
|
Column('distributor'),
|
|
Column('distributor_num'),
|
|
),
|
|
)
|
|
|
|
class ComponentParameterSearchForm(forms.Form):
|
|
parameter = AutocompleteForeingKeyField(required=True, foreign_model=parts_models.ComponentParameterType, api_search_url='componentparametertype-list', image_field_name=None, name_field_name='parameter_name')
|
|
value = forms.CharField(max_length=100, required=False)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.helper = FormHelper()
|
|
self.helper.form_tag = False
|
|
self.helper.layout = Layout(
|
|
Row(
|
|
Column('parameter'),
|
|
Column('value')
|
|
)
|
|
)
|
|
class ComponentParameterCreateForm(forms.Form):
|
|
parameter_type = AutocompleteForeingKeyField(required=True, foreign_model=parts_models.ComponentParameterType, api_search_url='componentparametertype-list', image_field_name=None, name_field_name='descriptive_name')
|
|
value = forms.CharField(required=True, max_length=256)
|
|
model = parts_models.ComponentParameter
|
|
|
|
def clean(self):
|
|
data = super().clean()
|
|
ptype = data.get('parameter_type')
|
|
value = data.get('value')
|
|
|
|
if not ptype:
|
|
raise ValidationError('No valid parameter type selected')
|
|
|
|
if not value:
|
|
raise ValidationError('No valid parameter value')
|
|
|
|
if ptype.parameter_type == 'E' or ptype.parameter_type == 'I' or ptype.parameter_type == 'N':
|
|
try:
|
|
number = EngineeringNumberConverter.engineering_to_number(value)
|
|
except:
|
|
raise ValidationError('Cannot convert value to number')
|
|
data['number_value'] = number
|
|
else:
|
|
pass
|
|
|
|
def save(self, component):
|
|
param_type = self.cleaned_data['parameter_type']
|
|
if param_type.parameter_type == 'F':
|
|
text_value = self.cleaned_data['value']
|
|
value = 0
|
|
else:
|
|
text_value = ''
|
|
value = self.cleaned_data['number_value']
|
|
self.model.objects.create(parameter_type=param_type, component=component, value=value, text_value=text_value)
|
|
|
|
class PackageParameterCreateForm(ComponentParameterCreateForm):
|
|
model = parts_models.PackageParameter
|
|
|
|
def save(self, package):
|
|
param_type = self.cleaned_data['parameter_type']
|
|
if param_type.parameter_type == 'F':
|
|
text_value = self.cleaned_data['value']
|
|
value = 0
|
|
else:
|
|
text_value = ''
|
|
value = self.cleaned_data['number_value']
|
|
self.model.objects.create(parameter_type=param_type, package=package, value=value, text_value=text_value)
|
|
|
|
class QrSearchForm(forms.Form):
|
|
my_qr_validator = QrCodeValidator()
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
qr_search = forms.CharField(label='qr_search', validators=[my_qr_validator]) |