Add stock list to storage dtail view and start search

This commit is contained in:
Mario Hüttel 2021-10-31 20:57:28 +01:00
parent f4113d71d8
commit 81a644cd95
5 changed files with 107 additions and 30 deletions

View File

@ -0,0 +1,8 @@
from django import forms
class MyTestForm(forms.Form):
pass
class AddSubStorageForm(forms.Form):
storage_name = forms.CharField(label="storage_name", initial='')
responsible = forms.CharField(label='responsible_user')

View File

@ -13,6 +13,9 @@ from .models import Storage, Stock
from .qr_parser import QrCodeValidator from .qr_parser import QrCodeValidator
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from .forms import MyTestForm, AddSubStorageForm
from django.db.models import Q
import uuid
class QrSearchForm(forms.Form): class QrSearchForm(forms.Form):
my_qr_validator = QrCodeValidator() my_qr_validator = QrCodeValidator()
@ -100,10 +103,6 @@ class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
base_title = 'Components' base_title = 'Components'
navbar_selected = 'Components' navbar_selected = 'Components'
class AddSubStorageForm(forms.Form):
storage_name = forms.CharField(label="storage_name", initial='')
responsible = forms.CharField(label='responsible_user')
class StockView(LoginRequiredMixin, BaseTemplateMixin, TemplateView): class StockView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
template_name = 'parts/stocks.html' template_name = 'parts/stocks.html'
base_title = 'Stocks' base_title = 'Stocks'
@ -179,17 +178,44 @@ class StockViewDetail(LoginRequiredMixin, BaseTemplateMixin, DetailView):
crumbs = crumbs[::-1][:-1] crumbs = crumbs[::-1][:-1]
return crumbs return crumbs
def search_stock_queryset(self, search):
stocks_in_storage = Stock.objects.filter(storage=self.object)
if search is None or search == '':
return stocks_in_storage
# 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(component__id = test_uuid)
else:
stocks_in_storage = stocks_in_storage.filter(Q(component__name__contains = search) |
Q(component__package__name__contains = search))
return stocks_in_storage
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
self.base_title = 'Stocks / ' + self.object.name self.base_title = 'Stocks / ' + self.object.name
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['breadcrumbs'] = self.get_breadcrumbs() context['breadcrumbs'] = self.get_breadcrumbs()
storage_page = self.request.GET.get('storage_page') storage_page = self.request.GET.get('storage_page', default=1)
if storage_page is None:
storage_page = 1
storage_paginator = Paginator(Storage.objects.filter(parent_storage=self.object), self.default_pagination_size) 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)
stock_paginator = Paginator(self.search_stock_queryset(stock_search_input), self.default_pagination_size)
context['storages'] = storage_paginator.get_page(storage_page) context['storages'] = storage_paginator.get_page(storage_page)
context['stocks'] = stock_paginator.get_page(componente_stock_page)
context['stock_search'] = stock_search_input
add_storage_form = AddSubStorageForm() add_storage_form = AddSubStorageForm()
add_storage_form.fields['responsible'].initial = self.request.user.username add_storage_form.fields['responsible'].initial = self.request.user.username
context['add_storage_form'] = add_storage_form context['add_storage_form'] = add_storage_form

View File

@ -40,7 +40,9 @@ INSTALLED_APPS = [
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'parts.apps.PartsConfig', 'parts.apps.PartsConfig',
'qr_code', 'qr_code',
'rest_framework' 'rest_framework',
'crispy_forms',
'crispy_bootstrap5',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -170,4 +172,8 @@ LOGIN_URL = '/login'
LOGIN_REDIRECT_URL = '/' LOGIN_REDIRECT_URL = '/'
SHIMATTA_KENKYUSHO_TITLE = 'しまった・研究所' SHIMATTA_KENKYUSHO_TITLE = 'しまった・研究所'
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"

View File

@ -14,31 +14,68 @@
</nav> </nav>
<div class="row"> <div class="row">
<div class="col-md"> <div class="col-md-3">
{% qr_from_text object.get_qr_code size="m" image_format="svg" %} <div class="row-md">
{% qr_from_text object.get_qr_code size="m" image_format="svg" %}
</div>
<div class="row-md">
{% if object.parent_storage %}
<h1>Sub-Storages <a class="btn btn-secondary" href="{% url 'parts-stocks-detail' uuid=object.parent_storage.id %}">Parent Storage</a> {% else %}
<h1>Sub-Storages <a class="btn btn-secondary" href="{% url 'parts-stocks'%}">Stock Overview</a>
{% endif %}
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#delete-storage-modal">Delete</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#add-sub-modal"><i class="bi bi-plus-circle"></i></button>
</h1>
<div class="list-group">
{% for storage in storages %}
<a href="{% url 'parts-stocks-detail' uuid=storage.id %}" class="text-decoration-none">
<li class="list-group-item list-group-item-action justify-content-between align-items-center d-flex">
<div>
<h5>{{storage.name}}</h5>
Responsible: {{ storage.responsible }}
</div>
<span class="badge bg-primary rounded-pill">{{storage.get_total_stock_amount}}</span>
</li>
</a>
{% endfor %}
</div>
{% include 'paginator.html' with paginator=storages get_param='storage_page' aria_label='Storage Page Navigation' %}
</div>
</div> </div>
<div class="col-md"> <div class="col-md">
{% if object.parent_storage %} <h1>Stocked Components</h1>
<h1>Sub-Storages <a class="btn btn-secondary" href="{% url 'parts-stocks-detail' uuid=object.parent_storage.id %}">Parent Storage</a> {% else %} <form method="get">
<h1>Sub-Storages <a class="btn btn-secondary" href="{% url 'parts-stocks'%}">Stock Overview</a> <div class="input-group">
{% endif %} <input class="form-control" name="search" type="search" placeholder="Search..." {% if stock_search %}value="{{stock_search}}"{% endif %}>
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#delete-storage-modal">Delete</button> <button type="submit" class="btn btn-primary">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#add-sub-modal"><i class="bi bi-plus-circle"></i></button> <i class="bi bi-search"></i>
</h1> </button>
</div>
</form>
<div class="list-group"> <div class="list-group">
{% for storage in storages %} {% for stock in stocks %}
<a href="{% url 'parts-stocks-detail' uuid=storage.id %}" class="text-decoration-none"> <li class="list-group-item list-group-item-action d-flex align-items-center">
<li class="list-group-item list-group-item-action justify-content-between align-items-center d-flex"> <div class="flex-shrink-0">
<div> {% if stock.component.get_resolved_image %}
<h5>{{storage.name}}</h5> <img src="{{stock.component.get_resolved_image}}" style="max-width:64px;max-height:64px;" alt="{{ low.component.name }}" class="mr-3">
Responsible: {{ storage.responsible }} {% else %}
{% load static %}
<img src="{% static 'css/icons/card-image.svg' %}" style="width:64px;max-height:64px;" alt="{{ low.component.name }}" class="mr-3">
{% endif %}
</div>
<div class="flex-grow-1 ms-3">
<h6 class="mt-0 text-primary">{{ stock.component.name }}</h6>
{% if stock.component.package %}
Package: {{stock.component.package}}<br>
{% endif %}
{% if stock.component.manufacturer %}
Manufacturer: {{stock.component.manufacturer}}
{% endif %}
</div> </div>
<span class="badge bg-primary rounded-pill">{{storage.get_total_stock_amount}}</span>
</li> </li>
</a> {% endfor %}
{% endfor %}
</div> </div>
{% include 'paginator.html' with paginator=storages get_param='storage_page' aria_label='Storage Page Navigation' %} {% include 'paginator.html' with paginator=stocks get_param='stock_page' aria_label='Stock Page Navigation' %}
</div> </div>
</div> </div>
<!-- Modal for adding a substorage--> <!-- Modal for adding a substorage-->

View File

@ -8,7 +8,7 @@
<h1>Low Stocks</h1> <h1>Low Stocks</h1>
<div class="list-group"> <div class="list-group">
{% for low in low_stocks %} {% for low in low_stocks %}
<a href="{% url 'parts-stocks-detail' uuid=low.storage.id %}" class="text-decoration-none"> <a href="{% url 'parts-stocks-detail' uuid=low.storage.id %}?search={{low.component.id|urlencode}}" class="text-decoration-none">
<li class="list-group-item list-group-item-action d-flex justify-content-between align-items-center"> <li class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
<div class="flex-shrink-0"> <div class="flex-shrink-0">
{% if low.component.get_resolved_image %} {% if low.component.get_resolved_image %}
@ -19,7 +19,7 @@
{% endif %} {% endif %}
</div> </div>
<div class="flex-grow-1 ms-3"> <div class="flex-grow-1 ms-3">
<h5 class="mt-0">{{ low.component.name }} in {{ low.component.package }}</h5> <h5 class="mt-0">{{ low.component.name }}{% if low.component.package %} in {{ low.component.package }}{% endif %}</h5>
{{ low.storage }} {{ low.storage }}
</div> </div>