2024-11-18 21:27:21 +01:00
|
|
|
import uuid
|
|
|
|
from django.shortcuts import redirect
|
2024-11-18 20:56:23 +01:00
|
|
|
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.core.exceptions import ValidationError
|
|
|
|
from django.db.models import Q
|
|
|
|
from django.db.models.functions import Lower
|
2024-11-18 21:27:21 +01:00
|
|
|
from ..models import Storage, Stock
|
|
|
|
from ..forms import *
|
2024-11-18 20:56:23 +01:00
|
|
|
from .generic_views import BaseTemplateMixin
|
|
|
|
|
|
|
|
class StockView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
|
|
|
template_name = 'parts/stocks.html'
|
|
|
|
base_title = 'Stocks'
|
|
|
|
navbar_selected = 'Stocks'
|
|
|
|
default_pagination_size = 25
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
|
|
|
|
storage_page = self.request.GET.get('storage_page')
|
|
|
|
if storage_page is None:
|
|
|
|
storage_page = 1
|
|
|
|
low_stock_page = self.request.GET.get('low_stock_page')
|
|
|
|
if low_stock_page is None:
|
|
|
|
low_stock_page = 1
|
|
|
|
|
|
|
|
storage_paginator = Paginator(Storage.objects.filter(parent_storage=None), self.default_pagination_size)
|
|
|
|
low_stock_paginator = Paginator(Stock.get_under_watermark(),
|
|
|
|
self.default_pagination_size)
|
|
|
|
|
|
|
|
context['low_stocks'] = low_stock_paginator.get_page(low_stock_page)
|
|
|
|
context['storages'] = storage_paginator.get_page(storage_page)
|
|
|
|
add_stor_form = AddSubStorageForm()
|
|
|
|
add_stor_form.fields['responsible'].initial = self.request.user.id
|
|
|
|
context['add_storage_form'] = add_stor_form
|
|
|
|
return context
|
|
|
|
|
|
|
|
def handle_add_storage(self, request, **kwargs):
|
|
|
|
f = AddSubStorageForm(data=request.POST)
|
|
|
|
if f.is_valid():
|
|
|
|
sub_name = f.cleaned_data['storage_name']
|
|
|
|
try:
|
|
|
|
Storage.objects.create(name=sub_name,
|
|
|
|
responsible=f.cleaned_data['responsible'],
|
|
|
|
is_template=f.cleaned_data['is_template'],
|
|
|
|
template=f.cleaned_data.get('template'))
|
|
|
|
except ValidationError as v_err:
|
|
|
|
f.add_error('storage_name', '. '.join(v_err.messages))
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
|
|
context['add_storage_form'] = f
|
|
|
|
return self.render_to_response(context)
|
|
|
|
|
|
|
|
def post(self, request, **kwargs):
|
|
|
|
if 'submit-add-storage' in request.POST:
|
|
|
|
return self.handle_add_storage(request, **kwargs)
|
|
|
|
|
|
|
|
return super().post(request, **kwargs)
|
|
|
|
|
|
|
|
class StockViewDetail(LoginRequiredMixin, BaseTemplateMixin, DetailView):
|
|
|
|
template_name = 'parts/stocks-detail.html'
|
|
|
|
model = Storage
|
|
|
|
pk_url_kwarg = 'uuid'
|
|
|
|
base_title = ''
|
|
|
|
navbar_selected = 'Stocks'
|
|
|
|
default_pagination_size = 8
|
|
|
|
|
|
|
|
def get_breadcrumbs(self):
|
|
|
|
crumbs = self.object.get_path_components()
|
|
|
|
# Reverse list and drop the last element of the reversed list
|
|
|
|
crumbs = crumbs[::-1][:-1]
|
|
|
|
return crumbs
|
|
|
|
|
|
|
|
def search_stock_queryset(self, search):
|
|
|
|
stocks_in_storage = Stock.objects.filter(storage=self.object).order_by(Lower('component__name'))
|
2024-11-18 21:27:21 +01:00
|
|
|
|
2024-11-18 20:56:23 +01:00
|
|
|
if search is None or search == '':
|
|
|
|
return stocks_in_storage
|
|
|
|
|
|
|
|
if search.startswith('[comp_uuid]'):
|
|
|
|
search = search.replace('[comp_uuid]', '')
|
|
|
|
|
|
|
|
|
|
|
|
# Check if the searhc equals a UUID
|
|
|
|
test_uuid = None
|
|
|
|
try:
|
|
|
|
test_uuid = uuid.UUID(search)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
if test_uuid is not None:
|
|
|
|
stocks_in_storage = stocks_in_storage.filter(Q(component__id = test_uuid) | Q(id= test_uuid))
|
|
|
|
else:
|
|
|
|
stocks_in_storage = stocks_in_storage.filter(Q(component__name__icontains = search) |
|
|
|
|
Q(component__package__name__icontains = search) |
|
|
|
|
Q(component__manufacturer__name__icontains = search))
|
2024-11-18 21:27:21 +01:00
|
|
|
|
2024-11-18 20:56:23 +01:00
|
|
|
return stocks_in_storage
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
self.base_title = 'Stocks / ' + self.object.name
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
context['breadcrumbs'] = self.get_breadcrumbs()
|
|
|
|
|
|
|
|
storage_page = self.request.GET.get('storage_page', default=1)
|
|
|
|
storage_paginator = Paginator(Storage.objects.filter(parent_storage=self.object), self.default_pagination_size)
|
|
|
|
stock_search_input = self.request.GET.get('search')
|
|
|
|
|
|
|
|
componente_stock_page = self.request.GET.get('stock_page', default=1)
|
2024-11-18 21:27:21 +01:00
|
|
|
|
2024-11-18 20:56:23 +01:00
|
|
|
stock_paginator = Paginator(self.search_stock_queryset(stock_search_input), self.default_pagination_size)
|
|
|
|
|
|
|
|
context['storages'] = storage_paginator.get_page(storage_page)
|
|
|
|
stocks = stock_paginator.get_page(componente_stock_page)
|
|
|
|
context['stocks'] = stocks
|
|
|
|
context['stock_search'] = stock_search_input
|
|
|
|
add_storage_form = AddSubStorageForm()
|
|
|
|
add_storage_form.fields['responsible'].initial = self.request.user.id
|
|
|
|
context['add_storage_form'] = add_storage_form
|
|
|
|
change_storage_form = ChangeStorageForm()
|
|
|
|
change_storage_form.fields['storage_name'].initial = self.object.name
|
|
|
|
change_storage_form.fields['verbose_name'].initial = self.object.verbose_name
|
|
|
|
change_storage_form.fields['responsible'].initial = self.object.responsible.id
|
|
|
|
change_storage_form.fields['is_template'].initial = self.object.is_template
|
|
|
|
context['change_storage_form'] = change_storage_form
|
|
|
|
context['delete_storage_error'] = None
|
|
|
|
context['add_stock_form'] = AddStockForm()
|
|
|
|
|
|
|
|
return context
|
|
|
|
|
|
|
|
def handle_add_storage_post(self, request, **kwargs):
|
|
|
|
f = AddSubStorageForm(data=request.POST)
|
|
|
|
if f.is_valid():
|
|
|
|
sub_name = f.cleaned_data['storage_name']
|
|
|
|
try:
|
|
|
|
Storage.objects.create(name=sub_name,
|
|
|
|
verbose_name=f.cleaned_data.get('verbose_name'),
|
|
|
|
parent_storage=self.object,
|
|
|
|
responsible=f.cleaned_data['responsible'],
|
|
|
|
is_template=f.cleaned_data['is_template'],
|
|
|
|
template=f.cleaned_data.get('template'))
|
|
|
|
except ValidationError as v_err:
|
|
|
|
f.add_error('storage_name', '. '.join(v_err.messages))
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
|
|
context['add_storage_form'] = f
|
|
|
|
return self.render_to_response(context)
|
|
|
|
|
|
|
|
def handle_change_storage_post(self, request, **kwargs):
|
|
|
|
f = ChangeStorageForm(data=request.POST)
|
|
|
|
if f.is_valid():
|
|
|
|
try:
|
|
|
|
self.object.name = f.cleaned_data['storage_name']
|
|
|
|
self.object.verbose_name = f.cleaned_data.get('verbose_name')
|
|
|
|
self.object.responsible = f.cleaned_data['responsible']
|
|
|
|
self.object.is_template = f.cleaned_data['is_template']
|
|
|
|
self.object.save()
|
|
|
|
except ValidationError as v_err:
|
|
|
|
f.add_error('storage_name', '. '.join(v_err.messages))
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
|
|
context['change_storage_form'] = f
|
|
|
|
return self.render_to_response(context)
|
|
|
|
|
|
|
|
def handle_del_storage_post(self, request, **kwargs):
|
|
|
|
parent = self.object.parent_storage
|
2024-11-18 21:27:21 +01:00
|
|
|
try:
|
2024-11-18 20:56:23 +01:00
|
|
|
self.object.delete()
|
|
|
|
except:
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
|
|
context['delete_storage_errors'] = ['Error deleting Storage '+str(self.object)]
|
|
|
|
return self.render_to_response(context)
|
2024-11-18 21:27:21 +01:00
|
|
|
|
2024-11-18 20:56:23 +01:00
|
|
|
if parent is None:
|
|
|
|
return redirect('parts-stocks')
|
|
|
|
else:
|
|
|
|
return redirect(reverse('parts-stocks-detail', kwargs={'uuid':parent.id}))
|
|
|
|
|
|
|
|
def handle_del_stock_post(self, request, **kwargs):
|
2024-11-18 21:27:21 +01:00
|
|
|
del_error = None # TODO: Check error handling. This is clearly not working as intended :P
|
2024-11-18 20:56:23 +01:00
|
|
|
if 'stock_uuid' in request.POST:
|
|
|
|
f = DeleteStockForm(data=request.POST)
|
|
|
|
if f.is_valid():
|
|
|
|
try:
|
|
|
|
s = Stock.objects.get(id=f.cleaned_data['stock_uuid'])
|
|
|
|
print(s.storage)
|
|
|
|
print(self.object)
|
|
|
|
if s.storage == self.object:
|
|
|
|
s.delete()
|
|
|
|
else:
|
2024-11-18 21:27:21 +01:00
|
|
|
del_error = 'Cannot delete stock from another storage.'
|
2024-11-18 20:56:23 +01:00
|
|
|
except:
|
|
|
|
del_error = 'Could not find requested stock in this storage.'
|
2024-11-18 21:27:21 +01:00
|
|
|
|
2024-11-18 20:56:23 +01:00
|
|
|
context = self.get_context_data(**kwargs)
|
|
|
|
return self.render_to_response(context)
|
2024-11-18 21:27:21 +01:00
|
|
|
|
2024-11-18 20:56:23 +01:00
|
|
|
def handle_update_watermark(self, request, **kwargs):
|
|
|
|
edit_form = EditWatermarkForm(data=request.POST)
|
|
|
|
if edit_form.is_valid():
|
|
|
|
edit_form.save()
|
|
|
|
else:
|
|
|
|
pass # Todo: Handle error
|
|
|
|
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
|
|
return self.render_to_response(context)
|
2024-11-18 21:27:21 +01:00
|
|
|
|
2024-11-18 20:56:23 +01:00
|
|
|
def handle_amount_change_post(self, request, increase, **kwargs):
|
|
|
|
edit_form = EditStockAmountForm(data=request.POST)
|
|
|
|
if edit_form.is_valid():
|
|
|
|
edit_form.save(increase)
|
|
|
|
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
|
|
return self.render_to_response(context)
|
|
|
|
|
|
|
|
def handle_add_stock_post(self, request, **kwargs):
|
|
|
|
f = AddStockForm(data=request.POST)
|
|
|
|
error_occured = False
|
|
|
|
|
|
|
|
if f.is_valid():
|
|
|
|
try:
|
|
|
|
f.save(self.object)
|
|
|
|
except Exception as ex:
|
|
|
|
f.add_error('', str(ex))
|
|
|
|
error_occured = True
|
|
|
|
else:
|
|
|
|
error_occured = True
|
|
|
|
|
|
|
|
context = self.get_context_data(**kwargs)
|
|
|
|
if error_occured:
|
|
|
|
context['add_stock_form'] = f
|
|
|
|
return self.render_to_response(context)
|
|
|
|
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
|
|
self.object = self.get_object()
|
|
|
|
|
|
|
|
if 'submit-add-storage' in request.POST:
|
|
|
|
return self.handle_add_storage_post(request, **kwargs)
|
|
|
|
elif 'submit-change-storage' in request.POST:
|
|
|
|
return self.handle_change_storage_post(request, **kwargs)
|
|
|
|
elif 'submit-delete-storage' in request.POST:
|
|
|
|
return self.handle_del_storage_post(request, **kwargs)
|
|
|
|
elif 'submit-delete-stock' in request.POST:
|
|
|
|
return self.handle_del_stock_post(request, **kwargs)
|
|
|
|
elif 'submit-edit-watermark' in request.POST:
|
|
|
|
return self.handle_update_watermark(request, **kwargs)
|
|
|
|
elif 'submit-amount-reduce' in request.POST:
|
|
|
|
return self.handle_amount_change_post(request, False, **kwargs)
|
|
|
|
elif 'submit-amount-increase' in request.POST:
|
2024-11-18 21:27:21 +01:00
|
|
|
return self.handle_amount_change_post(request, True, **kwargs)
|
2024-11-18 20:56:23 +01:00
|
|
|
elif 'submit-add-stock' in request.POST:
|
|
|
|
return self.handle_add_stock_post(request, **kwargs)
|
|
|
|
|
|
|
|
return super().post(request, *args, **kwargs)
|