mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #767 from SchrodingersGat/fix
Fix for BOM table display
This commit is contained in:
commit
86c00f54b7
@ -133,11 +133,14 @@ function loadBomTable(table, options) {
|
|||||||
title: 'Part',
|
title: 'Part',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
formatter: function(value, row, index, field) {
|
formatter: function(value, row, index, field) {
|
||||||
var html = imageHoverIcon(row.sub_part_detail.thumbnail) + renderLink(row.sub_part_detail.full_name, row.sub_part_detail.url);
|
var url = `/part/${row.sub_part}/`;
|
||||||
|
var html = imageHoverIcon(row.sub_part_detail.thumbnail) + renderLink(row.sub_part_detail.full_name, url);
|
||||||
|
|
||||||
// Display an extra icon if this part is an assembly
|
// Display an extra icon if this part is an assembly
|
||||||
if (row.sub_part_detail.assembly) {
|
if (row.sub_part_detail.assembly) {
|
||||||
html += "<a href='" + row.sub_part_detail.url + "bom'><span title='Open subassembly' class='fas fa-stream label-right'></span></a>";
|
var text = `<span title='Open subassembly' class='fas fa-stream label-right'></span>`;
|
||||||
|
|
||||||
|
html += renderLink(text, `/part/${row.sub_part}/bom/`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
@ -185,26 +188,20 @@ function loadBomTable(table, options) {
|
|||||||
if (!options.editable) {
|
if (!options.editable) {
|
||||||
cols.push(
|
cols.push(
|
||||||
{
|
{
|
||||||
field: 'sub_part_detail.total_stock',
|
field: 'sub_part_detail.stock',
|
||||||
title: 'Available',
|
title: 'Available',
|
||||||
searchable: false,
|
searchable: false,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
formatter: function(value, row, index, field) {
|
formatter: function(value, row, index, field) {
|
||||||
var text = "";
|
|
||||||
|
var url = `/part/${row.sub_part_detail.pk}/stock/`;
|
||||||
if (row.quantity < row.sub_part_detail.total_stock)
|
var text = value;
|
||||||
{
|
|
||||||
text = "<span class='label label-success'>" + value + "</span>";
|
if (value == null || value <= 0) {
|
||||||
|
text = `<span class='label label-warning'>No Stock</span>`;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return renderLink(text, url);
|
||||||
if (!value) {
|
|
||||||
value = 'No Stock';
|
|
||||||
}
|
|
||||||
text = "<span class='label label-warning'>" + value + "</span>";
|
|
||||||
}
|
|
||||||
|
|
||||||
return renderLink(text, row.sub_part_detail.url + "stock/");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -468,15 +468,15 @@ class BomList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
# Do we wish to include extra detail?
|
# Do we wish to include extra detail?
|
||||||
try:
|
try:
|
||||||
part_detail = str2bool(self.request.GET.get('part_detail', None))
|
kwargs['part_detail'] = str2bool(self.request.GET.get('part_detail', None))
|
||||||
sub_part_detail = str2bool(self.request.GET.get('sub_part_detail', None))
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
part_detail = None
|
pass
|
||||||
sub_part_detail = None
|
|
||||||
|
|
||||||
kwargs['part_detail'] = part_detail
|
|
||||||
kwargs['sub_part_detail'] = sub_part_detail
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
kwargs['sub_part_detail'] = str2bool(self.request.GET.get('sub_part_detail', None))
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Ensure the request context is passed through!
|
# Ensure the request context is passed through!
|
||||||
kwargs['context'] = self.get_serializer_context()
|
kwargs['context'] = self.get_serializer_context()
|
||||||
|
|
||||||
@ -486,6 +486,12 @@ class BomList(generics.ListCreateAPIView):
|
|||||||
queryset = BomItem.objects.all()
|
queryset = BomItem.objects.all()
|
||||||
queryset = self.get_serializer_class().setup_eager_loading(queryset)
|
queryset = self.get_serializer_class().setup_eager_loading(queryset)
|
||||||
|
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def filter_queryset(self, queryset):
|
||||||
|
|
||||||
|
queryset = super().filter_queryset(queryset)
|
||||||
|
|
||||||
# Filter by part?
|
# Filter by part?
|
||||||
part = self.request.query_params.get('part', None)
|
part = self.request.query_params.get('part', None)
|
||||||
|
|
||||||
|
@ -1242,6 +1242,17 @@ class BomItem(models.Model):
|
|||||||
child=self.sub_part.full_name,
|
child=self.sub_part.full_name,
|
||||||
n=helpers.decimal2string(self.quantity))
|
n=helpers.decimal2string(self.quantity))
|
||||||
|
|
||||||
|
def available_stock(self):
|
||||||
|
"""
|
||||||
|
Return the available stock items for the referenced sub_part
|
||||||
|
"""
|
||||||
|
|
||||||
|
query = self.sub_part.stock_items.filter(StockModels.StockItem.IN_STOCK_FILTER).aggregate(
|
||||||
|
available=Coalesce(Sum('quantity'), 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
return query['available']
|
||||||
|
|
||||||
def get_overage_quantity(self, quantity):
|
def get_overage_quantity(self, quantity):
|
||||||
""" Calculate overage quantity
|
""" Calculate overage quantity
|
||||||
"""
|
"""
|
||||||
|
@ -54,6 +54,8 @@ class PartBriefSerializer(InvenTreeModelSerializer):
|
|||||||
|
|
||||||
thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True)
|
thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True)
|
||||||
|
|
||||||
|
stock = serializers.FloatField(source='total_stock')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Part
|
model = Part
|
||||||
fields = [
|
fields = [
|
||||||
@ -65,6 +67,7 @@ class PartBriefSerializer(InvenTreeModelSerializer):
|
|||||||
'assembly',
|
'assembly',
|
||||||
'purchaseable',
|
'purchaseable',
|
||||||
'salable',
|
'salable',
|
||||||
|
'stock',
|
||||||
'virtual',
|
'virtual',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{% extends "part/part_base.html" %}
|
{% extends "part/part_base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
{% block details %}
|
{% block details %}
|
||||||
|
|
||||||
{% include 'part/tabs.html' with tab='used' %}
|
{% include 'part/tabs.html' with tab='used' %}
|
||||||
|
|
||||||
<h4>Assemblies</h4>
|
<h4>{% trans "Assemblies" %}</h4>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
@ -35,10 +35,11 @@
|
|||||||
title: 'Part',
|
title: 'Part',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
formatter: function(value, row, index, field) {
|
formatter: function(value, row, index, field) {
|
||||||
var html = imageHoverIcon(row.part_detail.thumbnail) + renderLink(value.full_name, value.url + 'bom/');
|
var link = `/part/${value.pk}/bom/`;
|
||||||
|
var html = imageHoverIcon(row.part_detail.thumbnail) + renderLink(value.full_name, link);
|
||||||
|
|
||||||
if (!row.part_detail.active) {
|
if (!row.part_detail.active) {
|
||||||
html += "<span class='label label-warning' style='float: right;'>INACTIVE</span>";
|
html += "<span class='label label-warning' style='float: right;'>{% trans "INACTIVE" %}</span>";
|
||||||
}
|
}
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
|
@ -137,7 +137,6 @@ class StockItem(MPTTModel):
|
|||||||
sales_order=None,
|
sales_order=None,
|
||||||
build_order=None,
|
build_order=None,
|
||||||
belongs_to=None,
|
belongs_to=None,
|
||||||
status__in=StockStatus.AVAILABLE_CODES
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
Loading…
Reference in New Issue
Block a user