diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index ca3b202317..43308ad9ba 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -518,9 +518,25 @@ class Build(InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNo return True + @transaction.atomic + def complete_allocations(self, user): + """Complete all stock allocations for this build order. + + - This function is called when a build order is completed + """ + # Remove untracked allocated stock + self.subtract_allocated_stock(user) + + # Ensure that there are no longer any BuildItem objects + # which point to this Build Order + self.allocated_stock.delete() + @transaction.atomic def complete_build(self, user): """Mark this build as complete.""" + + import build.tasks + if self.incomplete_count > 0: return @@ -529,12 +545,12 @@ class Build(InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNo self.status = BuildStatus.COMPLETE.value self.save() - # Remove untracked allocated stock - self.subtract_allocated_stock(user) - - # Ensure that there are no longer any BuildItem objects - # which point to this Build Order - self.allocated_stock.delete() + # Offload task to complete build allocations + InvenTree.tasks.offload_task( + build.tasks.complete_build_allocations, + self.pk, + user.pk if user else None + ) # Register an event trigger_event('build.completed', id=self.pk) diff --git a/InvenTree/build/tasks.py b/InvenTree/build/tasks.py index 46fd97cab4..472b8c5166 100644 --- a/InvenTree/build/tasks.py +++ b/InvenTree/build/tasks.py @@ -4,6 +4,7 @@ from datetime import datetime, timedelta from decimal import Decimal import logging +from django.contrib.auth.models import User from django.utils.translation import gettext_lazy as _ from django.template.loader import render_to_string @@ -24,6 +25,27 @@ import part.models as part_models logger = logging.getLogger('inventree') +def complete_build_allocations(build_id: int, user_id: int): + """Complete build allocations for a specified BuildOrder.""" + + build_order = build.models.Build.objects.filter(pk=build_id).first() + + if user_id: + try: + user = User.objects.get(pk=user_id) + except User.DoesNotExist: + logger.warning("Could not complete build allocations for BuildOrder <%s> - User does not exist", build_id) + return + else: + user = None + + if not build_order: + logger.warning("Could not complete build allocations for BuildOrder <%s> - BuildOrder does not exist", build_id) + return + + build_order.complete_allocations(user) + + def update_build_order_lines(bom_item_pk: int): """Update all BuildOrderLineItem objects which reference a particular BomItem.