mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #2574 from SchrodingersGat/allocation-tab
Allocation tab
This commit is contained in:
commit
0ea0edf1bb
@ -846,6 +846,12 @@ class SOAllocationList(generics.ListAPIView):
|
||||
if order is not None:
|
||||
queryset = queryset.filter(line__order=order)
|
||||
|
||||
# Filter by "stock item"
|
||||
item = params.get('item', params.get('stock_item', None))
|
||||
|
||||
if item is not None:
|
||||
queryset = queryset.filter(item=item)
|
||||
|
||||
# Filter by "outstanding" order status
|
||||
outstanding = params.get('outstanding', None)
|
||||
|
||||
@ -865,7 +871,6 @@ class SOAllocationList(generics.ListAPIView):
|
||||
|
||||
# Default filterable fields
|
||||
filter_fields = [
|
||||
'item',
|
||||
]
|
||||
|
||||
|
||||
|
@ -37,6 +37,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-hidden' id='panel-allocations'>
|
||||
<div class='panel-heading'>
|
||||
<div class='d-flex flex-wrap'>
|
||||
<h4>{% trans "Part Stock Allocations" %}</h4>
|
||||
{% include "spacer.html" %}
|
||||
</div>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='allocations-button-toolbar'>
|
||||
<div class='btn-group' role='group'>
|
||||
{% include "filter_list.html" with id="allocations" %}
|
||||
</div>
|
||||
</div>
|
||||
<table class='table table-striped table-condensed' data-toolbar='#allocations-button-toolbar' id='part-allocation-table'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-hidden' id='panel-test-templates'>
|
||||
<div class='panel-heading'>
|
||||
<div class='d-flex flex-wrap'>
|
||||
@ -631,6 +648,19 @@
|
||||
{% endif %}
|
||||
});
|
||||
|
||||
// Load the "allocations" tab
|
||||
onPanelLoad('allocations', function() {
|
||||
|
||||
loadStockAllocationTable(
|
||||
$("#part-allocation-table"),
|
||||
{
|
||||
params: {
|
||||
part: {{ part.pk }},
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Load the "related parts" tab
|
||||
onPanelLoad("related-parts", function() {
|
||||
|
||||
|
@ -27,6 +27,10 @@
|
||||
{% endif %}
|
||||
{% trans "Pricing" as text %}
|
||||
{% include "sidebar_item.html" with label="pricing" text=text icon="fa-dollar-sign" %}
|
||||
{% if part.salable or part.component %}
|
||||
{% trans "Allocations" as text %}
|
||||
{% include "sidebar_item.html" with label="allocations" text=text icon="fa-bookmark" %}
|
||||
{% endif %}
|
||||
{% if part.purchaseable and roles.purchase_order.view %}
|
||||
{% trans "Suppliers" as text %}
|
||||
{% include "sidebar_item.html" with label="suppliers" text=text icon="fa-building" %}
|
||||
|
@ -43,9 +43,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-hidden' id='panel-allocations'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Stock Item Allocations" %}</h4>
|
||||
{% include "spacer.html" %}
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='allocations-button-toolbar'>
|
||||
<div class='btn-group' role='group'>
|
||||
{% include "filter_list.html" with id="allocations" %}
|
||||
</div>
|
||||
</div>
|
||||
<table class='table table-striped table-condensed' data-toolbar='#allocatoins-button-toolbar' id='stock-allocation-table'></table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class='panel panel-hidden' id='panel-children'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Child Stock Items" %}</h4>
|
||||
{% include "spacer.html" %}
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if item.child_count > 0 %}
|
||||
@ -151,6 +168,19 @@
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
// Load the "allocations" tab
|
||||
onPanelLoad('allocations', function() {
|
||||
|
||||
loadStockAllocationTable(
|
||||
$("#stock-allocation-table"),
|
||||
{
|
||||
params: {
|
||||
stock_item: {{ item.pk }},
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#stock-item-install').click(function() {
|
||||
|
||||
launchModalForm(
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
{% trans "Stock Tracking" as text %}
|
||||
{% include "sidebar_item.html" with label='history' text=text icon="fa-history" %}
|
||||
{% if item.part.salable or item.part.component %}
|
||||
{% trans "Allocations" as text %}
|
||||
{% include "sidebar_item.html" with label="allocations" text=text icon="fa-bookmark" %}
|
||||
{% endif %}
|
||||
{% if item.part.trackable %}
|
||||
{% trans "Test Data" as text %}
|
||||
{% include "sidebar_item.html" with label='test-data' text=text icon="fa-vial" %}
|
||||
|
@ -47,6 +47,7 @@
|
||||
exportStock,
|
||||
findStockItemBySerialNumber,
|
||||
loadInstalledInTable,
|
||||
loadStockAllocationTable,
|
||||
loadStockLocationTable,
|
||||
loadStockTable,
|
||||
loadStockTestResultsTable,
|
||||
@ -2203,6 +2204,125 @@ 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.order_detail = true;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
html += renderLink(
|
||||
global_settings.SALESORDER_REFERENCE_PREFIX + row.order,
|
||||
`/order/so/${row.order}/`
|
||||
);
|
||||
|
||||
html += makeIconBadge('fa-truck', '{% trans "Sales Order" %}');
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
{
|
||||
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
|
||||
*/
|
||||
@ -2252,7 +2372,6 @@ function loadStockLocationTable(table, options) {
|
||||
method: 'get',
|
||||
url: options.url || '{% url "api-location-list" %}',
|
||||
queryParams: filters,
|
||||
sidePagination: 'server',
|
||||
name: 'location',
|
||||
original: original,
|
||||
showColumns: true,
|
||||
|
Loading…
Reference in New Issue
Block a user