2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-30 04:26:44 +00:00

Build can be "unallocated" against a single build output

This commit is contained in:
Oliver Walters 2020-10-23 23:52:59 +11:00
parent fb7d9a7edf
commit a71a51b848
4 changed files with 92 additions and 9 deletions

View File

@ -46,6 +46,25 @@ class EditBuildForm(HelperForm):
] ]
class UnallocateBuildForm(HelperForm):
"""
Form for auto-de-allocation of stock from a build
"""
confirm = forms.BooleanField(required=False, help_text=_('Confirm unallocation of stock'))
output_id = forms.IntegerField(
required=False,
widget=forms.HiddenInput()
)
class Meta:
model = Build
fields = [
'confirm',
]
class ConfirmBuildForm(HelperForm): class ConfirmBuildForm(HelperForm):
""" Form for auto-allocation of stock to a build """ """ Form for auto-allocation of stock to a build """

View File

@ -363,10 +363,22 @@ class Build(MPTTModel):
return allocations return allocations
@transaction.atomic @transaction.atomic
def unallocateStock(self): def unallocateStock(self, output=None):
""" Deletes all stock allocations for this build. """ """
Deletes all stock allocations for this build.
BuildItem.objects.filter(build=self.id).delete() Args:
output: Specify which build output to delete allocations (optional)
"""
allocations = BuildItem.objects.filter(build=self.pk)
if output:
allocations = allocations.filter(install_into=output.pk)
# Remove all the allocations
allocations.delete()
@transaction.atomic @transaction.atomic
def autoAllocate(self): def autoAllocate(self):
@ -682,6 +694,8 @@ class BuildItem(models.Model):
def complete_allocation(self, user): def complete_allocation(self, user):
# TODO : This required much reworking!!
item = self.stock_item item = self.stock_item
# Split the allocated stock if there are more available than allocated # Split the allocated stock if there are more available than allocated

View File

@ -148,11 +148,29 @@ class BuildUnallocate(AjaxUpdateView):
""" """
model = Build model = Build
form_class = forms.ConfirmBuildForm form_class = forms.UnallocateBuildForm
ajax_form_title = _("Unallocate Stock") ajax_form_title = _("Unallocate Stock")
ajax_template_name = "build/unallocate.html" ajax_template_name = "build/unallocate.html"
form_required = 'build.change' form_required = 'build.change'
def get_initial(self):
initials = super().get_initial()
# Pointing to a particular build output?
output = self.get_param('output')
if output:
try:
output = StockItem.objects.get(pk=output)
except (ValueError, StockItem.DoesNotExist):
output = None
if output:
initials['output_id'] = output.pk
return initials
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
build = self.get_object() build = self.get_object()
@ -160,13 +178,20 @@ class BuildUnallocate(AjaxUpdateView):
confirm = request.POST.get('confirm', False) confirm = request.POST.get('confirm', False)
output_id = request.POST.get('output_id', None)
try:
output = StockItem.objects.get(pk=output_id)
except (ValueError, StockItem.DoesNotExist):
output = 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() build.unallocateStock(output=output)
valid = True valid = True
data = { data = {

View File

@ -40,6 +40,10 @@ function makeBuildOutputActionButtons(output, buildId) {
var panel = `#allocation-panel-${outputId}`; var panel = `#allocation-panel-${outputId}`;
function reloadTable() {
$(panel).find(`#allocation-table-${outputId}`).bootstrapTable('refresh');
}
// Find the div where the buttons will be displayed // Find the div where the buttons will be displayed
var buildActions = $(panel).find(`#output-actions-${outputId}`); var buildActions = $(panel).find(`#output-actions-${outputId}`);
@ -51,6 +55,13 @@ function makeBuildOutputActionButtons(output, buildId) {
'{% trans "Allocate stock items to this output" %}' '{% trans "Allocate stock items to this output" %}'
); );
if (output.quantity > 1) {
html += makeIconButton(
'fa-random icon-blue', 'button-output-split', outputId,
'{% trans "Split build output into separate items" %}',
);
}
// Add a button to "complete" the particular build output // Add a button to "complete" the particular build output
html += makeIconButton( html += makeIconButton(
'fa-tools icon-green', 'button-output-complete', outputId, 'fa-tools icon-green', 'button-output-complete', outputId,
@ -59,8 +70,14 @@ function makeBuildOutputActionButtons(output, buildId) {
// Add a button to "cancel" the particular build output (unallocate) // Add a button to "cancel" the particular build output (unallocate)
html += makeIconButton( html += makeIconButton(
'fa-times-circle icon-red', 'button-output-cancel', outputId, 'fa-times-circle icon-red', 'button-output-unallocate', outputId,
'{% trans "Cancel build output" %}', '{% trans "Unallocate stock from build output" %}',
);
// Add a button to "delete" the particular build output
html += makeIconButton(
'fa-trash-alt icon-red', 'button-output-delete', outputId,
'{% trans "Delete build output" %}',
); );
// Add a button to "destroy" the particular build output (mark as damaged, scrap) // Add a button to "destroy" the particular build output (mark as damaged, scrap)
@ -87,8 +104,16 @@ function makeBuildOutputActionButtons(output, buildId) {
// TODO // TODO
}); });
$(panel).find(`#button-output-cancel-${outputId}`).click(function() { $(panel).find(`#button-output-unallocate-${outputId}`).click(function() {
// TODO launchModalForm(
`/build/${buildId}/unallocate/`,
{
success: reloadTable,
data: {
output: outputId,
}
}
);
}); });
} }