diff --git a/InvenTree/build/forms.py b/InvenTree/build/forms.py index db4188021d..eb276d52d4 100644 --- a/InvenTree/build/forms.py +++ b/InvenTree/build/forms.py @@ -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): """ Form for auto-allocation of stock to a build """ diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 8cf8b4538d..b82d9470dd 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -363,10 +363,22 @@ class Build(MPTTModel): return allocations @transaction.atomic - def unallocateStock(self): - """ Deletes all stock allocations for this build. """ + def unallocateStock(self, output=None): + """ + Deletes all stock allocations for this build. + + Args: + output: Specify which build output to delete allocations (optional) - BuildItem.objects.filter(build=self.id).delete() + """ + + allocations = BuildItem.objects.filter(build=self.pk) + + if output: + allocations = allocations.filter(install_into=output.pk) + + # Remove all the allocations + allocations.delete() @transaction.atomic def autoAllocate(self): @@ -682,6 +694,8 @@ class BuildItem(models.Model): def complete_allocation(self, user): + # TODO : This required much reworking!! + item = self.stock_item # Split the allocated stock if there are more available than allocated diff --git a/InvenTree/build/views.py b/InvenTree/build/views.py index 9797e67ca1..53c16333cd 100644 --- a/InvenTree/build/views.py +++ b/InvenTree/build/views.py @@ -148,11 +148,29 @@ class BuildUnallocate(AjaxUpdateView): """ model = Build - form_class = forms.ConfirmBuildForm + form_class = forms.UnallocateBuildForm ajax_form_title = _("Unallocate Stock") ajax_template_name = "build/unallocate.html" 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): build = self.get_object() @@ -160,13 +178,20 @@ class BuildUnallocate(AjaxUpdateView): 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 if confirm is False: form.errors['confirm'] = [_('Confirm unallocation of build stock')] form.non_field_errors = [_('Check the confirmation box')] else: - build.unallocateStock() + build.unallocateStock(output=output) valid = True data = { diff --git a/InvenTree/templates/js/build.js b/InvenTree/templates/js/build.js index 157498bf84..ab1741d4bb 100644 --- a/InvenTree/templates/js/build.js +++ b/InvenTree/templates/js/build.js @@ -39,6 +39,10 @@ function makeBuildOutputActionButtons(output, buildId) { var outputId = output.pk; var panel = `#allocation-panel-${outputId}`; + + function reloadTable() { + $(panel).find(`#allocation-table-${outputId}`).bootstrapTable('refresh'); + } // Find the div where the buttons will be displayed var buildActions = $(panel).find(`#output-actions-${outputId}`); @@ -51,6 +55,13 @@ function makeBuildOutputActionButtons(output, buildId) { '{% 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 html += makeIconButton( '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) html += makeIconButton( - 'fa-times-circle icon-red', 'button-output-cancel', outputId, - '{% trans "Cancel build output" %}', + 'fa-times-circle icon-red', 'button-output-unallocate', outputId, + '{% 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) @@ -87,8 +104,16 @@ function makeBuildOutputActionButtons(output, buildId) { // TODO }); - $(panel).find(`#button-output-cancel-${outputId}`).click(function() { - // TODO + $(panel).find(`#button-output-unallocate-${outputId}`).click(function() { + launchModalForm( + `/build/${buildId}/unallocate/`, + { + success: reloadTable, + data: { + output: outputId, + } + } + ); }); }