diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index f03cb30c74..cd8f4df16f 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -582,7 +582,7 @@ class Build(MPTTModel, ReferenceIndexingMixin): self.subtractUntrackedStock(user) # Ensure that there are no longer any BuildItem objects - # which point to thie Build Order + # which point to thisFcan Build Order self.allocated_stock.all().delete() @transaction.atomic diff --git a/InvenTree/build/serializers.py b/InvenTree/build/serializers.py index 01ea9fd924..04cbc162c9 100644 --- a/InvenTree/build/serializers.py +++ b/InvenTree/build/serializers.py @@ -277,6 +277,15 @@ class BuildCompleteSerializer(serializers.Serializer): return value + def validate(self, data): + + build = self.context['build'] + + if build.incomplete_count > 0: + raise ValidationError(_("Build order has incomplete outputs")) + + return data + def save(self): request = self.context['request'] diff --git a/InvenTree/build/test_api.py b/InvenTree/build/test_api.py index 45662a58d6..64d17430a0 100644 --- a/InvenTree/build/test_api.py +++ b/InvenTree/build/test_api.py @@ -38,7 +38,7 @@ class BuildAPITest(InvenTreeAPITestCase): super().setUp() -class BuildCompleteTest(BuildAPITest): +class BuildOutputCompleteTest(BuildAPITest): """ Unit testing for the build complete API endpoint """ @@ -140,6 +140,9 @@ class BuildCompleteTest(BuildAPITest): Test build order completion """ + # Initially, build should not be able to be completed + self.assertFalse(self.build.can_complete) + # We start without any outputs assigned against the build self.assertEqual(self.build.incomplete_outputs.count(), 0) @@ -153,7 +156,7 @@ class BuildCompleteTest(BuildAPITest): self.assertEqual(self.build.completed, 0) # We shall complete 4 of these outputs - outputs = self.build.incomplete_outputs[0:4] + outputs = self.build.incomplete_outputs.all() self.post( self.url, @@ -165,19 +168,44 @@ class BuildCompleteTest(BuildAPITest): expected_code=201 ) - # There now should be 6 incomplete build outputs remaining - self.assertEqual(self.build.incomplete_outputs.count(), 6) + self.assertEqual(self.build.incomplete_outputs.count(), 0) - # And there should be 4 completed outputs + # And there should be 10 completed outputs outputs = self.build.complete_outputs - self.assertEqual(outputs.count(), 4) + self.assertEqual(outputs.count(), 10) for output in outputs: self.assertFalse(output.is_building) self.assertEqual(output.build, self.build) self.build.refresh_from_db() - self.assertEqual(self.build.completed, 40) + self.assertEqual(self.build.completed, 100) + + # Try to complete the build (it should fail) + finish_url = reverse('api-build-finish', kwargs={'pk': self.build.pk}) + + response = self.post( + finish_url, + {}, + expected_code=400 + ) + + self.assertTrue('accept_unallocated' in response.data) + + # Accept unallocated stock + response = self.post( + finish_url, + { + 'accept_unallocated': True, + }, + expected_code=201, + ) + + # Accept unfinished + self.build.refresh_from_db() + + # Build should have been marked as complete + self.assertTrue(self.build.is_complete) class BuildAllocationTest(BuildAPITest):