Assign sorting priority when allocating parts to a build order

1. Direct match parts
2. Variant parts
3. Any other parts (e.g. substitute parts)
This commit is contained in:
Oliver 2022-03-04 15:52:42 +11:00
parent 434f563a41
commit 71cd6c93d1
2 changed files with 41 additions and 6 deletions

View File

@ -848,6 +848,9 @@ class Build(MPTTModel, ReferenceIndexingMixin):
# Get a list of all 'untracked' BOM items
for bom_item in self.untracked_bom_items:
variant_parts = bom_item.sub_part.get_descendants(include_self=False)
substitute_parts = [p for p in bom_item.substitutes.all()]
unallocated_quantity = self.unallocated_quantity(bom_item)
if unallocated_quantity <= 0:
@ -873,10 +876,28 @@ class Build(MPTTModel, ReferenceIndexingMixin):
sublocations = location.get_descendants(include_self=True)
available_stock = available_stock.filter(location__in=[loc for loc in sublocations])
if available_stock.count() == 0:
"""
Next, we sort the available stock items with the following priority:
1. Direct part matches (+1)
2. Variant part matches (+2)
3. Substitute part matches (+3)
This ensures that allocation priority is first given to "direct" parts
"""
def stock_sort(item):
if item.part == bom_item.sub_part:
return 1
elif item.part in variant_parts:
return 2
else:
return 3
available_stock = sorted(available_stock, key=stock_sort)
if len(available_stock) == 0:
# No stock items are available
continue
elif available_stock.count() == 1 or interchangeable:
elif len(available_stock) == 1 or interchangeable:
# Either there is only a single stock item available,
# or all items are "interchangeable" and we don't care where we take stock from

View File

@ -1850,14 +1850,28 @@ function allocateStockToBuild(build_id, part_id, bom_items, options={}) {
*/
function autoAllocateStockToBuild(build_id, bom_items=[], options={}) {
var html = '';
var html = `
<div class='alert alert-block alert-info'>
<strong>{% trans "Automatic Stock Allocation" %}</strong><br>
{% trans "Stock items will be automatically allocated to this build order, according to the provided guidelines" %}:
<ul>
<li>{% trans "If a location is specifed, stock will only be allocated from that location" %}</li>
<li>{% trans "If stock is considered interchangeable, it will be allocated from the first location it is found" %}</li>
<li>{% trans "If substitute stock is allowed, it will be used where stock of the primary part cannot be found" %}</li>
</ul>
</div>
`;
var fields = {
location: {
value: options.location,
},
interchangeable: {},
substitutes: {},
interchangeable: {
value: true,
},
substitutes: {
value: true,
},
}
constructForm(`/api/build/${build_id}/auto-allocate/`, {
@ -1867,7 +1881,7 @@ function autoAllocateStockToBuild(build_id, bom_items=[], options={}) {
confirm: true,
preFormContent: html,
onSuccess: function(response) {
// TODO - Reload the allocation table
$('#allocation-table-untracked').bootstrapTable('refresh');
}
});
}