diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index e76e01ce06..2002165909 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -158,9 +158,11 @@ class Part(models.Model): This subtracts stock which is already allocated """ - # TODO - For now, just return total stock count - # TODO - In future must take account of allocated stock - return self.total_stock + total = self.total_stock + + total -= self.allocation_count + + return max(total, 0) @property def can_build(self): @@ -181,7 +183,7 @@ class Part(models.Model): if total is None or n < total: total = n - return total + return max(total, 0) @property def active_builds(self): @@ -205,6 +207,44 @@ class Part(models.Model): return sum([b.quantity for b in self.active_builds]) + @property + def allocated_builds(self): + """ Return list of builds to which this part is allocated + """ + + builds = [] + + for item in self.used_in.all(): + for build in item.part.active_builds: + builds.append(build) + + return builds + + @property + def allocated_build_count(self): + """ Return the total number of this that are allocated for builds + """ + + total = 0 + + for item in self.used_in.all(): + for build in item.part.active_builds: + n = build.quantity * item.quantity + total += n + + return total + + @property + def allocation_count(self): + """ Return true if any of this part is allocated + - To another build + - To a customer order + """ + + return sum([ + self.allocated_build_count, + ]) + @property def total_stock(self): """ Return the total stock quantity for this part. diff --git a/InvenTree/part/templates/part/allocation.html b/InvenTree/part/templates/part/allocation.html new file mode 100644 index 0000000000..35b8426815 --- /dev/null +++ b/InvenTree/part/templates/part/allocation.html @@ -0,0 +1,29 @@ +{% extends "part/part_base.html" %} + +{% block details %} + +{% include "part/tabs.html" with tab="allocation" %} + +

Part Allocation

+ +{% if part.allocated_build_count > 0 %} +

Allocated to Part Builds

+ + + + + + + +{% for build in part.allocated_builds %} + + + + + + +{% endfor %} +
BuildMakingAlloctedStatus
{{ build.title }}{{ build.part.name }}Quantity{% include "part/build_status.html" with build=build %}
+{% endif %} + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/build_list.html b/InvenTree/part/templates/part/build_list.html index a42518964a..8798323204 100644 --- a/InvenTree/part/templates/part/build_list.html +++ b/InvenTree/part/templates/part/build_list.html @@ -3,18 +3,8 @@ {{ build.title }} {{ build.quantity }} - {% if build.status == build.PENDING %} - - {% elif build.status == build.HOLDING %} - - {% elif build.status == build.CANCELLED %} - - {% elif build.status == build.COMPLETE %} - - {% endif %} - {{ build.get_status_display }} - + {% include "part/build_status.html" with build=build %} - {{ build.completion_date }} + {% if build.completion_date %}{{ build.completion_date }}{% endif %} {% endfor %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/build_status.html b/InvenTree/part/templates/part/build_status.html new file mode 100644 index 0000000000..1702ceccae --- /dev/null +++ b/InvenTree/part/templates/part/build_status.html @@ -0,0 +1,11 @@ +{% if build.status == build.PENDING %} + +{% elif build.status == build.HOLDING %} + +{% elif build.status == build.CANCELLED %} + +{% elif build.status == build.COMPLETE %} + +{% endif %} +{{ build.get_status_display }} + \ No newline at end of file diff --git a/InvenTree/part/templates/part/part_base.html b/InvenTree/part/templates/part/part_base.html index 69840829e3..a9f66a76b9 100644 --- a/InvenTree/part/templates/part/part_base.html +++ b/InvenTree/part/templates/part/part_base.html @@ -22,11 +22,6 @@ {% if part.description %}

{{ part.description }}

{% endif %} - - - -
- {% if part.IPN %} @@ -39,15 +34,22 @@ {% endif %} + + + + +
+

Stock Status - {{ part.available_stock }} available

+
IPN{{ part.URL }}
- + @@ -62,6 +64,23 @@ {% endif %} + {% if part.quantity_being_built > 0 %} + + + + + {% endif %} + {% endif %} + {% if part.allocation_count > 0 %} + + + {% if part.allocation_count > part.total_stock %} + + {% endif %}
Available StockIn Stock - {% if part.available_stock == 0 %} - {{ part.available_stock }} - {% elif part.available_stock < part.minimum_stock %} - {{ part.available_stock }} + {% if part.stock == 0 %} + {{ part.total_stock }} + {% elif part.stock < part.minimum_stock %} + {{ part.total_stock }} {% else %} - {{ part.available_stock }} + {{ part.total_stock }} {% endif %}
Underway{{ part.quantity_being_built }}
Allocated{{ part.allocation_count }} + {% else %} + {{ part.allocation_count }} {{ part.total_stock }} + {% endif %} +
diff --git a/InvenTree/part/templates/part/tabs.html b/InvenTree/part/templates/part/tabs.html index ce1cb7645b..da0b1c9ec2 100644 --- a/InvenTree/part/templates/part/tabs.html +++ b/InvenTree/part/templates/part/tabs.html @@ -7,7 +7,10 @@ {% if part.used_in_count > 0 %} Used In{% if part.used_in_count > 0 %}{{ part.used_in_count }}{% endif %} {% endif %} - Stock {{ part.available_stock }} + Stock {{ part.total_stock }} + {% if part.allocation_count > 0 %} + Allocated {{ part.allocation_count }} + {% endif %} {% if part.purchaseable %} Suppliers {{ part.supplier_count }} diff --git a/InvenTree/part/templates/part/used_in.html b/InvenTree/part/templates/part/used_in.html index 86a57f0b69..4a691aac23 100644 --- a/InvenTree/part/templates/part/used_in.html +++ b/InvenTree/part/templates/part/used_in.html @@ -9,11 +9,13 @@ + {% for item in part.used_in.all %} + {% endfor %} diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index ab95b2f43f..97888dc20b 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -44,6 +44,7 @@ part_detail_urls = [ url(r'^build/?', views.PartDetail.as_view(template_name='part/build.html'), name='part-build'), url(r'^stock/?', views.PartDetail.as_view(template_name='part/stock.html'), name='part-stock'), url(r'^used/?', views.PartDetail.as_view(template_name='part/used_in.html'), name='part-used-in'), + url(r'^allocation/?', views.PartDetail.as_view(template_name='part/allocation.html'), name='part-allocation'), url(r'^suppliers/?', views.PartDetail.as_view(template_name='part/supplier.html'), name='part-suppliers'), # Any other URLs go to the part detail page
PartUses Description
{{ item.part.name }}{{ item.quantity }} {{ item.part.description }}