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:
Bobbe 2023-10-17 15:48:30 +02:00 committed by GitHub
parent 8c10b98fe8
commit 9f2c55d2d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 7 deletions

View File

@ -866,10 +866,6 @@ class BuildAllocationItemSerializer(serializers.Serializer):
'output': _('Build output cannot be specified for allocation of untracked parts'), '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 return data
@ -914,12 +910,16 @@ class BuildAllocationSerializer(serializers.Serializer):
try: try:
# Create a new BuildItem to allocate stock # Create a new BuildItem to allocate stock
BuildItem.objects.create( build_item, created = BuildItem.objects.get_or_create(
build_line=build_line, build_line=build_line,
stock_item=stock_item, 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: except (ValidationError, DjangoValidationError) as exc:
# Catch model errors and re-throw as DRF errors # Catch model errors and re-throw as DRF errors
raise ValidationError(detail=serializers.as_serializer_error(exc)) raise ValidationError(detail=serializers.as_serializer_error(exc))

View File

@ -753,6 +753,80 @@ class BuildAllocationTest(BuildAPITest):
self.assertEqual(allocation.bom_item.pk, 1) self.assertEqual(allocation.bom_item.pk, 1)
self.assertEqual(allocation.stock_item.pk, 2) 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): class BuildOverallocationTest(BuildAPITest):
"""Unit tests for over allocation of stock items against a build order. """Unit tests for over allocation of stock items against a build order.