mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Display table of StockItems which have been split from the current item
- The StockItem list api now allows filtering by 'ancestor' - Add 'children' tab for StockItem - Needed to tweak the unit testing fixtures (yay thanks MPTT)
This commit is contained in:
parent
4f266958e3
commit
ae4ebab957
@ -257,6 +257,7 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
- location: Filter stock by location
|
- location: Filter stock by location
|
||||||
- category: Filter by parts belonging to a certain category
|
- category: Filter by parts belonging to a certain category
|
||||||
- supplier: Filter by supplier
|
- supplier: Filter by supplier
|
||||||
|
- ancestor: Filter by an 'ancestor' StockItem
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_serializer(self, *args, **kwargs):
|
def get_serializer(self, *args, **kwargs):
|
||||||
@ -284,6 +285,7 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
data = queryset.values(
|
data = queryset.values(
|
||||||
'pk',
|
'pk',
|
||||||
|
'parent',
|
||||||
'quantity',
|
'quantity',
|
||||||
'serial',
|
'serial',
|
||||||
'batch',
|
'batch',
|
||||||
@ -347,7 +349,20 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
else:
|
else:
|
||||||
stock_list = stock_list.filter(part=part_id)
|
stock_list = stock_list.filter(part=part_id)
|
||||||
|
|
||||||
except Part.DoesNotExist:
|
except (ValueError, Part.DoesNotExist):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Does the client wish to filter by the 'ancestor'?
|
||||||
|
anc_id = self.request.query_params.get('ancestor', None)
|
||||||
|
|
||||||
|
if anc_id:
|
||||||
|
try:
|
||||||
|
ancestor = StockItem.objects.get(pk=anc_id)
|
||||||
|
|
||||||
|
# Only allow items which are descendants of the specified StockItem
|
||||||
|
stock_list = stock_list.filter(id__in=[item.pk for item in ancestor.children.all()])
|
||||||
|
|
||||||
|
except (ValueError, Part.DoesNotExist):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Does the client wish to filter by stock location?
|
# Does the client wish to filter by stock location?
|
||||||
@ -358,7 +373,7 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
location = StockLocation.objects.get(pk=loc_id)
|
location = StockLocation.objects.get(pk=loc_id)
|
||||||
stock_list = stock_list.filter(location__in=location.getUniqueChildren())
|
stock_list = stock_list.filter(location__in=location.getUniqueChildren())
|
||||||
|
|
||||||
except StockLocation.DoesNotExist:
|
except (ValueError, StockLocation.DoesNotExist):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Does the client wish to filter by part category?
|
# Does the client wish to filter by part category?
|
||||||
@ -369,7 +384,7 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
category = PartCategory.objects.get(pk=cat_id)
|
category = PartCategory.objects.get(pk=cat_id)
|
||||||
stock_list = stock_list.filter(part__category__in=category.getUniqueChildren())
|
stock_list = stock_list.filter(part__category__in=category.getUniqueChildren())
|
||||||
|
|
||||||
except PartCategory.DoesNotExist:
|
except (ValueError, PartCategory.DoesNotExist):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Filter by supplier_part ID
|
# Filter by supplier_part ID
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
location: 3
|
location: 3
|
||||||
batch: 'B123'
|
batch: 'B123'
|
||||||
quantity: 4000
|
quantity: 4000
|
||||||
|
level: 0
|
||||||
|
tree_id: 0
|
||||||
|
lft: 0
|
||||||
|
rght: 0
|
||||||
|
|
||||||
# 5,000 screws in the bathroom
|
# 5,000 screws in the bathroom
|
||||||
- model: stock.stockitem
|
- model: stock.stockitem
|
||||||
@ -14,6 +18,10 @@
|
|||||||
part: 1
|
part: 1
|
||||||
location: 2
|
location: 2
|
||||||
quantity: 5000
|
quantity: 5000
|
||||||
|
level: 0
|
||||||
|
tree_id: 0
|
||||||
|
lft: 0
|
||||||
|
rght: 0
|
||||||
|
|
||||||
# 1234 2K2 resistors in 'Drawer_1'
|
# 1234 2K2 resistors in 'Drawer_1'
|
||||||
- model: stock.stockitem
|
- model: stock.stockitem
|
||||||
@ -22,6 +30,10 @@
|
|||||||
part: 3
|
part: 3
|
||||||
location: 5
|
location: 5
|
||||||
quantity: 1234
|
quantity: 1234
|
||||||
|
level: 0
|
||||||
|
tree_id: 0
|
||||||
|
lft: 0
|
||||||
|
rght: 0
|
||||||
|
|
||||||
# Some widgets in drawer 3
|
# Some widgets in drawer 3
|
||||||
- model: stock.stockitem
|
- model: stock.stockitem
|
||||||
@ -31,6 +43,10 @@
|
|||||||
location: 7
|
location: 7
|
||||||
quantity: 10
|
quantity: 10
|
||||||
delete_on_deplete: False
|
delete_on_deplete: False
|
||||||
|
level: 0
|
||||||
|
tree_id: 0
|
||||||
|
lft: 0
|
||||||
|
rght: 0
|
||||||
|
|
||||||
- model: stock.stockitem
|
- model: stock.stockitem
|
||||||
pk: 101
|
pk: 101
|
||||||
@ -38,10 +54,18 @@
|
|||||||
part: 25
|
part: 25
|
||||||
location: 7
|
location: 7
|
||||||
quantity: 5
|
quantity: 5
|
||||||
|
level: 0
|
||||||
|
tree_id: 0
|
||||||
|
lft: 0
|
||||||
|
rght: 0
|
||||||
|
|
||||||
- model: stock.stockitem
|
- model: stock.stockitem
|
||||||
pk: 102
|
pk: 102
|
||||||
fields:
|
fields:
|
||||||
part: 25
|
part: 25
|
||||||
location: 7
|
location: 7
|
||||||
quantity: 3
|
quantity: 3
|
||||||
|
level: 0
|
||||||
|
tree_id: 0
|
||||||
|
lft: 0
|
||||||
|
rght: 0
|
@ -385,12 +385,17 @@ class StockItem(MPTTModel):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def children(self):
|
||||||
|
""" Return a list of the child items which have been split from this stock item """
|
||||||
|
return self.get_descendants(include_self=False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def child_count(self):
|
def child_count(self):
|
||||||
""" Return the number of 'child' items associated with this StockItem.
|
""" Return the number of 'child' items associated with this StockItem.
|
||||||
A child item is one which has been split from this one.
|
A child item is one which has been split from this one.
|
||||||
"""
|
"""
|
||||||
return self.get_descendants(include_self=False).count()
|
return self.children.count()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def in_stock(self):
|
def in_stock(self):
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if item.parent %}
|
{% if item.parent %}
|
||||||
<div class='alert alert-block alert-info'>
|
<div class='alert alert-block alert-info'>
|
||||||
{% trans "This stock item has been split from " %}<a href="{% url 'stock-item-detail' item.parent.id %}">{{ item.parent }}</a>
|
{% trans "This stock item was split from " %}<a href="{% url 'stock-item-detail' item.parent.id %}">{{ item.parent }}</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
42
InvenTree/stock/templates/stock/item_childs.html
Normal file
42
InvenTree/stock/templates/stock/item_childs.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{% extends "stock/item_base.html" %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block details %}
|
||||||
|
|
||||||
|
{% include "stock/tabs.html" with tab='children' %}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h4>{% trans "Child Stock Items" %}</h4>
|
||||||
|
|
||||||
|
{% if item.child_count > 0 %}
|
||||||
|
{% include "stock_table.html" %}
|
||||||
|
{% else %}
|
||||||
|
<div class='alert alert-block alert-info'>
|
||||||
|
{% trans "This stock item does not have any child items" %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js_ready %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
{% if item.child_count > 0 %}
|
||||||
|
loadStockTable($("#stock-table"), {
|
||||||
|
params: {
|
||||||
|
location_detail: true,
|
||||||
|
part_details: true,
|
||||||
|
ancestor: {{ item.id }},
|
||||||
|
},
|
||||||
|
groupByField: 'location',
|
||||||
|
buttons: [
|
||||||
|
'#stock-options',
|
||||||
|
],
|
||||||
|
url: "{% url 'api-stock-list' %}",
|
||||||
|
});
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -4,6 +4,9 @@
|
|||||||
<li{% ifequal tab 'tracking' %} class='active'{% endifequal %}>
|
<li{% ifequal tab 'tracking' %} class='active'{% endifequal %}>
|
||||||
<a href="{% url 'stock-item-detail' item.id %}">{% trans "Tracking" %}</a>
|
<a href="{% url 'stock-item-detail' item.id %}">{% trans "Tracking" %}</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li{% ifequal tab 'children' %} class='active'{% endifequal %}>
|
||||||
|
<a href="{% url 'stock-item-children' item.id %}">{% trans "Children" %}{% if item.child_count > 0 %}<span class='badge'>{{ item.child_count }}</span>{% endif %}</a>
|
||||||
|
</li>
|
||||||
{% if 0 %}
|
{% if 0 %}
|
||||||
<!-- These tabs are to be implemented in the future -->
|
<!-- These tabs are to be implemented in the future -->
|
||||||
<li{% ifequal tab 'builds' %} class='active'{% endifequal %}>
|
<li{% ifequal tab 'builds' %} class='active'{% endifequal %}>
|
||||||
|
@ -24,6 +24,7 @@ stock_item_detail_urls = [
|
|||||||
|
|
||||||
url(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'),
|
url(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'),
|
||||||
|
|
||||||
|
url(r'^children/', views.StockItemDetail.as_view(template_name='stock/item_childs.html'), name='stock-item-children'),
|
||||||
url(r'^notes/', views.StockItemNotes.as_view(), name='stock-item-notes'),
|
url(r'^notes/', views.StockItemNotes.as_view(), name='stock-item-notes'),
|
||||||
|
|
||||||
url('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'),
|
url('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'),
|
||||||
|
Loading…
Reference in New Issue
Block a user