diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py
index 22514ee7b7..592ff5dc16 100644
--- a/InvenTree/build/api.py
+++ b/InvenTree/build/api.py
@@ -59,7 +59,10 @@ class BuildList(generics.ListCreateAPIView):
status = self.request.query_params.get('status', None)
if status is not None:
- queryset = queryset.filter(status=status)
+ # Get status codes
+ codes = status.split('-')
+ # Filter by codes
+ queryset = queryset.filter(status__in=codes)
# Filter by associated part?
part = self.request.query_params.get('part', None)
diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py
index abc4181895..cf260d7bfa 100644
--- a/InvenTree/part/api.py
+++ b/InvenTree/part/api.py
@@ -405,6 +405,27 @@ class PartList(generics.ListCreateAPIView):
except (ValueError, Part.DoesNotExist):
pass
+ # Filter by latest part creation date
+ latest_parts = params.get('latest_parts', None)
+
+ if latest_parts is not None:
+ # Get the last 5 created parts
+ queryset = queryset.order_by('-creation_date')[:5]
+
+ # Filter invalid BOMs
+ bom_invalid = params.get('bom_invalid', None)
+
+ if bom_invalid is not None:
+ # Get assemblies with invalid BOMs
+ assemblies = queryset.filter(active=True).filter(assembly=True)
+ valid_boms = []
+
+ for part in assemblies:
+ if part.is_bom_valid:
+ valid_boms.append(part.pk)
+
+ queryset = assemblies.exclude(pk__in=valid_boms)
+
# Filter by 'starred' parts?
starred = params.get('starred', None)
@@ -477,6 +498,22 @@ class PartList(generics.ListCreateAPIView):
# Filter items which have an 'in_stock' level higher than 'minimum_stock'
queryset = queryset.filter(Q(in_stock__gte=F('minimum_stock')))
+ # Filter by "parts which need stock to complete build"
+ stock_to_build = params.get('stock_to_build', None)
+
+ if stock_to_build is not None:
+ # Filter only active parts
+ queryset = queryset.filter(active=True)
+ parts_need_stock = []
+
+ # Find parts with active builds
+ # where any subpart's stock is lower than quantity being built
+ for part in queryset:
+ if part.active_builds and part.can_build < part.quantity_being_built:
+ parts_need_stock.append(part.pk)
+
+ queryset = queryset.filter(pk__in=parts_need_stock)
+
return queryset
permission_classes = [
diff --git a/InvenTree/templates/InvenTree/bom_invalid.html b/InvenTree/templates/InvenTree/bom_invalid.html
new file mode 100644
index 0000000000..84f4fd7938
--- /dev/null
+++ b/InvenTree/templates/InvenTree/bom_invalid.html
@@ -0,0 +1,15 @@
+{% extends "collapse_index.html" %}
+
+{% load i18n %}
+
+{% block collapse_title %}
+
+{% trans "BOM Waiting Validation" %}0
+{% endblock %}
+
+{% block collapse_content %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/templates/InvenTree/build_pending.html b/InvenTree/templates/InvenTree/build_pending.html
new file mode 100644
index 0000000000..31a083cfc0
--- /dev/null
+++ b/InvenTree/templates/InvenTree/build_pending.html
@@ -0,0 +1,15 @@
+{% extends "collapse_index.html" %}
+
+{% load i18n %}
+
+{% block collapse_title %}
+
+{% trans "Pending Builds" %}0
+{% endblock %}
+
+{% block collapse_content %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/templates/InvenTree/index.html b/InvenTree/templates/InvenTree/index.html
index 570378e55d..fa9818069e 100644
--- a/InvenTree/templates/InvenTree/index.html
+++ b/InvenTree/templates/InvenTree/index.html
@@ -7,9 +7,43 @@ InvenTree | Index
{% block content %}
InvenTree
-{% include "InvenTree/starred_parts.html" with collapse_id="starred" %}
-{% include "InvenTree/low_stock.html" with collapse_id="order" %}
+
+
+ {% include "InvenTree/latest_parts.html" with collapse_id="latest_parts" %}
+
+
+ {% include "InvenTree/starred_parts.html" with collapse_id="starred" %}
+
+
+
+
+
+
+ {% include "InvenTree/bom_invalid.html" with collapse_id="bom_invalid" %}
+
+
+ {% include "InvenTree/build_pending.html" with collapse_id="build_pending" %}
+
+
+
+
+
+ {% include "InvenTree/low_stock.html" with collapse_id="order" %}
+
+
+ {% include "InvenTree/required_stock_build.html" with collapse_id="stock_to_build" %}
+
+
+
+
+
+ {% include "InvenTree/po_outstanding.html" with collapse_id="po_outstanding" %}
+
+
+ {% include "InvenTree/so_outstanding.html" with collapse_id="so_outstanding" %}
+
+
{% endblock %}
@@ -21,29 +55,106 @@ InvenTree | Index
{{ block.super }}
+loadPartTable("#latest-parts-table", "{% url 'api-part-list' %}", {
+ params: {
+ "latest_parts": true,
+ }
+});
+
loadPartTable("#starred-parts-table", "{% url 'api-part-list' %}", {
params: {
"starred": true,
}
});
+loadPartTable("#bom-invalid-table", "{% url 'api-part-list' %}", {
+ params: {
+ "bom_invalid": true,
+ }
+});
+
+loadBuildTable("#build-pending-table", {
+ url: "{% url 'api-build-list' %}",
+ params: {
+ "part_detail": true,
+ "status": "10-20",
+ }
+});
+
loadPartTable("#low-stock-table", "{% url 'api-part-list' %}", {
params: {
"low_stock": true,
}
});
+loadPartTable("#stock-to-build-table", "{% url 'api-part-list' %}", {
+ params: {
+ "stock_to_build": true,
+ }
+});
+
+loadPurchaseOrderTable("#po-outstanding-table", {
+ url: "{% url 'api-po-list' %}",
+ params: {
+ "supplier_detail": true,
+ "oustanding": true,
+ }
+});
+
+loadSalesOrderTable("#so-outstanding-table", {
+ url: "{% url 'api-so-list' %}",
+ params: {
+ "customer_detail": true,
+ "oustanding": true,
+ }
+});
+
+$("#latest-parts-table").on('load-success.bs.table', function() {
+ var count = $("#latest-parts-table").bootstrapTable('getData').length;
+
+ $("#latest-parts-count").html(count);
+});
+
$("#starred-parts-table").on('load-success.bs.table', function() {
var count = $("#starred-parts-table").bootstrapTable('getData').length;
$("#starred-parts-count").html(count);
});
+$("#bom-invalid-table").on('load-success.bs.table', function() {
+ var count = $("#bom-invalid-table").bootstrapTable('getData').length;
+
+ $("#bom-invalid-count").html(count);
+});
+
+$("#build-pending-table").on('load-success.bs.table', function() {
+ var count = $("#build-pending-table").bootstrapTable('getData').length;
+
+ $("#build-pending-count").html(count);
+});
+
$("#low-stock-table").on('load-success.bs.table', function() {
var count = $("#low-stock-table").bootstrapTable('getData').length;
$("#low-stock-count").html(count);
});
+$("#stock-to-build-table").on('load-success.bs.table', function() {
+ var count = $("#stock-to-build-table").bootstrapTable('getData').length;
+
+ $("#stock-to-build-count").html(count);
+});
+
+$("#po-outstanding-table").on('load-success.bs.table', function() {
+ var count = $("#po-outstanding-table").bootstrapTable('getData').length;
+
+ $("#po-outstanding-count").html(count);
+});
+
+$("#so-outstanding-table").on('load-success.bs.table', function() {
+ var count = $("#so-outstanding-table").bootstrapTable('getData').length;
+
+ $("#so-outstanding-count").html(count);
+});
{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/templates/InvenTree/latest_parts.html b/InvenTree/templates/InvenTree/latest_parts.html
new file mode 100644
index 0000000000..e9c9879740
--- /dev/null
+++ b/InvenTree/templates/InvenTree/latest_parts.html
@@ -0,0 +1,15 @@
+{% extends "collapse_index.html" %}
+
+{% load i18n %}
+
+{% block collapse_title %}
+
+{% trans "Latest Parts" %}0
+{% endblock %}
+
+{% block collapse_content %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/templates/InvenTree/low_stock.html b/InvenTree/templates/InvenTree/low_stock.html
index edafab1756..333dbded27 100644
--- a/InvenTree/templates/InvenTree/low_stock.html
+++ b/InvenTree/templates/InvenTree/low_stock.html
@@ -1,4 +1,4 @@
-{% extends "collapse.html" %}
+{% extends "collapse_index.html" %}
{% load i18n %}
diff --git a/InvenTree/templates/InvenTree/po_outstanding.html b/InvenTree/templates/InvenTree/po_outstanding.html
new file mode 100644
index 0000000000..063915a414
--- /dev/null
+++ b/InvenTree/templates/InvenTree/po_outstanding.html
@@ -0,0 +1,15 @@
+{% extends "collapse_index.html" %}
+
+{% load i18n %}
+
+{% block collapse_title %}
+
+{% trans "Outstanding Purchase Orders" %}0
+{% endblock %}
+
+{% block collapse_content %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/templates/InvenTree/required_stock_build.html b/InvenTree/templates/InvenTree/required_stock_build.html
new file mode 100644
index 0000000000..8202766ec1
--- /dev/null
+++ b/InvenTree/templates/InvenTree/required_stock_build.html
@@ -0,0 +1,15 @@
+{% extends "collapse_index.html" %}
+
+{% load i18n %}
+
+{% block collapse_title %}
+
+{% trans "Require Stock To Complete Build" %}0
+{% endblock %}
+
+{% block collapse_content %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/templates/InvenTree/so_outstanding.html b/InvenTree/templates/InvenTree/so_outstanding.html
new file mode 100644
index 0000000000..023abb2b6a
--- /dev/null
+++ b/InvenTree/templates/InvenTree/so_outstanding.html
@@ -0,0 +1,15 @@
+{% extends "collapse_index.html" %}
+
+{% load i18n %}
+
+{% block collapse_title %}
+
+{% trans "Outstanding Sales Orders" %}0
+{% endblock %}
+
+{% block collapse_content %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/templates/InvenTree/starred_parts.html b/InvenTree/templates/InvenTree/starred_parts.html
index f13987e3c5..74f6edafb1 100644
--- a/InvenTree/templates/InvenTree/starred_parts.html
+++ b/InvenTree/templates/InvenTree/starred_parts.html
@@ -1,4 +1,4 @@
-{% extends "collapse.html" %}
+{% extends "collapse_index.html" %}
{% load i18n %}
@@ -9,7 +9,7 @@
{% block collapse_content %}
-
+
{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/templates/collapse_index.html b/InvenTree/templates/collapse_index.html
new file mode 100644
index 0000000000..d87f63b244
--- /dev/null
+++ b/InvenTree/templates/collapse_index.html
@@ -0,0 +1,19 @@
+{% block collapse_preamble %}
+{% endblock %}
+
+
+
+
+ {% block collapse_heading %}
+ {% endblock %}
+
+
+
+ {% block collapse_content %}
+ {% endblock %}
+
+
+
+
\ No newline at end of file
diff --git a/InvenTree/templates/js/build.html b/InvenTree/templates/js/build.html
index 8682e9bd81..10c017a776 100644
--- a/InvenTree/templates/js/build.html
+++ b/InvenTree/templates/js/build.html
@@ -13,7 +13,7 @@ function loadBuildTable(table, options) {
setupFilterList("build", table);
- table.inventreeTable({
+ $(table).inventreeTable({
method: 'get',
formatNoMatches: function() {
return "{% trans "No builds matching query" %}";