mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add ability to specify "source location" for stock allocations
- Defaults to build.take_from - User-selectable at run-time - Selected value affects select2 query
This commit is contained in:
parent
76668b0d54
commit
563deb5ffa
@ -317,6 +317,9 @@ var buildInfo = {
|
|||||||
quantity: {{ build.quantity }},
|
quantity: {{ build.quantity }},
|
||||||
completed: {{ build.completed }},
|
completed: {{ build.completed }},
|
||||||
part: {{ build.part.pk }},
|
part: {{ build.part.pk }},
|
||||||
|
{% if build.take_from %}
|
||||||
|
source_location: {{ build.take_from.pk }},
|
||||||
|
{% endif %}
|
||||||
};
|
};
|
||||||
|
|
||||||
{% for item in build.incomplete_outputs %}
|
{% for item in build.incomplete_outputs %}
|
||||||
@ -412,13 +415,6 @@ $('#edit-notes').click(function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var buildInfo = {
|
|
||||||
pk: {{ build.pk }},
|
|
||||||
quantity: {{ build.quantity }},
|
|
||||||
completed: {{ build.completed }},
|
|
||||||
part: {{ build.part.pk }},
|
|
||||||
};
|
|
||||||
|
|
||||||
{% if build.has_untracked_bom_items %}
|
{% if build.has_untracked_bom_items %}
|
||||||
// Load allocation table for un-tracked parts
|
// Load allocation table for un-tracked parts
|
||||||
loadBuildOutputAllocationTable(buildInfo, null);
|
loadBuildOutputAllocationTable(buildInfo, null);
|
||||||
@ -453,6 +449,9 @@ $("#btn-auto-allocate").on('click', function() {
|
|||||||
{{ build.part.pk }},
|
{{ build.part.pk }},
|
||||||
incomplete_bom_items,
|
incomplete_bom_items,
|
||||||
{
|
{
|
||||||
|
{% if build.take_from %}
|
||||||
|
source_location: {{ build.take_from.pk }},
|
||||||
|
{% endif %}
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
$('#allocation-table-untracked').bootstrapTable('refresh');
|
$('#allocation-table-untracked').bootstrapTable('refresh');
|
||||||
}
|
}
|
||||||
@ -479,6 +478,9 @@ $('#allocate-selected-items').click(function() {
|
|||||||
{{ build.part.pk }},
|
{{ build.part.pk }},
|
||||||
bom_items,
|
bom_items,
|
||||||
{
|
{
|
||||||
|
{% if build.take_from %}
|
||||||
|
source_location: {{ build.take_from.pk }},
|
||||||
|
{% endif %}
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
$('#allocation-table-untracked').bootstrapTable('refresh');
|
$('#allocation-table-untracked').bootstrapTable('refresh');
|
||||||
}
|
}
|
||||||
|
@ -821,7 +821,7 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
if loc_id is not None:
|
if loc_id is not None:
|
||||||
|
|
||||||
# Filter by 'null' location (i.e. top-level items)
|
# Filter by 'null' location (i.e. top-level items)
|
||||||
if isNull(loc_id):
|
if isNull(loc_id) and not cascade:
|
||||||
queryset = queryset.filter(location=None)
|
queryset = queryset.filter(location=None)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
@ -172,6 +172,7 @@ function makeBuildOutputActionButtons(output, buildInfo, lines) {
|
|||||||
partId,
|
partId,
|
||||||
bom_items,
|
bom_items,
|
||||||
{
|
{
|
||||||
|
source_location: buildInfo.source_location,
|
||||||
output: outputId,
|
output: outputId,
|
||||||
success: reloadTable,
|
success: reloadTable,
|
||||||
}
|
}
|
||||||
@ -407,6 +408,7 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
|||||||
row,
|
row,
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
|
source_location: buildInfo.source_location,
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
$(table).bootstrapTable('refresh');
|
$(table).bootstrapTable('refresh');
|
||||||
},
|
},
|
||||||
@ -824,7 +826,8 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
|||||||
* - bom_items: A list of BomItem objects to be allocated
|
* - bom_items: A list of BomItem objects to be allocated
|
||||||
*
|
*
|
||||||
* options:
|
* options:
|
||||||
* - outputId: ID / PK of the associated build output (or null for untracked items)
|
* - output: ID / PK of the associated build output (or null for untracked items)
|
||||||
|
* - source_location: ID / PK of the top-level StockLocation to take parts from (or null)
|
||||||
*/
|
*/
|
||||||
function allocateStockToBuild(build_id, part_id, bom_items, options={}) {
|
function allocateStockToBuild(build_id, part_id, bom_items, options={}) {
|
||||||
|
|
||||||
@ -837,6 +840,8 @@ function allocateStockToBuild(build_id, part_id, bom_items, options={}) {
|
|||||||
sub_part_trackable: output_id != null
|
sub_part_trackable: output_id != null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var source_location = options.source_location;
|
||||||
|
|
||||||
function renderBomItemRow(bom_item, quantity) {
|
function renderBomItemRow(bom_item, quantity) {
|
||||||
|
|
||||||
var pk = bom_item.pk;
|
var pk = bom_item.pk;
|
||||||
@ -936,8 +941,22 @@ function allocateStockToBuild(build_id, part_id, bom_items, options={}) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var html = ``;
|
||||||
|
|
||||||
|
// Render a "take from" input
|
||||||
|
html += constructField(
|
||||||
|
'take_from',
|
||||||
|
{
|
||||||
|
type: 'related field',
|
||||||
|
label: '{% trans "Source Location" %}',
|
||||||
|
help_text: '{% trans "Select source location (leave blank to take from all locations)" %}',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
// Create table of parts
|
// Create table of parts
|
||||||
var html = `
|
html += `
|
||||||
<table class='table table-striped table-condensed' id='stock-allocation-table'>
|
<table class='table table-striped table-condensed' id='stock-allocation-table'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -964,7 +983,26 @@ function allocateStockToBuild(build_id, part_id, bom_items, options={}) {
|
|||||||
title: '{% trans "Allocate Stock Items to Build Order" %}',
|
title: '{% trans "Allocate Stock Items to Build Order" %}',
|
||||||
afterRender: function(fields, options) {
|
afterRender: function(fields, options) {
|
||||||
|
|
||||||
// Initialize select2 fields
|
var take_from_field = {
|
||||||
|
name: 'take_from',
|
||||||
|
model: 'stocklocation',
|
||||||
|
api_url: '{% url "api-location-list" %}',
|
||||||
|
required: false,
|
||||||
|
type: 'related field',
|
||||||
|
value: source_location,
|
||||||
|
noResults: function(query) {
|
||||||
|
return '{% trans "No matching stock locations" %}';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize "take from" field
|
||||||
|
initializeRelatedField(
|
||||||
|
take_from_field,
|
||||||
|
null,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialize stock item fields
|
||||||
bom_items.forEach(function(bom_item) {
|
bom_items.forEach(function(bom_item) {
|
||||||
initializeRelatedField(
|
initializeRelatedField(
|
||||||
{
|
{
|
||||||
@ -981,6 +1019,21 @@ function allocateStockToBuild(build_id, part_id, bom_items, options={}) {
|
|||||||
render_part_detail: false,
|
render_part_detail: false,
|
||||||
render_location_detail: true,
|
render_location_detail: true,
|
||||||
auto_fill: true,
|
auto_fill: true,
|
||||||
|
adjustFilters: function(filters) {
|
||||||
|
// Restrict query to the selected location
|
||||||
|
var location = getFormFieldValue(
|
||||||
|
'take_from',
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
modal: options.modal,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
filters.location = location;
|
||||||
|
filters.cascade = true;
|
||||||
|
|
||||||
|
return filters;
|
||||||
|
},
|
||||||
noResults: function(query) {
|
noResults: function(query) {
|
||||||
return '{% trans "No matching stock items" %}';
|
return '{% trans "No matching stock items" %}';
|
||||||
}
|
}
|
||||||
@ -990,6 +1043,13 @@ function allocateStockToBuild(build_id, part_id, bom_items, options={}) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add callback to "clear" button for take_from field
|
||||||
|
addClearCallback(
|
||||||
|
"take_from",
|
||||||
|
take_from_field,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
|
||||||
// Add button callbacks
|
// Add button callbacks
|
||||||
$(options.modal).find('.button-row-remove').click(function() {
|
$(options.modal).find('.button-row-remove').click(function() {
|
||||||
var pk = $(this).attr('pk');
|
var pk = $(this).attr('pk');
|
||||||
|
@ -728,10 +728,17 @@ function updateFieldValues(fields, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the value of a named field
|
||||||
|
*/
|
||||||
function updateFieldValue(name, value, field, options) {
|
function updateFieldValue(name, value, field, options) {
|
||||||
var el = $(options.modal).find(`#id_${name}`);
|
var el = $(options.modal).find(`#id_${name}`);
|
||||||
|
|
||||||
|
if (!el) {
|
||||||
|
console.log(`WARNING: updateFieldValue could not find field '${name}'`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (field.type) {
|
switch (field.type) {
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
el.prop('checked', value);
|
el.prop('checked', value);
|
||||||
@ -1105,7 +1112,14 @@ function addClearCallbacks(fields, options) {
|
|||||||
|
|
||||||
function addClearCallback(name, field, options) {
|
function addClearCallback(name, field, options) {
|
||||||
|
|
||||||
$(options.modal).find(`#clear_${name}`).click(function() {
|
var el = $(options.modal).find(`#clear_${name}`);
|
||||||
|
|
||||||
|
if (!el) {
|
||||||
|
console.log(`WARNING: addClearCallback could not find field '${name}'`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
el.click(function() {
|
||||||
updateFieldValue(name, null, field, options);
|
updateFieldValue(name, null, field, options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1333,6 +1347,11 @@ function initializeRelatedField(field, fields, options) {
|
|||||||
query.offset = offset;
|
query.offset = offset;
|
||||||
query.limit = pageSize;
|
query.limit = pageSize;
|
||||||
|
|
||||||
|
// Allow custom run-time filter augmentation
|
||||||
|
if ("adjustFilters" in field) {
|
||||||
|
query = field.adjustFilters(query);
|
||||||
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
},
|
},
|
||||||
processResults: function(response) {
|
processResults: function(response) {
|
||||||
@ -1453,7 +1472,6 @@ function initializeRelatedField(field, fields, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user