mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 13:15:43 +00:00 
			
		
		
		
	Allow stock items to be reallocated for build items (#5693)
* Allow stock items to be reallocated for build items * Refactor create check * Fix quantity calculation, Add tests
This commit is contained in:
		| @@ -866,10 +866,6 @@ class BuildAllocationItemSerializer(serializers.Serializer): | ||||
|                 'output': _('Build output cannot be specified for allocation of untracked parts'), | ||||
|             }) | ||||
|  | ||||
|         # Check if this allocation would be unique | ||||
|         if BuildItem.objects.filter(build_line=build_line, stock_item=stock_item, install_into=output).exists(): | ||||
|             raise ValidationError(_('This stock item has already been allocated to this build output')) | ||||
|  | ||||
|         return data | ||||
|  | ||||
|  | ||||
| @@ -914,12 +910,16 @@ class BuildAllocationSerializer(serializers.Serializer): | ||||
|  | ||||
|                 try: | ||||
|                     # Create a new BuildItem to allocate stock | ||||
|                     BuildItem.objects.create( | ||||
|                     build_item, created = BuildItem.objects.get_or_create( | ||||
|                         build_line=build_line, | ||||
|                         stock_item=stock_item, | ||||
|                         quantity=quantity, | ||||
|                         install_into=output | ||||
|                         install_into=output, | ||||
|                     ) | ||||
|                     if created: | ||||
|                         build_item.quantity = quantity | ||||
|                     else: | ||||
|                         build_item.quantity += quantity | ||||
|                     build_item.save() | ||||
|                 except (ValidationError, DjangoValidationError) as exc: | ||||
|                     # Catch model errors and re-throw as DRF errors | ||||
|                     raise ValidationError(detail=serializers.as_serializer_error(exc)) | ||||
|   | ||||
| @@ -753,6 +753,80 @@ class BuildAllocationTest(BuildAPITest): | ||||
|         self.assertEqual(allocation.bom_item.pk, 1) | ||||
|         self.assertEqual(allocation.stock_item.pk, 2) | ||||
|  | ||||
|     def test_reallocate(self): | ||||
|         """Test reallocating an existing built item with the same stock item. | ||||
|  | ||||
|         This should increment the quantity of the existing BuildItem object | ||||
|         """ | ||||
|  | ||||
|         # Find the correct BuildLine | ||||
|         si = StockItem.objects.get(pk=2) | ||||
|  | ||||
|         right_line = None | ||||
|         for line in self.build.build_lines.all(): | ||||
|             if line.bom_item.sub_part.pk == si.part.pk: | ||||
|                 right_line = line | ||||
|                 break | ||||
|  | ||||
|         self.post( | ||||
|             self.url, | ||||
|             { | ||||
|                 "items": [ | ||||
|                     { | ||||
|                         "build_line": right_line.pk, | ||||
|                         "stock_item": 2, | ||||
|                         "quantity": 3000, | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             expected_code=201 | ||||
|         ) | ||||
|  | ||||
|         # A new BuildItem should have been created | ||||
|         self.assertEqual(self.n + 1, BuildItem.objects.count()) | ||||
|  | ||||
|         allocation = BuildItem.objects.last() | ||||
|  | ||||
|         self.assertEqual(allocation.quantity, 3000) | ||||
|         self.assertEqual(allocation.bom_item.pk, 1) | ||||
|         self.assertEqual(allocation.stock_item.pk, 2) | ||||
|  | ||||
|         # Try to allocate more than the required quantity (this should fail) | ||||
|         self.post( | ||||
|             self.url, | ||||
|             { | ||||
|                 "items": [ | ||||
|                     { | ||||
|                         "build_line": right_line.pk, | ||||
|                         "stock_item": 2, | ||||
|                         "quantity": 2001, | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             expected_code=400 | ||||
|         ) | ||||
|  | ||||
|         allocation.refresh_from_db() | ||||
|         self.assertEqual(allocation.quantity, 3000) | ||||
|  | ||||
|         # Try to allocate the remaining items | ||||
|         self.post( | ||||
|             self.url, | ||||
|             { | ||||
|                 "items": [ | ||||
|                     { | ||||
|                         "build_line": right_line.pk, | ||||
|                         "stock_item": 2, | ||||
|                         "quantity": 2000, | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             expected_code=201 | ||||
|         ) | ||||
|  | ||||
|         allocation.refresh_from_db() | ||||
|         self.assertEqual(allocation.quantity, 5000) | ||||
|  | ||||
|  | ||||
| class BuildOverallocationTest(BuildAPITest): | ||||
|     """Unit tests for over allocation of stock items against a build order. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user