mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Display a sub-list of stock items which are allocated to a SalseOrderLineItem
This commit is contained in:
parent
b40234e403
commit
cb636e000d
@ -158,6 +158,15 @@
|
|||||||
background-color: #ebf4f4;
|
background-color: #ebf4f4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sub-table {
|
||||||
|
margin-left: 25px;
|
||||||
|
margin-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-icon .glyphicon {
|
||||||
|
color: #98d296;
|
||||||
|
}
|
||||||
|
|
||||||
/* Force select2 elements in modal forms to be full width */
|
/* Force select2 elements in modal forms to be full width */
|
||||||
.select-full-width {
|
.select-full-width {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -221,7 +221,6 @@ function loadBomTable(table, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Part notes
|
// Part notes
|
||||||
|
@ -44,6 +44,67 @@ $("#so-lines-table").inventreeTable({
|
|||||||
part_detail: true,
|
part_detail: true,
|
||||||
},
|
},
|
||||||
url: "{% url 'api-so-line-list' %}",
|
url: "{% url 'api-so-line-list' %}",
|
||||||
|
detailView: true,
|
||||||
|
detailFilter: function(index, row) {
|
||||||
|
return row.allocated > 0;
|
||||||
|
},
|
||||||
|
detailFormatter: function(index, row, element) {
|
||||||
|
inventreeGet("{% url 'api-stock-list' %}",
|
||||||
|
{
|
||||||
|
location_detail: true,
|
||||||
|
sales_order_line: row.pk,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
success: function(response) {
|
||||||
|
|
||||||
|
var html = `<div class='sub-table'><table class='table table-striped table-condensed' id='allocation-table-${row.pk}'></table></div>`;
|
||||||
|
|
||||||
|
element.html(html);
|
||||||
|
|
||||||
|
$(`#allocation-table-${row.pk}`).bootstrapTable({
|
||||||
|
data: response,
|
||||||
|
showHeader: false,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
width: '50%',
|
||||||
|
field: 'quantity',
|
||||||
|
title: 'Quantity',
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
var html = '';
|
||||||
|
if (row.serial && row.quantity == 1) {
|
||||||
|
html = `Serial Number: ${row.serial}`;
|
||||||
|
} else {
|
||||||
|
html = `Quantity: ${row.quantity}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderLink(html, `/stock/item/${row.pk}/`);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'location',
|
||||||
|
title: 'Location',
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
return renderLink(row.location_detail.pathstring, `/stock/location/${row.location}/`);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'buttons',
|
||||||
|
title: 'Actions',
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(response) {
|
||||||
|
console.log("An error!");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return "{% trans 'Loading data' %}";
|
||||||
|
},
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
field: 'pk',
|
field: 'pk',
|
||||||
@ -73,12 +134,29 @@ $("#so-lines-table").inventreeTable({
|
|||||||
title: 'Quantity',
|
title: 'Quantity',
|
||||||
formatter: function(value, row, index, field) {
|
formatter: function(value, row, index, field) {
|
||||||
return makeProgressBar(row.allocated, row.quantity);
|
return makeProgressBar(row.allocated, row.quantity);
|
||||||
|
},
|
||||||
|
sorter: function(valA, valB, rowA, rowB) {
|
||||||
|
|
||||||
|
if (rowA.allocated == 0 && rowB.allocated == 0) {
|
||||||
|
return (rowA.quantity > rowB.quantity) ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var progressA = rowA.allocated / rowA.quantity;
|
||||||
|
var progressB = rowB.allocated / rowA.quantity;
|
||||||
|
|
||||||
|
return (progressA < progressB) ? 1 : -1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'notes',
|
field: 'notes',
|
||||||
title: 'Notes',
|
title: 'Notes',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'buttons',
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -233,9 +233,11 @@ class PartStarSerializer(InvenTreeModelSerializer):
|
|||||||
class BomItemSerializer(InvenTreeModelSerializer):
|
class BomItemSerializer(InvenTreeModelSerializer):
|
||||||
""" Serializer for BomItem object """
|
""" Serializer for BomItem object """
|
||||||
|
|
||||||
|
price_range = serializers.CharField(read_only=True)
|
||||||
|
|
||||||
part_detail = PartBriefSerializer(source='part', many=False, read_only=True)
|
part_detail = PartBriefSerializer(source='part', many=False, read_only=True)
|
||||||
sub_part_detail = PartBriefSerializer(source='sub_part', many=False, read_only=True)
|
sub_part_detail = PartBriefSerializer(source='sub_part', many=False, read_only=True)
|
||||||
price_range = serializers.CharField(read_only=True)
|
|
||||||
validated = serializers.BooleanField(read_only=True, source='is_line_valid')
|
validated = serializers.BooleanField(read_only=True, source='is_line_valid')
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
{% if item.sales_order %}
|
{% if item.sales_order_line %}
|
||||||
<div class='alert alert-block alert-info'>
|
<div class='alert alert-block alert-info'>
|
||||||
{% trans "This stock item is allocated to " %}
|
{% trans "This stock item is allocated to Sales Order" %}
|
||||||
<a href="{% url 'so-detail' item.sales_order.order.id %}"><b>{{ item.sales_order.order }}</b></a>
|
<a href="{% url 'so-detail' item.sales_order_line.order.id %}"><b>{{ item.sales_order_line.order }}</b></a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user