mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-11-04 07:05:41 +00:00 
			
		
		
		
	Build can be "unallocated" against a single build output
This commit is contained in:
		@@ -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 """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 = {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user