shimatta-kenkyusho/shimatta_kenkyusho/parts/views/component_views.py

279 lines
12 KiB
Python

from django.shortcuts import render, redirect
from django.urls import reverse
from django.contrib.auth import logout, login
from django.contrib.auth.forms import AuthenticationForm as AuthForm
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
import django.forms as forms
from django.views.generic import TemplateView, DetailView
from django.contrib.auth.mixins import LoginRequiredMixin
from ..models import Storage, Stock, Component, Distributor, Manufacturer, Package, ComponentParameter, DistributorNum
from django.core.paginator import Paginator
from django.core.exceptions import ValidationError
from django.db import IntegrityError
from django.db.models import ProtectedError
from ..forms import *
from .component_import import import_components_from_csv
from django.db.models import Q
from django.db.models.functions import Lower
from django.forms import formset_factory
from django.http import HttpResponse
import uuid
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()
if not search_string:
return queryset
search_fragments = search_string.strip().split()
for search in search_fragments:
queryset = queryset.filter(Q(name__icontains = search) | Q(manufacturer__name__icontains = search) | Q(package__name__icontains = search))
return queryset
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)
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 = 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
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')
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)