From f253bf18434eb06a48bab00719c9c4899b991253 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 28 Sep 2020 20:07:25 +1000 Subject: [PATCH] Add ability for stock API to be filtered by installed status --- .../build/templates/build/build_output.html | 2 +- InvenTree/stock/api.py | 20 ++++++++++++ .../stock/templates/stock/item_installed.html | 31 +++++++++++++++++++ InvenTree/stock/templates/stock/tabs.html | 6 ++-- InvenTree/stock/urls.py | 1 + InvenTree/templates/js/stock.html | 18 ++++++----- InvenTree/templates/js/table_filters.html | 5 +++ 7 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 InvenTree/stock/templates/stock/item_installed.html diff --git a/InvenTree/build/templates/build/build_output.html b/InvenTree/build/templates/build/build_output.html index e5a3e77e61..75257f2d5d 100644 --- a/InvenTree/build/templates/build/build_output.html +++ b/InvenTree/build/templates/build/build_output.html @@ -19,7 +19,7 @@ loadStockTable($("#stock-table"), { params: { location_detail: true, - part_details: true, + part_detail: true, build: {{ build.id }}, }, groupByField: 'location', diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 900a94ed52..55bc62a44e 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -476,6 +476,26 @@ class StockList(generics.ListCreateAPIView): if sales_order: queryset = queryset.filter(sales_order=sales_order) + # Filter stock items which are installed in another (specific) stock item + installed_in = params.get('installed_in', None) + + if installed_in: + # Note: The "installed_in" field is called "belongs_to" + queryset = queryset.filter(belongs_to=installed_in) + + # Filter stock items which are installed in another stock item + installed = params.get('installed', None) + + if installed is not None: + installed = str2bool(installed) + + if installed: + # Exclude items which are *not* installed in another item + queryset = queryset.exclude(belongs_to=None) + else: + # Exclude items which are instaled in another item + queryset = queryset.filter(belongs_to=None) + # Filter by customer customer = params.get('customer', None) diff --git a/InvenTree/stock/templates/stock/item_installed.html b/InvenTree/stock/templates/stock/item_installed.html new file mode 100644 index 0000000000..abecaf6e3c --- /dev/null +++ b/InvenTree/stock/templates/stock/item_installed.html @@ -0,0 +1,31 @@ +{% extends "stock/item_base.html" %} + +{% load static %} +{% load i18n %} + +{% block details %} + +{% include "stock/tabs.html" with tab='installed' %} + +

{% trans "Installed Items" %}

+
+ + +
+ +{% endblock %} + +{% block js_ready %} + +{{ block.super }} + +loadStockTable($("#installed-table"), { + params: { + installed_in: {{ item.id }}, + part_detail: true, + }, + name: 'stock-item-installed', + url: "{% url 'api-stock-list' %}", +}) + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/stock/templates/stock/tabs.html b/InvenTree/stock/templates/stock/tabs.html index 72da8a5cf2..05841987da 100644 --- a/InvenTree/stock/templates/stock/tabs.html +++ b/InvenTree/stock/templates/stock/tabs.html @@ -38,11 +38,11 @@ {% trans "Children" %}{% if item.child_count > 0 %}{{ item.child_count }}{% endif %} {% endif %} - {% if item.installedItemCount > 0 %} + {% if item.part.assembly or item.installedItemCount > 0 %}
  • - + {% trans "Installed Parts" %} - {{ item.installedItemCount }} + {% if item.installedItemCount > 0 %}{{ item.installedItemCount }}{% endif %}
  • {% endif %} diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py index 51067b57de..c6b0b2b54c 100644 --- a/InvenTree/stock/urls.py +++ b/InvenTree/stock/urls.py @@ -34,6 +34,7 @@ stock_item_detail_urls = [ url(r'^test/', views.StockItemDetail.as_view(template_name='stock/item_tests.html'), name='stock-item-test-results'), url(r'^children/', views.StockItemDetail.as_view(template_name='stock/item_childs.html'), name='stock-item-children'), url(r'^attachments/', views.StockItemDetail.as_view(template_name='stock/item_attachments.html'), name='stock-item-attachments'), + url(r'^installed/', views.StockItemDetail.as_view(template_name='stock/item_installed.html'), name='stock-item-installed'), url(r'^notes/', views.StockItemNotes.as_view(), name='stock-item-notes'), url('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'), diff --git a/InvenTree/templates/js/stock.html b/InvenTree/templates/js/stock.html index bb0673c16d..9a9e629efe 100644 --- a/InvenTree/templates/js/stock.html +++ b/InvenTree/templates/js/stock.html @@ -512,16 +512,20 @@ function loadStockTable(table, options) { title: '{% trans "Location" %}', sortable: true, formatter: function(value, row, index, field) { - if (value) { + if (row.belongs_to) { + var text = "{% trans 'Installed in Stock Item ' %}" + row.belongs_to; + var url = `/stock/item/${row.belongs_to}/installed/`; + + return renderLink(text, url); + } else if (row.customer) { + var text = "{% trans "Shipped to customer" %}"; + return renderLink(text, `/company/${row.customer}/assigned-stock/`); + } + else if (value) { return renderLink(value, `/stock/location/${row.location}/`); } else { - if (row.customer) { - var text = "{% trans "Shipped to customer" %}"; - return renderLink(text, `/company/${row.customer}/assigned-stock/`); - } else { - return '{% trans "No stock location set" %}'; - } + return '{% trans "No stock location set" %}'; } } }, diff --git a/InvenTree/templates/js/table_filters.html b/InvenTree/templates/js/table_filters.html index 316abcad7b..44c4149265 100644 --- a/InvenTree/templates/js/table_filters.html +++ b/InvenTree/templates/js/table_filters.html @@ -65,6 +65,11 @@ function getAvailableTableFilters(tableKey) { title: '{% trans "In Stock" %}', description: '{% trans "Show items which are in stock" %}', }, + installed: { + type: 'bool', + title: '{% trans "Installed" %}', + description: '{% trans "Show stock items which are installed in another item" %}', + }, sent_to_customer: { type: 'bool', title: '{% trans "Sent to customer" %}',