mirror of
https://github.com/Sosokker/Inventory-Management-System.git
synced 2025-12-18 23:24:05 +01:00
Add Warehouse Detail View and filter
This commit is contained in:
parent
9ebf8268fc
commit
6ed740b0a9
@ -5,6 +5,6 @@ from django.views.generic.base import RedirectView
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path("accounts/", include("django.contrib.auth.urls")), # new
|
||||
path('dashboard/', include('inventory.urls'), name='dashboard'),
|
||||
path('', RedirectView.as_view(url='/dashboard/overview/')),
|
||||
path('', include('inventory.urls'), name='dashboard'),
|
||||
path('', RedirectView.as_view(url='/overview/')),
|
||||
]
|
||||
|
||||
@ -1,7 +1,28 @@
|
||||
import django_filters
|
||||
from inventory.models import Warehouse
|
||||
from inventory.models import Warehouse, Inventory
|
||||
|
||||
class WarehouseFilter(django_filters.FilterSet):
|
||||
class Meta:
|
||||
model = Warehouse
|
||||
fields = ['name', 'address', 'have_freeze']
|
||||
fields = ['name', 'address', 'have_freeze']
|
||||
|
||||
|
||||
class InventoryFilter(django_filters.FilterSet):
|
||||
current_stock__gte = django_filters.NumberFilter(field_name='current_stock', lookup_expr='gte', label='Min Current Stock')
|
||||
current_stock__lte = django_filters.NumberFilter(field_name='current_stock', lookup_expr='lte', label='Max Current Stock')
|
||||
max_stock__gte = django_filters.NumberFilter(field_name='max_stock', lookup_expr='gte', label='Min Max Stock')
|
||||
max_stock__lte = django_filters.NumberFilter(field_name='max_stock', lookup_expr='lte', label='Max Max Stock')
|
||||
ordering = django_filters.OrderingFilter(
|
||||
fields=(
|
||||
('current_stock', 'current_stock'),
|
||||
('max_stock', 'max_stock'),
|
||||
),
|
||||
field_labels={
|
||||
'current_stock': 'Current Stock',
|
||||
'max_stock': 'Max Stock',
|
||||
}
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Inventory
|
||||
fields = []
|
||||
@ -1,7 +1,9 @@
|
||||
from django.urls import path, include
|
||||
from inventory.views import OverviewView, WarehouseView
|
||||
from inventory.views import OverviewView, WarehouseView, InventoryView, WarehouseDetailView
|
||||
|
||||
urlpatterns = [
|
||||
path('overview/', OverviewView.as_view(), name='overview'),
|
||||
path('warehouse/', WarehouseView.as_view(), name='warehouse'),
|
||||
path('warehouse/<int:id>/', WarehouseDetailView.as_view(), name='warehouse-detail'),
|
||||
path('warehouse/<int:wid>/<int:iid>/', InventoryView.as_view(), name='inventory'),
|
||||
]
|
||||
|
||||
@ -2,11 +2,11 @@ from typing import Any
|
||||
from django.shortcuts import render
|
||||
from django.views.generic import TemplateView
|
||||
from django_filters.views import FilterView
|
||||
from inventory.filters import WarehouseFilter
|
||||
from inventory.filters import WarehouseFilter, InventoryFilter
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from inventory.models import Warehouse
|
||||
from inventory.models import Warehouse, Inventory
|
||||
from inventory.utils import stock_percentage_all, count_pending_supply
|
||||
from transaction.models import Customer
|
||||
|
||||
@ -33,6 +33,28 @@ class WarehouseView(FilterView, LoginRequiredMixin):
|
||||
filterset_class = WarehouseFilter
|
||||
|
||||
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['warehouse_list'] = Warehouse.objects.all()
|
||||
return context
|
||||
|
||||
|
||||
class WarehouseDetailView(FilterView, LoginRequiredMixin):
|
||||
model = Inventory
|
||||
template_name = "inventory/warehouse_detail.html"
|
||||
filterset_class = InventoryFilter
|
||||
context_object_name = 'inventory_list'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['warehouse_id'] = self.kwargs.get('id')
|
||||
context['inventory_list'] = Inventory.objects.all()
|
||||
return context
|
||||
|
||||
|
||||
class InventoryView(TemplateView, LoginRequiredMixin):
|
||||
template_name = "inventory/inventory.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['warehouse_list'] = Warehouse.objects.all()
|
||||
return context
|
||||
@ -88,7 +88,7 @@
|
||||
{% if filter.is_bound %}
|
||||
{% for warehouse in filter.qs %}
|
||||
<tr>
|
||||
<td>{{ warehouse.name }}</td>
|
||||
<td><a href={% url "warehouse-detail" id=warehouse.id %}>{{ warehouse.name }}<a/></td>
|
||||
<td>{{ warehouse.address }}</td>
|
||||
<td>{{ warehouse.stock_percentage|floatformat:3 }}</td>
|
||||
<td>{{ warehouse.inventory_count }}</td>
|
||||
@ -98,7 +98,7 @@
|
||||
{% else %}
|
||||
{% for warehouse in warehouse_list %}
|
||||
<tr>
|
||||
<td>{{ warehouse.name }}</td>
|
||||
<td><a href={% url "warehouse-detail" id=warehouse.id %}>{{ warehouse.name }}<a/></td>
|
||||
<td>{{ warehouse.address }}</td>
|
||||
<td>{{ warehouse.stock_percentage|floatformat:3 }}</td>
|
||||
<td>{{ warehouse.inventory_count }}</td>
|
||||
|
||||
122
templates/inventory/warehouse_detail.html
Normal file
122
templates/inventory/warehouse_detail.html
Normal file
@ -0,0 +1,122 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<body id="page-top">
|
||||
|
||||
<!-- Page Wrapper -->
|
||||
<div id="wrapper">
|
||||
|
||||
{% include "nav.html" %}
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
||||
<!-- Main Content -->
|
||||
<div id="content">
|
||||
|
||||
|
||||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Page Heading -->
|
||||
<h1 class="h3 mb-2 text-gray-800">Warehouse Tables</h1>
|
||||
<p class="mb-4">Warehouse Table</p>
|
||||
<!-- Filter -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Accordion -->
|
||||
<a class="d-block card-header py-3">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Filter</h6>
|
||||
</a>
|
||||
<!-- Card Content - Collapse -->
|
||||
<form method="get">
|
||||
<div class="row g-3 align-items-center mx-2 my-4">
|
||||
{{ filter.form.as_p }}
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary">Filter</button>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<a href={{ request.path }} class="btn btn-danger">
|
||||
<i class="fas fa-trash"></i> Clear Filter
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- End Filter -->
|
||||
|
||||
<!-- DataTales Example -->
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header py-3">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Warehouse</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Inventory Name</th>
|
||||
<th>Current Stock</th>
|
||||
<th>Max Stock</th>
|
||||
<th>Stock Percentage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>Inventory Name</th>
|
||||
<th>Current Stock</th>
|
||||
<th>Max Stock</th>
|
||||
<th>Stock Percentage</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
{% if filter.is_bound %}
|
||||
{% for inventory in filter.qs %}
|
||||
<tr>
|
||||
<td><a href={% url "inventory" wid=warehouse_id iid=inventory.id %}>{{ inventory.stock_identifier }}<a/></td>
|
||||
<td>{{ inventory.current_stock }}</td>
|
||||
<td>{{ inventory.max_stock }}</td>
|
||||
<td>{{ inventory.stock_percentage|floatformat:3 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for inventory in inventory_list %}
|
||||
<tr>
|
||||
<td><a href={% url "inventory" wid=warehouse_id iid=inventory.id %}>{{ inventory.stock_identifier }}<a/></td>
|
||||
<td>{{ inventory.current_stock }}</td>
|
||||
<td>{{ inventory.max_stock }}</td>
|
||||
<td>{{ inventory.stock_percentage|floatformat:3 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
|
||||
</div>
|
||||
<!-- End of Main Content -->
|
||||
|
||||
|
||||
</div>
|
||||
<!-- End of Content Wrapper -->
|
||||
|
||||
</div>
|
||||
<!-- End of Page Wrapper -->
|
||||
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
{% include "footer.html" %}
|
||||
|
||||
</body>
|
||||
{% endblock content %}
|
||||
@ -35,14 +35,6 @@ Storage
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- Nav Item - Inventory -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">
|
||||
<i class="fas fa-fw fa-wrench"></i>
|
||||
<span>Inventory</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider">
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user