From 0e8563ebee8163af280baa2e461ac920b2a20590 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 21 Dec 2022 21:22:59 +1100 Subject: [PATCH] Control build allocation of optional BOM items (#4090) * Control build allocation of optional BOM items - User can specify in form whether optional items are allocated - Default = False * Updated unit test --- InvenTree/build/models.py | 5 +++++ InvenTree/build/serializers.py | 8 ++++++++ InvenTree/build/test_build.py | 11 +++++++---- InvenTree/templates/js/translated/build.js | 3 +++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index c2bc02cf85..1845712a1b 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -832,6 +832,7 @@ class Build(MPTTModel, ReferenceIndexingMixin): exclude_location = kwargs.get('exclude_location', None) interchangeable = kwargs.get('interchangeable', False) substitutes = kwargs.get('substitutes', True) + optional_items = kwargs.get('optional_items', False) def stock_sort(item, bom_item, variant_parts): if item.part == bom_item.sub_part: @@ -848,6 +849,10 @@ class Build(MPTTModel, ReferenceIndexingMixin): # Do not auto-allocate stock to consumable BOM items continue + if bom_item.optional and not optional_items: + # User has specified that optional_items are to be ignored + continue + variant_parts = bom_item.sub_part.get_descendants(include_self=False) unallocated_quantity = self.unallocated_quantity(bom_item) diff --git a/InvenTree/build/serializers.py b/InvenTree/build/serializers.py index ea64cb800c..48d8b92368 100644 --- a/InvenTree/build/serializers.py +++ b/InvenTree/build/serializers.py @@ -812,6 +812,7 @@ class BuildAutoAllocationSerializer(serializers.Serializer): 'exclude_location', 'interchangeable', 'substitutes', + 'optional_items', ] location = serializers.PrimaryKeyRelatedField( @@ -844,6 +845,12 @@ class BuildAutoAllocationSerializer(serializers.Serializer): help_text=_('Allow allocation of substitute parts'), ) + optional_items = serializers.BooleanField( + default=False, + label=_('Optional Items'), + help_text=_('Allocate optional BOM items to build order'), + ) + def save(self): """Perform the auto-allocation step""" data = self.validated_data @@ -855,6 +862,7 @@ class BuildAutoAllocationSerializer(serializers.Serializer): exclude_location=data.get('exclude_location', None), interchangeable=data['interchangeable'], substitutes=data['substitutes'], + optional_items=data['optional_items'], ) diff --git a/InvenTree/build/test_build.py b/InvenTree/build/test_build.py index 6561e08903..38c20c331b 100644 --- a/InvenTree/build/test_build.py +++ b/InvenTree/build/test_build.py @@ -82,7 +82,8 @@ class BuildTestBase(TestCase): self.bom_item_2 = BomItem.objects.create( part=self.assembly, sub_part=self.sub_part_2, - quantity=3 + quantity=3, + optional=True ) # sub_part_3 is trackable! @@ -626,6 +627,7 @@ class AutoAllocationTests(BuildTestBase): self.build.auto_allocate_stock( interchangeable=True, substitutes=False, + optional_items=True, ) self.assertFalse(self.build.are_untracked_parts_allocated()) @@ -646,17 +648,18 @@ class AutoAllocationTests(BuildTestBase): # self.assertEqual(self.build.allocated_stock.count(), 8) self.assertEqual(self.build.unallocated_quantity(self.bom_item_1), 0) - self.assertEqual(self.build.unallocated_quantity(self.bom_item_2), 0) + self.assertEqual(self.build.unallocated_quantity(self.bom_item_2), 5.0) self.assertTrue(self.build.is_bom_item_allocated(self.bom_item_1)) - self.assertTrue(self.build.is_bom_item_allocated(self.bom_item_2)) + self.assertFalse(self.build.is_bom_item_allocated(self.bom_item_2)) def test_fully_auto(self): """We should be able to auto-allocate against a build in a single go""" self.build.auto_allocate_stock( interchangeable=True, - substitutes=True + substitutes=True, + optional_items=True, ) self.assertTrue(self.build.are_untracked_parts_allocated()) diff --git a/InvenTree/templates/js/translated/build.js b/InvenTree/templates/js/translated/build.js index 316ae03c2f..ce4d92dc29 100644 --- a/InvenTree/templates/js/translated/build.js +++ b/InvenTree/templates/js/translated/build.js @@ -2422,6 +2422,9 @@ function autoAllocateStockToBuild(build_id, bom_items=[], options={}) { substitutes: { value: true, }, + optional_items: { + value: false, + }, }; constructForm(`/api/build/${build_id}/auto-allocate/`, {