From 2499e97928b674c28e4218a21fbd15e4531ad18d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:39:15 +1100 Subject: [PATCH] Bug fix for allocating items to build (#6532) (#6533) * Bug fix for allocating items to build - Handle case where allocated quantity is less than 1 - Add unit tests - Closes https://github.com/inventree/InvenTree/issues/6145 * Remove debug messgae (cherry picked from commit a310437dc71ae08af30c8079532e425bc1838c7d) Co-authored-by: Oliver --- InvenTree/build/serializers.py | 26 ++++++++++------- InvenTree/build/test_api.py | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/InvenTree/build/serializers.py b/InvenTree/build/serializers.py index 5d19244927..c50afa9503 100644 --- a/InvenTree/build/serializers.py +++ b/InvenTree/build/serializers.py @@ -904,18 +904,24 @@ class BuildAllocationSerializer(serializers.Serializer): if build_line.bom_item.consumable: continue + params = { + "build_line": build_line, + "stock_item": stock_item, + "install_into": output, + } + try: - # Create a new BuildItem to allocate stock - build_item, created = BuildItem.objects.get_or_create( - build_line=build_line, - stock_item=stock_item, - install_into=output, - ) - if created: - build_item.quantity = quantity - else: + if build_item := BuildItem.objects.filter(**params).first(): + # Find an existing BuildItem for this stock item + # If it exists, increase the quantity build_item.quantity += quantity - build_item.save() + build_item.save() + else: + # Create a new BuildItem to allocate stock + build_item = BuildItem.objects.create( + quantity=quantity, + **params + ) except (ValidationError, DjangoValidationError) as exc: # Catch model errors and re-throw as DRF errors raise ValidationError(detail=serializers.as_serializer_error(exc)) diff --git a/InvenTree/build/test_api.py b/InvenTree/build/test_api.py index 0d5e834cbd..6f7ad83e14 100644 --- a/InvenTree/build/test_api.py +++ b/InvenTree/build/test_api.py @@ -822,6 +822,58 @@ class BuildAllocationTest(BuildAPITest): allocation.refresh_from_db() self.assertEqual(allocation.quantity, 5000) + def test_fractional_allocation(self): + """Test allocation of a fractional quantity of stock items. + + Ref: https://github.com/inventree/InvenTree/issues/6508 + """ + + si = StockItem.objects.get(pk=2) + + # Find line item + line = self.build.build_lines.all().filter(bom_item__sub_part=si.part).first() + + # Test a fractional quantity when the *available* quantity is greater than 1 + si.quantity = 100 + si.save() + + response = self.post( + self.url, + { + "items": [ + { + "build_line": line.pk, + "stock_item": si.pk, + "quantity": 0.1616, + } + ] + }, + expected_code=201 + ) + + # Test a fractional quantity when the *available* quantity is less than 1 + si = StockItem.objects.create( + part=si.part, + quantity=0.3159, + tree_id=0, + level=0, + lft=0, rght=0 + ) + + response = self.post( + self.url, + { + "items": [ + { + "build_line": line.pk, + "stock_item": si.pk, + "quantity": 0.1616, + } + ] + }, + expected_code=201, + ) + class BuildOverallocationTest(BuildAPITest): """Unit tests for over allocation of stock items against a build order.