Uninstall fix (#12378)
* Prevent uninstall into structural location * Regression tests
This commit is contained in:
parent
a12fd546ff
commit
b64182b565
|
|
@ -1760,6 +1760,11 @@ class StockItem(
|
|||
if self.belongs_to is None:
|
||||
return False
|
||||
|
||||
if location and location.structural:
|
||||
raise ValidationError({
|
||||
'location': _('Cannot assign stock to structural location')
|
||||
})
|
||||
|
||||
# Add a transaction note to the parent item
|
||||
self.belongs_to.add_tracking_entry(
|
||||
StockHistoryCode.REMOVED_CHILD_ITEM,
|
||||
|
|
|
|||
|
|
@ -938,6 +938,15 @@ class UninstallStockItemSerializer(serializers.Serializer):
|
|||
allow_blank=True,
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
def save(self):
|
||||
"""Uninstall stock item."""
|
||||
item = self.context.get('item')
|
||||
|
|
|
|||
|
|
@ -1977,6 +1977,20 @@ class StockItemTest(StockAPITestCase):
|
|||
|
||||
url = reverse('api-stock-item-uninstall', kwargs={'pk': sub_item.pk})
|
||||
|
||||
# An uninstalled item cannot be moved into a structural location
|
||||
structural = StockLocation.objects.create(
|
||||
name='Structural location', structural=True
|
||||
)
|
||||
|
||||
response = self.post(url, {'location': structural.pk}, expected_code=400)
|
||||
|
||||
self.assertIn(
|
||||
'Structural locations cannot be assigned stock items', str(response.data)
|
||||
)
|
||||
|
||||
sub_item.refresh_from_db()
|
||||
self.assertEqual(sub_item.belongs_to, item)
|
||||
|
||||
self.post(url, {'location': 1}, expected_code=201)
|
||||
|
||||
sub_item.refresh_from_db()
|
||||
|
|
|
|||
|
|
@ -351,6 +351,38 @@ class StockTest(StockTestBase):
|
|||
stock.splitStock(stock.quantity, None, self.user)
|
||||
self.assertEqual(StockItem.objects.filter(part=3).count(), n + 1)
|
||||
|
||||
def test_uninstall_into_structural_location(self):
|
||||
"""Test that an item cannot be uninstalled into a structural location."""
|
||||
parent = StockItem.objects.get(pk=1)
|
||||
|
||||
item = StockItem.objects.get(pk=2)
|
||||
item.belongs_to = parent
|
||||
item.save()
|
||||
|
||||
n_entries = item.tracking_info.count()
|
||||
n_parent_entries = parent.tracking_info.count()
|
||||
|
||||
structural = StockLocation.objects.create(
|
||||
name='Structural location', structural=True
|
||||
)
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
item.uninstall_into_location(structural, self.user, 'Uninstalling')
|
||||
|
||||
# The item remains installed, with no location change or tracking entries
|
||||
item.refresh_from_db()
|
||||
self.assertEqual(item.belongs_to, parent)
|
||||
self.assertNotEqual(item.location, structural)
|
||||
self.assertEqual(item.tracking_info.count(), n_entries)
|
||||
self.assertEqual(parent.tracking_info.count(), n_parent_entries)
|
||||
|
||||
# Uninstalling into a non-structural location is still permitted
|
||||
item.uninstall_into_location(self.drawer2, self.user, 'Uninstalling')
|
||||
|
||||
item.refresh_from_db()
|
||||
self.assertIsNone(item.belongs_to)
|
||||
self.assertEqual(item.location, self.drawer2)
|
||||
|
||||
def test_child_items(self):
|
||||
"""Test the 'children' reverse relation and 'child_count' property.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue