diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py
index 18267f33c4..9a388c5b2c 100644
--- a/InvenTree/InvenTree/views.py
+++ b/InvenTree/InvenTree/views.py
@@ -15,6 +15,8 @@ from django.views import View
from django.views.generic import UpdateView, CreateView, DeleteView
from django.views.generic.base import TemplateView
+from part.models import Part
+
from rest_framework import views
@@ -287,6 +289,21 @@ class IndexView(TemplateView):
template_name = 'InvenTree/index.html'
+ def get_context_data(self, **kwargs):
+
+ context = super(TemplateView, self).get_context_data(**kwargs)
+
+ # Generate a list of orderable parts which have stock below their minimum values
+ context['to_order'] = [part for part in Part.objects.filter(purchaseable=True) if part.need_to_restock()]
+
+ # Generate a list of buildable parts which have stock below their minimum values
+ context['to_build'] = [part for part in Part.objects.filter(buildable=True) if part.need_to_restock()]
+
+ print("order:", len(context['to_order']))
+ print("build:", len(context['to_build']))
+
+ return context
+
class SearchView(TemplateView):
""" View for InvenTree search page.
diff --git a/InvenTree/build/templates/build/allocate.html b/InvenTree/build/templates/build/allocate.html
index c3cda38429..0a3867af8e 100644
--- a/InvenTree/build/templates/build/allocate.html
+++ b/InvenTree/build/templates/build/allocate.html
@@ -11,12 +11,9 @@
{% for bom_item in bom_items.all %}
-{% include "build/allocation_item.html" with item=bom_item build=build %}
+{% include "build/allocation_item.html" with item=bom_item build=build collapse_id=bom_item.id %}
{% endfor %}
-
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index ab83b584cd..820df63955 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -193,14 +193,25 @@ class Part(models.Model):
def available_stock(self):
"""
Return the total available stock.
- This subtracts stock which is already allocated
+
+ - This subtracts stock which is already allocated to builds
"""
total = self.total_stock
total -= self.allocation_count
- return max(total, 0)
+ return total
+
+ def need_to_restock(self):
+ """ Return True if this part needs to be restocked
+ (either by purchasing or building).
+
+ If the allocated_stock exceeds the total_stock,
+ then we need to restock.
+ """
+
+ return (self.total_stock - self.allocation_count) < self.minimum_stock
@property
def can_build(self):
@@ -307,6 +318,12 @@ class Part(models.Model):
def used_in_count(self):
return self.used_in.count()
+ def required_parts(self):
+ parts = []
+ for bom in self.bom_items.all():
+ parts.append(bom.sub_part)
+ return parts
+
@property
def supplier_count(self):
# Return the number of supplier parts available for this part
diff --git a/InvenTree/part/templates/part/category.html b/InvenTree/part/templates/part/category.html
index 3d514389bc..f199cc5981 100644
--- a/InvenTree/part/templates/part/category.html
+++ b/InvenTree/part/templates/part/category.html
@@ -33,9 +33,9 @@
-{% if category %}
-{% include "part/subcategories.html" with children=category.children.all %}
-{% else %}
+{% if category and category.children.all|length > 0 %}
+{% include "part/subcategories.html" with children=category.children.all collapse_id="children"%}
+{% elif children|length > 0 %}
{% include "part/subcategories.html" with children=children %}
{% endif %}
diff --git a/InvenTree/part/templates/part/subcategories.html b/InvenTree/part/templates/part/subcategories.html
index 5dcfa426ad..abf61d743e 100644
--- a/InvenTree/part/templates/part/subcategories.html
+++ b/InvenTree/part/templates/part/subcategories.html
@@ -1,27 +1,19 @@
-{% if children|length > 0 %}
-
-
\ No newline at end of file
diff --git a/InvenTree/templates/required_part_table.html b/InvenTree/templates/required_part_table.html
new file mode 100644
index 0000000000..4ae1441f11
--- /dev/null
+++ b/InvenTree/templates/required_part_table.html
@@ -0,0 +1,18 @@
+