mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add run-time addition of extra data to the API
This commit is contained in:
parent
93e6eb6dc7
commit
0c19a94f5c
@ -22,7 +22,10 @@ from part.models import Part, PartCategory
|
|||||||
from part.serializers import PartBriefSerializer
|
from part.serializers import PartBriefSerializer
|
||||||
|
|
||||||
from company.models import SupplierPart
|
from company.models import SupplierPart
|
||||||
from company.serializers import SupplierPartSerializer
|
from company.serializers import CompanySerializer, SupplierPartSerializer
|
||||||
|
|
||||||
|
from order.models import PurchaseOrder
|
||||||
|
from order.serializers import POSerializer
|
||||||
|
|
||||||
import common.settings
|
import common.settings
|
||||||
import common.models
|
import common.models
|
||||||
@ -992,6 +995,59 @@ class StockTrackingList(generics.ListAPIView):
|
|||||||
|
|
||||||
return self.serializer_class(*args, **kwargs)
|
return self.serializer_class(*args, **kwargs)
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
|
||||||
|
queryset = self.filter_queryset(self.get_queryset())
|
||||||
|
|
||||||
|
serializer = self.get_serializer(queryset, many=True)
|
||||||
|
|
||||||
|
data = serializer.data
|
||||||
|
|
||||||
|
# Attempt to add extra context information to the historical data
|
||||||
|
for item in data:
|
||||||
|
deltas = item['deltas']
|
||||||
|
|
||||||
|
# Add location detail
|
||||||
|
if 'location' in deltas:
|
||||||
|
try:
|
||||||
|
location = StockLocation.objects.get(pk=deltas['location'])
|
||||||
|
serializer = LocationSerializer(location)
|
||||||
|
deltas['location_detail'] = serializer.data
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Add stockitem detail
|
||||||
|
if 'stockitem' in deltas:
|
||||||
|
try:
|
||||||
|
stockitem = StockItem.objects.get(pk=deltas['stockitem'])
|
||||||
|
serializer = StockItemSerializer(stockitem)
|
||||||
|
deltas['stockitem_detail'] = serializer.data
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Add customer detail
|
||||||
|
if 'customer' in deltas:
|
||||||
|
try:
|
||||||
|
customer = Company.objects.get(pk=deltas['customer'])
|
||||||
|
serializer = CompanySerializer(location)
|
||||||
|
deltas['customer_detail'] = serializer.data
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Add purchaseorder detail
|
||||||
|
if 'purchaseorder' in deltas:
|
||||||
|
try:
|
||||||
|
order = PurchaseOrder.objects.get(pk=deltas['purchaseorder'])
|
||||||
|
serializer = POSerializer(order)
|
||||||
|
deltas['purchaseorder_detail'] = serializer.data
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if request.is_ajax():
|
||||||
|
return JsonResponse(data, safe=False)
|
||||||
|
else:
|
||||||
|
return Response(data)
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
""" Create a new StockItemTracking object
|
""" Create a new StockItemTracking object
|
||||||
|
|
||||||
|
@ -976,42 +976,28 @@ function loadStockLocationTable(table, options) {
|
|||||||
|
|
||||||
function loadStockTrackingTable(table, options) {
|
function loadStockTrackingTable(table, options) {
|
||||||
|
|
||||||
var cols = [
|
var cols = [];
|
||||||
{
|
|
||||||
field: 'pk',
|
|
||||||
visible: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'date',
|
|
||||||
title: '{% trans "Date" %}',
|
|
||||||
sortable: true,
|
|
||||||
formatter: function(value, row, index, field) {
|
|
||||||
var m = moment(value);
|
|
||||||
if (m.isValid()) {
|
|
||||||
var html = m.format('dddd MMMM Do YYYY'); // + '<br>' + m.format('h:mm a');
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'N/A';
|
// Date
|
||||||
}
|
cols.push({
|
||||||
},
|
field: 'date',
|
||||||
];
|
title: '{% trans "Date" %}',
|
||||||
|
sortable: true,
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
var m = moment(value);
|
||||||
|
|
||||||
// If enabled, provide a link to the referenced StockItem
|
if (m.isValid()) {
|
||||||
if (options.partColumn) {
|
var html = m.format('dddd MMMM Do YYYY'); // + '<br>' + m.format('h:mm a');
|
||||||
cols.push({
|
return html;
|
||||||
field: 'item',
|
|
||||||
title: '{% trans "Stock Item" %}',
|
|
||||||
sortable: true,
|
|
||||||
formatter: function(value, row, index, field) {
|
|
||||||
return renderLink(value.part_name, value.url);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
return '<i>{% trans "Invalid date" %}</i>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Stock transaction description
|
// Stock transaction description
|
||||||
cols.push({
|
cols.push({
|
||||||
field: 'title',
|
field: 'label',
|
||||||
title: '{% trans "Description" %}',
|
title: '{% trans "Description" %}',
|
||||||
formatter: function(value, row, index, field) {
|
formatter: function(value, row, index, field) {
|
||||||
var html = "<b>" + value + "</b>";
|
var html = "<b>" + value + "</b>";
|
||||||
@ -1020,20 +1006,129 @@ function loadStockTrackingTable(table, options) {
|
|||||||
html += "<br><i>" + row.notes + "</i>";
|
html += "<br><i>" + row.notes + "</i>";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row.link) {
|
|
||||||
html += "<br><a href='" + row.link + "'>" + row.link + "</a>";
|
|
||||||
}
|
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Stock transaction details
|
||||||
cols.push({
|
cols.push({
|
||||||
field: 'quantity',
|
field: 'deltas',
|
||||||
title: '{% trans "Quantity" %}',
|
title: '{% trans "Details" %}',
|
||||||
formatter: function(value, row, index, field) {
|
formatter: function(details, row, index, field) {
|
||||||
return parseFloat(value);
|
var html = `<table class='table table-condensed' id='tracking-table-${row.pk}'>`;
|
||||||
},
|
|
||||||
|
// Location information
|
||||||
|
if (details.location) {
|
||||||
|
|
||||||
|
html += `<tr><th>{% trans "Location" %}</th>`;
|
||||||
|
|
||||||
|
html += '<td>';
|
||||||
|
|
||||||
|
if (details.location_detail) {
|
||||||
|
// A valid location is provided
|
||||||
|
|
||||||
|
html += renderLink(
|
||||||
|
details.location_detail.pathstring,
|
||||||
|
details.location_detail.url,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// An invalid location (may have been deleted?)
|
||||||
|
html += `<i>{% trans "Location no longer exists" %}</i>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</td></tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Purchase Order Information
|
||||||
|
if (details.purchaseorder) {
|
||||||
|
|
||||||
|
html += `<tr><th>{% trans "Purchase Order" %}</td>`;
|
||||||
|
|
||||||
|
html += '<td>';
|
||||||
|
|
||||||
|
if (details.purchaseorder_detail) {
|
||||||
|
html += renderLink(
|
||||||
|
details.purchaseorder_detail.reference,
|
||||||
|
`/order/purchase-order/${details.purchaseorder}/`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
html += `<i>{% trans "Purchase order no longer exists" %}</i>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</td></tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Customer information
|
||||||
|
if (details.customer) {
|
||||||
|
|
||||||
|
html += `<tr><th>{% trans "Customer" %}</td>`;
|
||||||
|
|
||||||
|
html += '<td>';
|
||||||
|
|
||||||
|
if (details.customer_detail) {
|
||||||
|
html += renderLink(
|
||||||
|
details.customer_detail.name,
|
||||||
|
details.customer_detail.url
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
html += `<i>{% trans "Customer no longer exists" %}</i>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</td></tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stockitem information
|
||||||
|
if (details.stockitem) {
|
||||||
|
html += '<tr><th>{% trans "Stock Item" %}</td>';
|
||||||
|
|
||||||
|
html += '<td>';
|
||||||
|
|
||||||
|
if (details.stockitem_detail) {
|
||||||
|
html += renderLink(
|
||||||
|
details.stockitem,
|
||||||
|
`/stock/item/${details.stockitem}/`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
html += `<i>{% trans "Stock item no longer exists" %}</i>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</td></tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status information
|
||||||
|
if (details.status) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quantity information
|
||||||
|
if (details.added) {
|
||||||
|
html += '<tr><th>{% trans "Added" %}</th>';
|
||||||
|
|
||||||
|
html += `<td>${details.added}</td>`;
|
||||||
|
|
||||||
|
html += '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (details.removed) {
|
||||||
|
html += '<tr><th>{% trans "Removed" %}</th>';
|
||||||
|
|
||||||
|
html += `<td>${details.removed}</td>`;
|
||||||
|
|
||||||
|
html += '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (details.quantity) {
|
||||||
|
html += '<tr><th>{% trans "Quantity" %}</th>';
|
||||||
|
|
||||||
|
html += `<td>${details.quantity}</td>`;
|
||||||
|
|
||||||
|
html += '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</table>';
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cols.push({
|
cols.push({
|
||||||
@ -1056,7 +1151,7 @@ function loadStockTrackingTable(table, options) {
|
|||||||
sortable: false,
|
sortable: false,
|
||||||
formatter: function(value, row, index, field) {
|
formatter: function(value, row, index, field) {
|
||||||
// Manually created entries can be edited or deleted
|
// Manually created entries can be edited or deleted
|
||||||
if (!row.system) {
|
if (false && !row.system) {
|
||||||
var bEdit = "<button title='{% trans 'Edit tracking entry' %}' class='btn btn-entry-edit btn-default btn-glyph' type='button' url='/stock/track/" + row.pk + "/edit/'><span class='fas fa-edit'/></button>";
|
var bEdit = "<button title='{% trans 'Edit tracking entry' %}' class='btn btn-entry-edit btn-default btn-glyph' type='button' url='/stock/track/" + row.pk + "/edit/'><span class='fas fa-edit'/></button>";
|
||||||
var bDel = "<button title='{% trans 'Delete tracking entry' %}' class='btn btn-entry-delete btn-default btn-glyph' type='button' url='/stock/track/" + row.pk + "/delete/'><span class='fas fa-trash-alt icon-red'/></button>";
|
var bDel = "<button title='{% trans 'Delete tracking entry' %}' class='btn btn-entry-delete btn-default btn-glyph' type='button' url='/stock/track/" + row.pk + "/delete/'><span class='fas fa-trash-alt icon-red'/></button>";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user