mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 13:05:42 +00:00
Merge branch 'master' into matmair/issue2694
This commit is contained in:
@ -312,7 +312,13 @@ function renderPartCategory(name, data, parameters, options) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function renderPartParameterTemplate(name, data, parameters, options) {
|
||||
|
||||
var html = `<span>${data.name} - [${data.units}]</span>`;
|
||||
var units = '';
|
||||
|
||||
if (data.units) {
|
||||
units = ` [${data.units}]`;
|
||||
}
|
||||
|
||||
var html = `<span>${data.name}${units}</span>`;
|
||||
|
||||
return html;
|
||||
}
|
||||
|
@ -2298,15 +2298,7 @@ function loadSalesOrderAllocationTable(table, options={}) {
|
||||
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);
|
||||
return locationDetail(row.item_detail, true);
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1068,68 +1068,84 @@ function loadRelatedPartsTable(table, part_id, options={}) {
|
||||
}
|
||||
|
||||
|
||||
/* Load parametric table for part parameters
|
||||
*/
|
||||
function loadParametricPartTable(table, options={}) {
|
||||
/* Load parametric table for part parameters
|
||||
*
|
||||
* Args:
|
||||
* - table: HTML reference to the table
|
||||
* - table_headers: Unique parameters found in category
|
||||
* - table_data: Parameters data
|
||||
*/
|
||||
|
||||
var table_headers = options.headers;
|
||||
var table_data = options.data;
|
||||
var columns = [
|
||||
{
|
||||
field: 'name',
|
||||
title: '{% trans "Part" %}',
|
||||
switchable: false,
|
||||
sortable: true,
|
||||
formatter: function(value, row) {
|
||||
var name = row.full_name;
|
||||
|
||||
var columns = [];
|
||||
var display = imageHoverIcon(row.thumbnail) + renderLink(name, `/part/${row.pk}/`);
|
||||
|
||||
for (var header of table_headers) {
|
||||
if (header === 'part') {
|
||||
columns.push({
|
||||
field: header,
|
||||
title: '{% trans "Part" %}',
|
||||
sortable: true,
|
||||
sortName: 'name',
|
||||
formatter: function(value, row) {
|
||||
|
||||
var name = '';
|
||||
|
||||
if (row.IPN) {
|
||||
name += row.IPN + ' | ' + row.name;
|
||||
} else {
|
||||
name += row.name;
|
||||
}
|
||||
|
||||
return renderLink(name, '/part/' + row.pk + '/');
|
||||
}
|
||||
});
|
||||
} else if (header === 'description') {
|
||||
columns.push({
|
||||
field: header,
|
||||
title: '{% trans "Description" %}',
|
||||
sortable: true,
|
||||
});
|
||||
} else {
|
||||
columns.push({
|
||||
field: header,
|
||||
title: header,
|
||||
sortable: true,
|
||||
filterControl: 'input',
|
||||
});
|
||||
return display;
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// Request a list of parameters we are interested in for this category
|
||||
inventreeGet(
|
||||
'{% url "api-part-parameter-template-list" %}',
|
||||
{
|
||||
category: options.category,
|
||||
},
|
||||
{
|
||||
async: false,
|
||||
success: function(response) {
|
||||
for (var template of response) {
|
||||
columns.push({
|
||||
field: `parameter_${template.pk}`,
|
||||
title: template.name,
|
||||
switchable: true,
|
||||
sortable: true,
|
||||
filterControl: 'input',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// TODO: Re-enable filter control for parameter values
|
||||
|
||||
$(table).inventreeTable({
|
||||
sortName: 'part',
|
||||
queryParams: table_headers,
|
||||
url: '{% url "api-part-list" %}',
|
||||
queryParams: {
|
||||
category: options.category,
|
||||
cascade: true,
|
||||
parameters: true,
|
||||
},
|
||||
groupBy: false,
|
||||
name: options.name || 'parametric',
|
||||
name: options.name || 'part-parameters',
|
||||
formatNoMatches: function() {
|
||||
return '{% trans "No parts found" %}';
|
||||
},
|
||||
columns: columns,
|
||||
showColumns: true,
|
||||
data: table_data,
|
||||
filterControl: true,
|
||||
// filterControl: true,
|
||||
sidePagination: 'server',
|
||||
idField: 'pk',
|
||||
uniqueId: 'pk',
|
||||
onLoadSuccess: function() {
|
||||
|
||||
var data = $(table).bootstrapTable('getData');
|
||||
|
||||
for (var idx = 0; idx < data.length; idx++) {
|
||||
var row = data[idx];
|
||||
var pk = row.pk;
|
||||
|
||||
// Make each parameter accessible, based on the "template" columns
|
||||
row.parameters.forEach(function(parameter) {
|
||||
row[`parameter_${parameter.template}`] = parameter.data;
|
||||
});
|
||||
|
||||
$(table).bootstrapTable('updateRow', pk, row);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -2028,6 +2044,22 @@ function loadPartSchedulingChart(canvas_id, part_id) {
|
||||
}
|
||||
);
|
||||
|
||||
// If no scheduling information is available for the part,
|
||||
// remove the chart and display a message instead
|
||||
if (stock_schedule.length <= 1) {
|
||||
|
||||
var message = `
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% trans "No scheduling information available for this part" %}.<br>
|
||||
</div>`;
|
||||
|
||||
var canvas_element = $('#part-schedule-chart');
|
||||
|
||||
canvas_element.closest('div').html(message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate through future "events" to calculate expected quantity
|
||||
|
||||
var quantity = part_info.in_stock;
|
||||
|
@ -46,7 +46,6 @@
|
||||
findStockItemBySerialNumber,
|
||||
installStockItem,
|
||||
loadInstalledInTable,
|
||||
loadStockAllocationTable,
|
||||
loadStockLocationTable,
|
||||
loadStockTable,
|
||||
loadStockTestResultsTable,
|
||||
@ -2302,157 +2301,6 @@ function loadStockTable(table, options) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display a table of allocated stock, for either a part or stock item
|
||||
* Allocations are displayed for:
|
||||
*
|
||||
* a) Sales Orders
|
||||
* b) Build Orders
|
||||
*/
|
||||
function loadStockAllocationTable(table, options={}) {
|
||||
|
||||
var params = options.params || {};
|
||||
|
||||
params.build_detail = true;
|
||||
|
||||
var filterListElement = options.filterList || '#filter-list-allocations';
|
||||
|
||||
var filters = {};
|
||||
|
||||
var filterKey = options.filterKey || options.name || 'allocations';
|
||||
|
||||
var original = {};
|
||||
|
||||
for (var k in params) {
|
||||
original[k] = params[k];
|
||||
filters[k] = params[k];
|
||||
}
|
||||
|
||||
setupFilterList(filterKey, table, filterListElement);
|
||||
|
||||
/*
|
||||
* We have two separate API queries to make here:
|
||||
* a) Build Order Allocations
|
||||
* b) Sales Order Allocations
|
||||
*
|
||||
* We will let the call to inventreeTable take care of build orders,
|
||||
* and then load sales orders after that.
|
||||
*/
|
||||
table.inventreeTable({
|
||||
url: '{% url "api-build-item-list" %}',
|
||||
name: 'allocations',
|
||||
original: original,
|
||||
method: 'get',
|
||||
queryParams: filters,
|
||||
sidePagination: 'client',
|
||||
showColumns: false,
|
||||
onLoadSuccess: function(tableData) {
|
||||
|
||||
var query_params = params;
|
||||
|
||||
query_params.customer_detail = true;
|
||||
query_params.order_detail = true;
|
||||
|
||||
delete query_params.build_detail;
|
||||
|
||||
// Load sales order allocation data
|
||||
inventreeGet('{% url "api-so-allocation-list" %}', query_params, {
|
||||
success: function(data) {
|
||||
// Update table to include sales order data
|
||||
$(table).bootstrapTable('append', data);
|
||||
}
|
||||
});
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'order',
|
||||
title: '{% trans "Order" %}',
|
||||
formatter: function(value, row) {
|
||||
|
||||
var html = '';
|
||||
|
||||
if (row.build) {
|
||||
|
||||
// Add an icon for the part being built
|
||||
html += thumbnailImage(row.build_detail.part_detail.thumbnail, {
|
||||
title: row.build_detail.part_detail.full_name
|
||||
});
|
||||
|
||||
html += ' ';
|
||||
|
||||
html += renderLink(
|
||||
global_settings.BUILDORDER_REFERENCE_PREFIX + row.build_detail.reference,
|
||||
`/build/${row.build}/`
|
||||
);
|
||||
|
||||
html += makeIconBadge('fa-tools', '{% trans "Build Order" %}');
|
||||
} else if (row.order) {
|
||||
|
||||
// Add an icon for the customer
|
||||
html += thumbnailImage(row.customer_detail.thumbnail || row.customer_detail.image, {
|
||||
title: row.customer_detail.name,
|
||||
});
|
||||
|
||||
html += ' ';
|
||||
|
||||
html += renderLink(
|
||||
global_settings.SALESORDER_REFERENCE_PREFIX + row.order_detail.reference,
|
||||
`/order/sales-order/${row.order}/`
|
||||
);
|
||||
html += makeIconBadge('fa-truck', '{% trans "Sales Order" %}');
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
title: '{% trans "Description" %}',
|
||||
formatter: function(value, row) {
|
||||
if (row.order_detail) {
|
||||
return row.order_detail.description;
|
||||
} else if (row.build_detail) {
|
||||
return row.build_detail.title;
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
title: '{% trans "Order Status" %}',
|
||||
formatter: function(value, row) {
|
||||
if (row.build) {
|
||||
return buildStatusDisplay(row.build_detail.status);
|
||||
} else if (row.order) {
|
||||
return salesOrderStatusDisplay(row.order_detail.status);
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'quantity',
|
||||
title: '{% trans "Allocated Quantity" %}',
|
||||
formatter: function(value, row) {
|
||||
var text = value;
|
||||
var pk = row.stock_item || row.item;
|
||||
|
||||
if (pk) {
|
||||
var url = `/stock/item/${pk}/`;
|
||||
return renderLink(text, url);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display a table of stock locations
|
||||
*/
|
||||
|
@ -341,6 +341,15 @@ function getAvailableTableFilters(tableKey) {
|
||||
};
|
||||
}
|
||||
|
||||
if (tableKey == 'salesorderallocation') {
|
||||
return {
|
||||
outstanding: {
|
||||
type: 'bool',
|
||||
title: '{% trans "Outstanding" %}',
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (tableKey == 'salesorder') {
|
||||
return {
|
||||
status: {
|
||||
|
Reference in New Issue
Block a user