diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 02393023b9..90a6fd365c 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -647,6 +647,9 @@ class StockItem(MPTTModel): # Copy entire transaction history new_item.copyHistoryFrom(self) + # Copy test result history + new_item.copyTestResultsFrom(self) + # Create a new stock tracking item new_item.addTransactionNote(_('Add serial number'), user, notes=notes) @@ -655,7 +658,7 @@ class StockItem(MPTTModel): @transaction.atomic def copyHistoryFrom(self, other): - """ Copy stock history from another part """ + """ Copy stock history from another StockItem """ for item in other.tracking_info.all(): @@ -663,6 +666,17 @@ class StockItem(MPTTModel): item.pk = None item.save() + @transaction.atomic + def copyTestResultsFrom(self, other, filters={}): + """ Copy all test results from another StockItem """ + + for result in other.test_results.all().filter(**filters): + + # Create a copy of the test result by nulling-out the pk + result.pk = None + result.stock_item = self + result.save() + @transaction.atomic def splitStock(self, quantity, location, user): """ Split this stock item into two items, in the same location. @@ -713,6 +727,9 @@ class StockItem(MPTTModel): # Copy the transaction history of this part into the new one new_stock.copyHistoryFrom(self) + # Copy the test results of this part to the new one + new_stock.copyTestResultsFrom(self) + # Add a new tracking item for the new stock item new_stock.addTransactionNote( "Split from existing stock", diff --git a/InvenTree/stock/tests.py b/InvenTree/stock/tests.py index 045cbe164e..513368c422 100644 --- a/InvenTree/stock/tests.py +++ b/InvenTree/stock/tests.py @@ -458,3 +458,68 @@ class TestResultTest(StockTest): ) self.assertTrue(item.passedAllRequiredTests()) + + def test_duplicate_item_tests(self): + + # Create an example stock item by copying one from the database (because we are lazy) + item = StockItem.objects.get(pk=522) + + item.pk = None + item.serial = None + item.quantity = 50 + + item.save() + + # Do some tests! + StockItemTestResult.objects.create( + stock_item=item, + test="Firmware", + result=True + ) + + StockItemTestResult.objects.create( + stock_item=item, + test="Paint Color", + result=True, + value="Red" + ) + + StockItemTestResult.objects.create( + stock_item=item, + test="Applied Sticker", + result=False + ) + + self.assertEqual(item.test_results.count(), 3) + self.assertEqual(item.quantity, 50) + + # Split some items out + item2 = item.splitStock(20, None, None) + + self.assertEqual(item.quantity, 30) + + self.assertEqual(item.test_results.count(), 3) + self.assertEqual(item2.test_results.count(), 3) + + StockItemTestResult.objects.create( + stock_item=item2, + test='A new test' + ) + + self.assertEqual(item.test_results.count(), 3) + self.assertEqual(item2.test_results.count(), 4) + + # Test StockItem serialization + item2.serializeStock(1, [100], self.user) + + # Add a test result to the parent *after* serialization + StockItemTestResult.objects.create( + stock_item=item2, + test='abcde' + ) + + self.assertEqual(item2.test_results.count(), 5) + + item3 = StockItem.objects.get(serial=100, part=item2.part) + + self.assertEqual(item3.test_results.count(), 4)