mirror of
https://github.com/inventree/InvenTree.git
synced 2026-05-06 09:43:38 +00:00
Prevent delete serialized stock (#11872)
* Add setting to prevent deletion of serialized stock Co-authored-by: Copilot <copilot@github.com> * Add unit test Co-authored-by: Copilot <copilot@github.com> * Update CHANGELOG Co-authored-by: Copilot <copilot@github.com> --------- Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- [#11872](https://github.com/inventree/InvenTree/pull/11872) adds a global setting to allow or disallow the deletion of serialized stock items.
|
||||||
- [#11861](https://github.com/inventree/InvenTree/pull/11861) adds support for bulk-replacing a component in multiple BOMs simultaneously
|
- [#11861](https://github.com/inventree/InvenTree/pull/11861) adds support for bulk-replacing a component in multiple BOMs simultaneously
|
||||||
- [#11853](https://github.com/inventree/InvenTree/pull/11853) adds BOM comparison functionality, allowing users to compare the BOM of one assembly with another assembly.
|
- [#11853](https://github.com/inventree/InvenTree/pull/11853) adds BOM comparison functionality, allowing users to compare the BOM of one assembly with another assembly.
|
||||||
- [#11809](https://github.com/inventree/InvenTree/pull/11809) adds multi-level subassembly display mode to the BOM table, allowing users to view multiple levels of subassemblies in a single table view. This is an optional display mode which can be toggled on or off by the user.
|
- [#11809](https://github.com/inventree/InvenTree/pull/11809) adds multi-level subassembly display mode to the BOM table, allowing users to view multiple levels of subassemblies in a single table view. This is an optional display mode which can be toggled on or off by the user.
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ Configuration of stock item options
|
|||||||
| Name | Description | Default | Units |
|
| Name | Description | Default | Units |
|
||||||
| ---- | ----------- | ------- | ----- |
|
| ---- | ----------- | ------- | ----- |
|
||||||
{{ globalsetting("SERIAL_NUMBER_GLOBALLY_UNIQUE") }}
|
{{ globalsetting("SERIAL_NUMBER_GLOBALLY_UNIQUE") }}
|
||||||
|
{{ globalsetting("STOCK_ALLOW_DELETE_SERIALIZED") }}
|
||||||
{{ globalsetting("STOCK_DELETE_DEPLETED_DEFAULT") }}
|
{{ globalsetting("STOCK_DELETE_DEPLETED_DEFAULT") }}
|
||||||
{{ globalsetting("STOCK_BATCH_CODE_TEMPLATE") }}
|
{{ globalsetting("STOCK_BATCH_CODE_TEMPLATE") }}
|
||||||
{{ globalsetting("STOCK_ENABLE_EXPIRY") }}
|
{{ globalsetting("STOCK_ENABLE_EXPIRY") }}
|
||||||
|
|||||||
@@ -716,6 +716,12 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = {
|
|||||||
'default': True,
|
'default': True,
|
||||||
'validator': bool,
|
'validator': bool,
|
||||||
},
|
},
|
||||||
|
'STOCK_ALLOW_DELETE_SERIALIZED': {
|
||||||
|
'name': _('Delete Serialized Stock'),
|
||||||
|
'description': _('Allow deletion of stock items which have a serial number'),
|
||||||
|
'default': True,
|
||||||
|
'validator': bool,
|
||||||
|
},
|
||||||
'STOCK_BATCH_CODE_TEMPLATE': {
|
'STOCK_BATCH_CODE_TEMPLATE': {
|
||||||
'name': _('Batch Code Template'),
|
'name': _('Batch Code Template'),
|
||||||
'description': _('Template for generating default batch codes for stock items'),
|
'description': _('Template for generating default batch codes for stock items'),
|
||||||
|
|||||||
@@ -449,6 +449,14 @@ class StockItem(
|
|||||||
|
|
||||||
order_insertion_by = ['part']
|
order_insertion_by = ['part']
|
||||||
|
|
||||||
|
def delete(self, **kwargs):
|
||||||
|
"""Custom delete method for StockItem model."""
|
||||||
|
if not get_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', cache=False):
|
||||||
|
if self.serialized:
|
||||||
|
raise ValidationError(_('Serialized stock items cannot be deleted'))
|
||||||
|
|
||||||
|
super().delete(**kwargs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_api_url():
|
def get_api_url():
|
||||||
"""Return API url."""
|
"""Return API url."""
|
||||||
|
|||||||
@@ -2181,6 +2181,37 @@ class StockItemDeletionTest(StockAPITestCase):
|
|||||||
|
|
||||||
self.assertEqual(StockItem.objects.count(), n)
|
self.assertEqual(StockItem.objects.count(), n)
|
||||||
|
|
||||||
|
def test_delete_serialized(self):
|
||||||
|
"""Test deletion of serialized stock items."""
|
||||||
|
trackable_part = part.models.Part.objects.create(
|
||||||
|
name='My part',
|
||||||
|
description='A trackable part',
|
||||||
|
trackable=True,
|
||||||
|
default_location=StockLocation.objects.get(pk=1),
|
||||||
|
)
|
||||||
|
|
||||||
|
stock_item = StockItem.objects.create(
|
||||||
|
part=trackable_part, quantity=1, serial='12345'
|
||||||
|
)
|
||||||
|
|
||||||
|
set_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', False)
|
||||||
|
|
||||||
|
response = self.delete(
|
||||||
|
reverse('api-stock-detail', kwargs={'pk': stock_item.pk}), expected_code=400
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIn('Serialized stock items cannot be deleted', str(response.data))
|
||||||
|
|
||||||
|
set_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', True)
|
||||||
|
|
||||||
|
response = self.delete(
|
||||||
|
reverse('api-stock-detail', kwargs={'pk': stock_item.pk}), expected_code=204
|
||||||
|
)
|
||||||
|
|
||||||
|
self.get(
|
||||||
|
reverse('api-stock-detail', kwargs={'pk': stock_item.pk}), expected_code=404
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class StockTestResultTest(StockAPITestCase):
|
class StockTestResultTest(StockAPITestCase):
|
||||||
"""Tests for StockTestResult APIs."""
|
"""Tests for StockTestResult APIs."""
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ export default function SystemSettings() {
|
|||||||
<GlobalSettingList
|
<GlobalSettingList
|
||||||
keys={[
|
keys={[
|
||||||
'SERIAL_NUMBER_GLOBALLY_UNIQUE',
|
'SERIAL_NUMBER_GLOBALLY_UNIQUE',
|
||||||
|
'STOCK_ALLOW_DELETE_SERIALIZED',
|
||||||
'STOCK_DELETE_DEPLETED_DEFAULT',
|
'STOCK_DELETE_DEPLETED_DEFAULT',
|
||||||
'STOCK_BATCH_CODE_TEMPLATE',
|
'STOCK_BATCH_CODE_TEMPLATE',
|
||||||
'STOCK_OWNERSHIP_CONTROL',
|
'STOCK_OWNERSHIP_CONTROL',
|
||||||
|
|||||||
Reference in New Issue
Block a user