Enhancement for the BuildItem API / serializer

- Add optional "part_detail" information
- Add optional "build_detail" information
- Add optional "location_detail" information
This commit is contained in:
Oliver 2021-06-18 19:08:54 +10:00
parent 10ecddf9b4
commit 245c9bfd28
3 changed files with 122 additions and 7 deletions

View File

@ -165,6 +165,16 @@ class BuildItemList(generics.ListCreateAPIView):
serializer_class = BuildItemSerializer
def get_serializer(self, *args, **kwargs):
params = self.request.query_params
kwargs['part_detail'] = str2bool(params.get('part_detail', False))
kwargs['build_detail'] = str2bool(params.get('build_detail', False))
kwargs['location_detail'] = str2bool(params.get('location_detail', False))
return self.serializer_class(*args, **kwargs)
def get_queryset(self):
""" Override the queryset method,
to allow filtering by stock_item.part

View File

@ -13,7 +13,8 @@ from rest_framework import serializers
from InvenTree.serializers import InvenTreeModelSerializer
from stock.serializers import StockItemSerializerBrief
from part.serializers import PartBriefSerializer
from stock.serializers import LocationSerializer
from part.serializers import PartSerializer, PartBriefSerializer
from .models import Build, BuildItem
@ -99,22 +100,45 @@ class BuildItemSerializer(InvenTreeModelSerializer):
bom_part = serializers.IntegerField(source='bom_item.sub_part.pk', read_only=True)
part = serializers.IntegerField(source='stock_item.part.pk', read_only=True)
part_name = serializers.CharField(source='stock_item.part.full_name', read_only=True)
part_thumb = serializers.CharField(source='getStockItemThumbnail', read_only=True)
location = serializers.IntegerField(source='stock_item.location.pk', read_only=True)
# Extra (optional) detail fields
part_detail = PartSerializer(source='stock_item.part', many=False, read_only=True)
build_detail = BuildSerializer(source='build', many=False, read_only=True)
stock_item_detail = StockItemSerializerBrief(source='stock_item', read_only=True)
location_detail = LocationSerializer(source='stock_item.location', read_only=True)
quantity = serializers.FloatField()
def __init__(self, *args, **kwargs):
build_detail = kwargs.pop('build_detail', False)
part_detail = kwargs.pop('part_detail', False)
location_detail = kwargs.pop('location_detail', False)
super().__init__(*args, **kwargs)
if not build_detail:
self.fields.pop('build_detail')
if not part_detail:
self.fields.pop('part_detail')
if not location_detail:
self.fields.pop('location_detail')
class Meta:
model = BuildItem
fields = [
'pk',
'bom_part',
'build',
'build_detail',
'install_into',
'location',
'location_detail',
'part',
'part_name',
'part_thumb',
'part_detail',
'stock_item',
'stock_item_detail',
'quantity'

View File

@ -155,6 +155,85 @@ function makeBuildOutputActionButtons(output, buildInfo, lines) {
}
function loadBuildOrderAllocationTable(table, options={}) {
/**
* Load a table showing all the BuildOrder allocations for a given part
*/
options.params['part_detail'] = true;
options.params['build_detail'] = true;
options.params['location_detail'] = true;
var filters = loadTableFilters("buildorderallocation");
for (var key in options.params) {
filters[key] = options.params[key];
}
setupFilterList("buildorderallocation", $(table));
$(table).inventreeTable({
url: '{% url "api-build-item-list" %}',
queryParams: filters,
name: 'buildorderallocation',
groupBy: false,
original: options.params,
formatNoMatches: function() {
return '{% trans "No build order allocations found" %}'
},
columns: [
{
field: 'pk',
visible: false,
switchable: false,
},
{
field: 'build',
title: '{% trans "Build Order" %}',
formatter: function(value, row) {
var prefix = "{% settings_value 'BUILDORDER_REFERENCE_PREFIX' %}";
var ref = `${prefix}${row.build_detail.reference}`;
return renderLink(ref, `/build/${row.build}/`);
}
},
{
field: 'item',
title: '{% trans "Stock Item" %}',
formatter: function(value, row) {
// Render a link to the particular stock item
var link = `/stock/item/${row.stock_item}/`;
var text = `{% trans "Stock Item" %} ${row.stock_item}`;
return renderLink(text, link);
}
},
{
field: 'location',
title: '{% trans "Location" %}',
formatter: function(value, row) {
if (!value) {
return '{% trans "Location not specified" %}';
}
var link = `/stock/location/${value}`;
var text = row.location_detail.description;
return renderLink(text, link);
}
},
{
field: 'quantity',
title: '{% trans "Quantity" %}',
}
]
});
}
function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
/*
* Load the "allocation table" for a particular build output.
@ -347,6 +426,8 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
var params = {
build: buildId,
part_detail: true,
location_detail: true,
}
if (output) {
@ -466,8 +547,8 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
title: '{% trans "Part" %}',
formatter: function(value, row) {
var html = imageHoverIcon(row.part_thumb);
html += renderLink(row.part_name, `/part/${value}/`);
var html = imageHoverIcon(row.part_detail.thumbnail);
html += renderLink(row.part_detail.full_name, `/part/${value}/`);
return html;
}
},