From 6986709fb899f43724647f9ea891ce6b578c2444 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 20 Apr 2021 19:49:07 +1000 Subject: [PATCH] Reorganized stock location view --- InvenTree/stock/api.py | 5 ++ InvenTree/stock/serializers.py | 1 + InvenTree/stock/templates/stock/location.html | 42 +++++------ .../stock/templates/stock/location_list.html | 24 ------- .../templates/stock/location_navbar.html | 33 +++++++++ .../stock/templates/stock/sublocation.html | 36 ++++++++++ InvenTree/stock/urls.py | 27 ++++--- InvenTree/templates/js/stock.js | 71 +++++++++++++++++++ 8 files changed, 184 insertions(+), 55 deletions(-) delete mode 100644 InvenTree/stock/templates/stock/location_list.html create mode 100644 InvenTree/stock/templates/stock/location_navbar.html create mode 100644 InvenTree/stock/templates/stock/sublocation.html diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 6da3962224..2667352515 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -320,6 +320,11 @@ class StockLocationList(generics.ListCreateAPIView): 'description', ] + ordering_fields = [ + 'name', + 'items', + ] + class StockList(generics.ListCreateAPIView): """ API endpoint for list view of Stock objects diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index 5b00c1dd17..2439bb9330 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -244,6 +244,7 @@ class LocationSerializer(InvenTreeModelSerializer): items = serializers.IntegerField(source='item_count', read_only=True) + class Meta: model = StockLocation fields = [ diff --git a/InvenTree/stock/templates/stock/location.html b/InvenTree/stock/templates/stock/location.html index 74e43f88bb..396a433566 100644 --- a/InvenTree/stock/templates/stock/location.html +++ b/InvenTree/stock/templates/stock/location.html @@ -2,8 +2,15 @@ {% load static %} {% load inventree_extras %} {% load i18n %} + +{% block menubar %} +{% include "stock/location_navbar.html" with tab="stock" %} +{% endblock %} + {% block content %} +
+ {% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %} {% if owner_control.value == "True" %} {% authorized_owners location.owner as owners %} @@ -120,36 +127,29 @@
+ -{% if location and location.children.all|length > 0 %} -{% include 'stock/location_list.html' with children=location.children.all collapse_id="locations" %} -{% elif locations|length > 0 %} -{% include 'stock/location_list.html' with children=locations collapse_id="locations" %} -{% endif %} +{% block location_content %} -
- -{% include "stock_table.html" %} +
+
+

{% trans "Stock Items" %}

+
+ {% include "stock_table.html" %}
{% endblock %} -{% block js_load %} -{{ block.super }} + + {% endblock %} + {% block js_ready %} {{ block.super }} - if (inventreeLoadInt("show-part-locs") == 1) { - $("#collapse-item-locations").collapse('show'); - } - - $("#collapse-item-locations").on('shown.bs.collapse', function() { - inventreeSave('show-part-locs', 1); - }); - - $("#collapse-item-locations").on('hidden.bs.collapse', function() { - inventreeDel('show-part-locs'); + enableNavbar({ + label: 'location', + toggleId: '#location-menu-toggle' }); {% if location %} @@ -261,7 +261,7 @@ ], params: { {% if location %} - location: {{ location.id }}, + location: {{ location.pk }}, {% endif %} part_detail: true, location_detail: true, diff --git a/InvenTree/stock/templates/stock/location_list.html b/InvenTree/stock/templates/stock/location_list.html deleted file mode 100644 index f9464c5fa3..0000000000 --- a/InvenTree/stock/templates/stock/location_list.html +++ /dev/null @@ -1,24 +0,0 @@ -{% extends "collapse.html" %} -{% load i18n %} - -{% if roles.stock_location.view or roles.stock.view %} -{% block collapse_title %} -{% trans 'Sub-Locations' %}{{ children|length }} -{% endblock %} - -{% block collapse_content %} - -{% endblock %} -{% endif %} \ No newline at end of file diff --git a/InvenTree/stock/templates/stock/location_navbar.html b/InvenTree/stock/templates/stock/location_navbar.html new file mode 100644 index 0000000000..0cb0c9d1eb --- /dev/null +++ b/InvenTree/stock/templates/stock/location_navbar.html @@ -0,0 +1,33 @@ +{% load i18n %} + + \ No newline at end of file diff --git a/InvenTree/stock/templates/stock/sublocation.html b/InvenTree/stock/templates/stock/sublocation.html new file mode 100644 index 0000000000..b8b32328a2 --- /dev/null +++ b/InvenTree/stock/templates/stock/sublocation.html @@ -0,0 +1,36 @@ +{% extends "stock/location.html" %} + +{% load static %} +{% load i18n %} +{% load inventree_extras %} + +{% block menubar %} +{% include "stock/location_navbar.html" with tab="sublocations" %} +{% endblock %} + + +{% block location_content %} + +
+
+

{% trans "Sublocations" %}

+
+
+
+ +{% endblock %} + +{% block js_ready %} +{{ block.super }} + +loadStockLocationTable($('#sublocation-table'), { + params: { + {% if location %} + parent: {{ location.pk }}, + {% else %} + parent: 'null', + {% endif %} + } +}); + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py index 5c6c678978..24e609fa4f 100644 --- a/InvenTree/stock/urls.py +++ b/InvenTree/stock/urls.py @@ -6,14 +6,21 @@ from django.conf.urls import url, include from . import views -# URL list for web interface -stock_location_detail_urls = [ - url(r'^edit/?', views.StockLocationEdit.as_view(), name='stock-location-edit'), - url(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'), - url(r'^qr_code/?', views.StockLocationQRCode.as_view(), name='stock-location-qr'), +location_urls = [ + + url(r'^new/', views.StockLocationCreate.as_view(), name='stock-location-create'), + + url(r'^(?P\d+)/', include([ + url(r'^edit/?', views.StockLocationEdit.as_view(), name='stock-location-edit'), + url(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'), + url(r'^qr_code/?', views.StockLocationQRCode.as_view(), name='stock-location-qr'), + + url(r'sublocation/', views.StockLocationDetail.as_view(template_name='stock/sublocation.html'), name='stock-location-sublocation'), + + # Anything else + url('^.*$', views.StockLocationDetail.as_view(), name='stock-location-detail'), + ])), - # Anything else - url('^.*$', views.StockLocationDetail.as_view(), name='stock-location-detail'), ] stock_item_detail_urls = [ @@ -49,9 +56,7 @@ stock_tracking_urls = [ stock_urls = [ # Stock location - url(r'^location/(?P\d+)/', include(stock_location_detail_urls)), - - url(r'^location/new/', views.StockLocationCreate.as_view(), name='stock-location-create'), + url(r'^location/', include(location_urls)), url(r'^item/new/?', views.StockItemCreate.as_view(), name='stock-item-create'), @@ -81,5 +86,7 @@ stock_urls = [ # Individual stock items url(r'^item/(?P\d+)/', include(stock_item_detail_urls)), + url(r'^sublocations/', views.StockIndex.as_view(template_name='stock/sublocation.html'), name='stock-sublocations'), + url(r'^.*$', views.StockIndex.as_view(), name='stock-index'), ] diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js index 33f2dae8d6..990acf65ba 100644 --- a/InvenTree/templates/js/stock.js +++ b/InvenTree/templates/js/stock.js @@ -897,6 +897,77 @@ function loadStockTable(table, options) { }); } +function loadStockLocationTable(table, options) { + /* Display a table of stock locations */ + + var params = options.params || {}; + + var filterListElement = options.filterList || '#filter-list-location'; + + var filters = {}; + + var filterKey = options.filterKey || options.name || 'location'; + + if (!options.disableFilters) { + filters = loadTableFilters(filterKey); + } + + var original = {}; + + for (var key in params) { + original[key] = params[key]; + } + + setupFilterList(filterKey, table, filterListElement); + + for (var key in params) { + filters[key] = params[key]; + } + + table.inventreeTable({ + method: 'get', + url: options.url || '{% url "api-location-list" %}', + queryParams: filters, + sidePagination: 'server', + name: 'location', + original: original, + showColumns: true, + columns: [ + { + checkbox: true, + title: '{% trans "Select" %}', + searchable: false, + switchable: false, + }, + { + field: 'name', + title: '{% trans "Name" %}', + switchable: true, + sortable: true, + formatter: function(value, row) { + return renderLink( + value, + `/stock/location/${row.pk}/` + ); + }, + }, + { + field: 'description', + title: '{% trans "Description" %}', + switchable: true, + sortable: false, + }, + { + field: 'items', + title: '{% trans "Stock Items" %}', + switchable: true, + sortable: false, + sortName: 'item_count', + } + ] + }); +} + function loadStockTrackingTable(table, options) { var cols = [