Unallocate stock against a particular line item

This commit is contained in:
Oliver Walters 2020-10-24 13:15:13 +11:00
parent b7e7543be6
commit a3265ef9fd
4 changed files with 69 additions and 6 deletions

View File

@ -81,6 +81,11 @@ class UnallocateBuildForm(HelperForm):
widget=forms.HiddenInput() widget=forms.HiddenInput()
) )
part_id = forms.IntegerField(
required=False,
widget=forms.HiddenInput(),
)
class Meta: class Meta:
model = Build model = Build
fields = [ fields = [

View File

@ -363,7 +363,7 @@ class Build(MPTTModel):
return allocations return allocations
@transaction.atomic @transaction.atomic
def unallocateStock(self, output=None): def unallocateStock(self, output=None, part=None):
""" """
Deletes all stock allocations for this build. Deletes all stock allocations for this build.
@ -377,6 +377,9 @@ class Build(MPTTModel):
if output: if output:
allocations = allocations.filter(install_into=output.pk) allocations = allocations.filter(install_into=output.pk)
if part:
allocations = allocations.filter(stock_item__part=part)
# Remove all the allocations # Remove all the allocations
allocations.delete() allocations.delete()

View File

@ -218,6 +218,12 @@ class BuildUnallocate(AjaxUpdateView):
if output: if output:
initials['output_id'] = output initials['output_id'] = output
# Pointing to a particular part?
part = self.get_param('part')
if part:
initials['part_id'] = part
return initials return initials
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
@ -234,13 +240,20 @@ class BuildUnallocate(AjaxUpdateView):
except (ValueError, StockItem.DoesNotExist): except (ValueError, StockItem.DoesNotExist):
output = None output = None
part_id = request.POST.get('part_id', None)
try:
part = Part.objects.get(pk=part_id)
except (ValueError, Part.DoesNotExist):
part = None
valid = False valid = False
if confirm is False: if confirm is False:
form.errors['confirm'] = [_('Confirm unallocation of build stock')] form.errors['confirm'] = [_('Confirm unallocation of build stock')]
form.non_field_errors = [_('Check the confirmation box')] form.non_field_errors = [_('Check the confirmation box')]
else: else:
build.unallocateStock(output=output) build.unallocateStock(output=output, part=part)
valid = True valid = True
data = { data = {

View File

@ -160,6 +160,12 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
$(table).bootstrapTable('refresh'); $(table).bootstrapTable('refresh');
} }
function requiredQuantity(row) {
// Return the requied quantity for a given row
return row.quantity * output.quantity;
}
function sumAllocations(row) { function sumAllocations(row) {
// Calculat total allocations for a given row // Calculat total allocations for a given row
if (!row.allocations) { if (!row.allocations) {
@ -185,8 +191,8 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
var pk = $(this).attr('pk'); var pk = $(this).attr('pk');
// Extract row data from the table // Extract row data from the table
var idx = $(this).closest('tr').attr('data-index'); //var idx = $(this).closest('tr').attr('data-index');
var row = $(table).bootstrapTable('getData')[idx]; //var row = $(table).bootstrapTable('getData')[idx];
// Launch form to allocate new stock against this output // Launch form to allocate new stock against this output
launchModalForm("{% url 'build-item-create' %}", { launchModalForm("{% url 'build-item-create' %}", {
@ -209,6 +215,36 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
] ]
}); });
}); });
// Callback for 'build' button
$(table).find('.button-build').click(function() {
var pk = $(this).attr('pk');
// Launch form to create a new build order
launchModalForm('{% url "build-create" %}', {
follow: true,
data: {
part: pk,
parent: buildId,
quantity: 123, // TODO - Fix this quantity!
}
});
});
// Callback for 'unallocate' button
$(table).find('.button-unallocate').click(function() {
var pk = $(this).attr('pk');
launchModalForm(`/build/${buildId}/unallocate/`,
{
success: reloadTable,
data: {
output: outputId,
part: pk,
}
}
);
});
} }
// Load table of BOM items // Load table of BOM items
@ -423,6 +459,10 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
title: '{% trans "Quantity Per" %}', title: '{% trans "Quantity Per" %}',
sortable: true, sortable: true,
}, },
{
field: 'sub_part_detail.stock',
title: '{% trans "Available" %}',
},
{ {
field: 'allocated', field: 'allocated',
title: '{% trans "Allocated" %}', title: '{% trans "Allocated" %}',
@ -436,7 +476,7 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
}); });
} }
var required = row.quantity * output.quantity; var required = requiredQuantity(row);
return makeProgressBar(allocated, required); return makeProgressBar(allocated, required);
}, },
@ -465,7 +505,7 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
var html = `<div class='btn-group float-right' role='group'>`; var html = `<div class='btn-group float-right' role='group'>`;
if (row.sub_part_detail.assembly) { if (row.sub_part_detail.assembly) {
html += makeIconButton('fa-tools icon-blue', 'button-build', row.sub_part, '{% trans "Build stock" %}', {disabled: true}); html += makeIconButton('fa-tools icon-blue', 'button-build', row.sub_part, '{% trans "Build stock" %}');
} }
if (row.sub_part_detail.purchaseable) { if (row.sub_part_detail.purchaseable) {
@ -474,6 +514,8 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
html += makeIconButton('fa-sign-in-alt icon-green', 'button-add', row.sub_part, '{% trans "Allocate stock" %}'); html += makeIconButton('fa-sign-in-alt icon-green', 'button-add', row.sub_part, '{% trans "Allocate stock" %}');
html += makeIconButton('fa-times-circle icon-red', 'button-unallocate', row.sub_part, '{% trans "Unallocate stock" %}');
html += '</div>'; html += '</div>';
return html; return html;