[bug] Validate location when completing build outputs (#12570)

* [bug] Validate location when completing build outputs

- Cannot be structural

* Fix unit test

---------

Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
Oliver
2026-08-08 23:27:53 +10:00
committed by GitHub
co-authored by Matthias Mair
parent c0ed42549f
commit 94024ad23e
2 changed files with 42 additions and 0 deletions
@@ -570,6 +570,15 @@ class BuildOutputCompleteSerializer(serializers.Serializer):
help_text=_('Location for completed build outputs'), help_text=_('Location for completed build outputs'),
) )
def validate_location(self, location):
"""Validate the provided location."""
if location and location.structural:
raise ValidationError(
_('Structural locations cannot be assigned stock items')
)
return location
status_custom_key = StockStatusCustomSerializer(default=StockStatus.OK.value) status_custom_key = StockStatusCustomSerializer(default=StockStatus.OK.value)
accept_incomplete_allocation = serializers.BooleanField( accept_incomplete_allocation = serializers.BooleanField(
+33
View File
@@ -498,6 +498,39 @@ class BuildTest(BuildAPITest):
'This build output has already been completed', str(response.data) 'This build output has already been completed', str(response.data)
) )
def test_complete_build_output_structural_location(self):
"""Test that a structural location is rejected by the BuildOutputComplete API.
Ref: this validation must happen synchronously in the serializer,
before the completion is offloaded to the background worker.
"""
bo = Build.objects.get(pk=1)
# Create a new build output
create_url = reverse('api-build-output-create', kwargs={'pk': bo.pk})
response = self.post(create_url, {'quantity': 1}, expected_code=201)
output = StockItem.objects.get(pk=response.data[0]['pk'])
structural_location = StockLocation.objects.create(
name='Structural location', structural=True
)
complete_url = reverse('api-build-output-complete', kwargs={'pk': bo.pk})
response = self.post(
complete_url,
{'outputs': [{'output': output.pk}], 'location': structural_location.pk},
expected_code=400,
)
self.assertIn(
'Structural locations cannot be assigned stock items', str(response.data)
)
# None of the outputs should have been completed
output.refresh_from_db()
self.assertTrue(output.is_building)
def test_download_build_orders(self): def test_download_build_orders(self):
"""Test that we can download a list of build orders via the API.""" """Test that we can download a list of build orders via the API."""
required_cols = [ required_cols = [