stefan
bbcbf6ab3d
the error handling is very basic, but effective some missing features like ordering ...and maybe a potential security as the search will allow search for all attributes somehow related to the component model
285 lines
12 KiB
Python
285 lines
12 KiB
Python
from django.shortcuts import redirect
|
|
from django.urls import reverse
|
|
from django.views.generic import TemplateView, DetailView
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.core.paginator import Paginator
|
|
from django.db.models import Q
|
|
from django.forms import formset_factory
|
|
from django.db import IntegrityError
|
|
from django.db.models import ProtectedError
|
|
from shimatta_modules.ShimattaSearchLanguage import ShimattaSearchLanguage
|
|
from ..models import Stock, Component, ComponentParameter, DistributorNum, PackageParameter
|
|
from ..forms import *
|
|
from .component_import import import_components_from_csv
|
|
from .generic_views import BaseTemplateMixin
|
|
|
|
|
|
ParameterSearchFormSet = formset_factory(ComponentParameterSearchForm, extra=1)
|
|
|
|
# Create your views here.
|
|
|
|
class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
|
template_name = 'parts/components.html'
|
|
base_title = 'Components'
|
|
navbar_selected = 'Components'
|
|
default_page_size = 25
|
|
|
|
def get_component_query_set(self, search_string):
|
|
queryset = Component.objects.all()
|
|
error_string = ''
|
|
|
|
if not search_string:
|
|
return queryset
|
|
|
|
search_parser = ShimattaSearchLanguage()
|
|
query, errors = search_parser.search_for_components(search_string)
|
|
|
|
if query:
|
|
try:
|
|
queryset = queryset.filter(query)
|
|
except Exception as ex:
|
|
error_string = str(ex)
|
|
else:
|
|
error_string = '<br><br>'.join(errors)
|
|
|
|
return queryset, error_string
|
|
|
|
def get_component_queryset_from_advanced_search(self, cleaned_data):
|
|
queryset = Component.objects.all()
|
|
|
|
if cleaned_data['name']:
|
|
queryset = queryset.filter(Q(name__icontains=cleaned_data['name']))
|
|
if cleaned_data['package']:
|
|
queryset = queryset.filter(package=cleaned_data['package'])
|
|
if cleaned_data['package_pin_count']:
|
|
queryset = queryset.filter(package__pin_count=cleaned_data['package_pin_count'])
|
|
if cleaned_data['component_type']:
|
|
queryset = queryset.filter(component_type=cleaned_data['component_type'])
|
|
if cleaned_data['distributor_num']:
|
|
if cleaned_data['distributor']:
|
|
distri = cleaned_data['distributor']
|
|
queryset = queryset.filter(Q(distributornum__distributor_part_number__icontains=cleaned_data['distributor_num']) & Q(distributornum__distributor=distri))
|
|
else:
|
|
queryset = queryset.filter(Q(distributornum__distributor_part_number__icontains=cleaned_data['distributor_num']))
|
|
if cleaned_data['manufacturer']:
|
|
queryset = queryset.filter(manufacturer=cleaned_data['manufacturer'])
|
|
return queryset
|
|
|
|
def get_context_data_int(self, advanced_search, parameter_formset : ParameterSearchFormSet, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
errors = ''
|
|
|
|
comp_page_num = self.request.GET.get('comp_page', default=1)
|
|
|
|
if advanced_search and parameter_formset:
|
|
search = None
|
|
context['advanced_search_shown'] = True
|
|
context['advanced_search_form'] = advanced_search
|
|
context['advanced_search_param_formset'] = parameter_formset
|
|
if advanced_search.is_valid():
|
|
paginator_queryset = self.get_component_queryset_from_advanced_search(
|
|
advanced_search.cleaned_data)
|
|
else:
|
|
paginator_queryset = Component.objects.all()
|
|
|
|
if parameter_formset.is_valid():
|
|
# Process parameters
|
|
pass
|
|
|
|
else:
|
|
search = self.request.GET.get('search', default=None)
|
|
paginator_queryset, errors = self.get_component_query_set(search)
|
|
|
|
comp_paginator = Paginator(paginator_queryset, self.default_page_size)
|
|
|
|
context['components'] = comp_paginator.get_page(comp_page_num)
|
|
context['comp_form'] = ComponentForm()
|
|
context['import_comp_form'] = ImportComponentForm()
|
|
context['search_string'] = search
|
|
context['errors'] = errors
|
|
|
|
if not parameter_formset:
|
|
context['advanced_search_param_formset'] = ParameterSearchFormSet()
|
|
|
|
if not advanced_search:
|
|
context['advanced_search_form'] = AdvancedComponentSearchForm(auto_id='adv_search_%s')
|
|
|
|
return context
|
|
|
|
def get_context_data(self, **kwargs):
|
|
return self.get_context_data_int(advanced_search = None, parameter_formset=None, **kwargs)
|
|
|
|
def handle_new_component_post(self, request, open=False, **kwargs):
|
|
cform = ComponentForm(data=request.POST, files=request.FILES)
|
|
new_component = None
|
|
if cform.is_valid():
|
|
new_component = cform.save()
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
if not cform.is_valid():
|
|
context['comp_form'] = cform
|
|
|
|
if open and new_component:
|
|
return redirect(reverse('parts-components-detail', kwargs={'uuid':new_component.id}))
|
|
return self.render_to_response(context)
|
|
|
|
def handle_import_components_post(self, request, open=False, **kwargs):
|
|
cform = ImportComponentForm(data=request.POST, files=request.FILES)
|
|
context = self.get_context_data(**kwargs)
|
|
if cform.is_valid():
|
|
try:
|
|
import_components_from_csv(cform.files['csv_file'].file)
|
|
except Exception as ex:
|
|
cform.add_error('csv_file', str(ex))
|
|
context['import_comp_form'] = cform
|
|
else:
|
|
context['import_comp_form'] = cform
|
|
|
|
return self.render_to_response(context)
|
|
|
|
def handle_advanced_search_post(self, request, **kwargs):
|
|
|
|
form = AdvancedComponentSearchForm(auto_id='adv_search_%s', data=request.POST)
|
|
param_formset = ParameterSearchFormSet(data=request.POST)
|
|
|
|
if form.is_valid():
|
|
print('Valid')
|
|
|
|
if param_formset.is_valid():
|
|
print('Formset is valid!')
|
|
|
|
|
|
context = self.get_context_data_int(form, param_formset, **kwargs)
|
|
return self.render_to_response(context)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
if 'submit-edit-component' in request.POST:
|
|
return self.handle_new_component_post(request, open=False, **kwargs)
|
|
elif 'submit-edit-component-open' in request.POST:
|
|
return self.handle_new_component_post(request, open=True, **kwargs)
|
|
elif 'submit-import-components' in request.POST:
|
|
return self.handle_import_components_post(request, open=True, **kwargs)
|
|
elif 'submit-advanced-search' in request.POST:
|
|
return self.handle_advanced_search_post(request, **kwargs)
|
|
else:
|
|
return super().post(request, *args, **kwargs)
|
|
|
|
class ComponentDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
|
|
template_name = 'parts/components-detail.html'
|
|
model = Component
|
|
pk_url_kwarg = 'uuid'
|
|
base_title = ''
|
|
navbar_selected = 'Components'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
self.base_title = 'Component / '+self.object.name
|
|
context = super().get_context_data(**kwargs)
|
|
context['component'] = self.object
|
|
context['stocks'] = Stock.objects.filter(component=self.object)
|
|
context['comp_form'] = ComponentForm(instance=self.object)
|
|
context['new_distri_num_form'] = DistributorNumberCreateForm()
|
|
context['new_param_form'] = ComponentParameterCreateForm()
|
|
context['distri_nums'] = DistributorNum.objects.filter(component=self.object).order_by(
|
|
'distributor__name')
|
|
context['parameters'] = ComponentParameter.objects.filter(component=self.object).order_by(
|
|
'parameter_type__parameter_name')
|
|
context['package_parameters'] = PackageParameter.objects.filter(package=self.object.package).order_by(
|
|
'parameter_type__parameter_name')
|
|
|
|
return context
|
|
|
|
def handle_submit_edit_component_post(self, request, **kwargs):
|
|
cform = ComponentForm(instance=self.object, data=request.POST, files=request.FILES)
|
|
if cform.is_valid():
|
|
cform.save()
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
if not cform.is_valid():
|
|
context['comp_form'] = cform
|
|
|
|
return self.render_to_response(context)
|
|
|
|
def handle_submit_delete_post(self, request, **kwargs):
|
|
delete_error = None
|
|
protected_stuff = None
|
|
|
|
try:
|
|
self.object.delete()
|
|
except ProtectedError as pe:
|
|
delete_error = 'Component is protected'
|
|
protected_stuff = pe.protected_objects
|
|
except:
|
|
delete_error = 'Cannot delete component. Unknown error'
|
|
|
|
if delete_error is None:
|
|
return redirect('parts-components')
|
|
else:
|
|
context = self.get_context_data(**kwargs)
|
|
context['delete_error'] = delete_error
|
|
context['protected_stuff'] = protected_stuff
|
|
return self.render_to_response(context)
|
|
|
|
def handle_submit_new_distri_num_post(self, request, **kwargs):
|
|
form = DistributorNumberCreateForm(data=request.POST)
|
|
if form.is_valid():
|
|
new_number = form.save(commit=False)
|
|
new_number.component = self.object
|
|
try:
|
|
new_number.save()
|
|
except IntegrityError as ie:
|
|
form.add_error('__all__', 'Number for given distributor already exists')
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
if not form.is_valid():
|
|
context['new_distri_num_form'] = form
|
|
return self.render_to_response(context)
|
|
|
|
def handle_submit_delete_distri_num_post(self, request, **kwargs):
|
|
form = DistributorNumberDeleteForm(data=request.POST)
|
|
if form.is_valid():
|
|
form.cleaned_data['distributor_num'].delete()
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
return self.render_to_response(context)
|
|
|
|
def handle_submit_delete_param_post(self, request, **kwargs):
|
|
form = ComponentParameterDeleteForm(data=request.POST)
|
|
if form.is_valid():
|
|
form.cleaned_data['param_num'].delete()
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
return self.render_to_response(context)
|
|
|
|
def handle_submit_new_param_post(self, request, **kwargs):
|
|
form = ComponentParameterCreateForm(data=request.POST)
|
|
|
|
if form.is_valid():
|
|
try:
|
|
form.save(self.object)
|
|
except IntegrityError:
|
|
form.add_error('__all__', 'This parameter is already set')
|
|
context = self.get_context_data(**kwargs)
|
|
if not form.is_valid():
|
|
context['new_param_form'] = form
|
|
return self.render_to_response(context)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
self.object = self.get_object()
|
|
if 'submit-edit-component' in request.POST:
|
|
return self.handle_submit_edit_component_post(request, **kwargs)
|
|
elif 'submit-component-delete' in request.POST:
|
|
return self.handle_submit_delete_post(request, **kwargs)
|
|
elif 'submit-create-new-distri-num' in request.POST:
|
|
return self.handle_submit_new_distri_num_post(request, **kwargs)
|
|
elif 'submit-delete-distributor-num' in request.POST:
|
|
return self.handle_submit_delete_distri_num_post(request, **kwargs)
|
|
elif 'submit-delete-param' in request.POST:
|
|
return self.handle_submit_delete_param_post(request, **kwargs)
|
|
elif 'submit-create-new-param' in request.POST:
|
|
return self.handle_submit_new_param_post(request, **kwargs)
|
|
else:
|
|
return super().post(request, *args, **kwargs)
|
|
|
|
|