mirror of
https://github.com/inventree/InvenTree.git
synced 2026-05-06 17:53:44 +00:00
Delete output check (#11881)
* Allow deletion of serialized build output - If calling "delete_output" on a BuildOrder - Only will delete an in_production output - Ignore the global setting in this case Co-authored-by: Copilot <copilot@github.com> * Add unit test Co-authored-by: Copilot <copilot@github.com> --------- Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -1033,7 +1033,9 @@ class Build(
|
|||||||
self.deallocate_stock(output=output)
|
self.deallocate_stock(output=output)
|
||||||
|
|
||||||
# Remove the build output from the database
|
# Remove the build output from the database
|
||||||
output.delete()
|
# This is a special case where serialized stock can be deleted,
|
||||||
|
# independedent of the global setting which normally prevents deletion of serialized stock items
|
||||||
|
output.delete(ignore_serial_check=True)
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def trim_allocated_stock(self):
|
def trim_allocated_stock(self):
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from rest_framework import status
|
|||||||
|
|
||||||
from build.models import Build, BuildItem, BuildLine
|
from build.models import Build, BuildItem, BuildLine
|
||||||
from build.status_codes import BuildStatus
|
from build.status_codes import BuildStatus
|
||||||
|
from common.settings import set_global_setting
|
||||||
from InvenTree.unit_test import InvenTreeAPITestCase
|
from InvenTree.unit_test import InvenTreeAPITestCase
|
||||||
from part.models import BomItem, Part
|
from part.models import BomItem, Part
|
||||||
from stock.models import StockItem
|
from stock.models import StockItem
|
||||||
@@ -1548,6 +1549,44 @@ class BuildOutputScrapTest(BuildAPITest):
|
|||||||
self.assertFalse(completed_output.is_building)
|
self.assertFalse(completed_output.is_building)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildOutputCancelTest(BuildAPITest):
|
||||||
|
"""Test cancellation of build outputs."""
|
||||||
|
|
||||||
|
def test_cancel_output(self):
|
||||||
|
"""Test cancellation of a build output."""
|
||||||
|
build = Build.objects.get(pk=1)
|
||||||
|
build.part.trackable = True
|
||||||
|
build.part.save()
|
||||||
|
|
||||||
|
N = build.build_outputs.count()
|
||||||
|
|
||||||
|
# Create outputs
|
||||||
|
outputs = build.create_build_output(2, serials=['101', '202'])
|
||||||
|
self.assertEqual(outputs.count(), 2)
|
||||||
|
self.assertEqual(build.build_outputs.count(), N + 2)
|
||||||
|
|
||||||
|
output_ids = list(outputs.values_list('pk', flat=True))
|
||||||
|
|
||||||
|
# Let's cancel one of the outputs
|
||||||
|
set_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', True)
|
||||||
|
url = reverse('api-build-output-delete', kwargs={'pk': build.pk})
|
||||||
|
|
||||||
|
self.post(url, data={'outputs': [{'output': output_ids[0]}]}, expected_code=201)
|
||||||
|
|
||||||
|
# Prevent deletion of serialized stock items, and try again
|
||||||
|
# Note that this should still succeed, independent of the global setting
|
||||||
|
set_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', False)
|
||||||
|
|
||||||
|
self.post(url, data={'outputs': [{'output': output_ids[1]}]}, expected_code=201)
|
||||||
|
|
||||||
|
# The outputs should have been scrapped
|
||||||
|
self.assertEqual(build.build_outputs.count(), N)
|
||||||
|
|
||||||
|
for pk in output_ids:
|
||||||
|
self.assertFalse(StockItem.objects.filter(pk=pk).exists())
|
||||||
|
self.get(reverse('api-stock-detail', kwargs={'pk': pk}), expected_code=404)
|
||||||
|
|
||||||
|
|
||||||
class BuildLineTests(BuildAPITest):
|
class BuildLineTests(BuildAPITest):
|
||||||
"""Unit tests for the BuildLine API endpoints."""
|
"""Unit tests for the BuildLine API endpoints."""
|
||||||
|
|
||||||
|
|||||||
@@ -449,9 +449,15 @@ class StockItem(
|
|||||||
|
|
||||||
order_insertion_by = ['part']
|
order_insertion_by = ['part']
|
||||||
|
|
||||||
def delete(self, **kwargs):
|
def delete(self, ignore_serial_check: bool = False, **kwargs):
|
||||||
"""Custom delete method for StockItem model."""
|
"""Custom delete method for StockItem model.
|
||||||
if not get_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', cache=False):
|
|
||||||
|
Arguments:
|
||||||
|
ignore_serial_check: If True, allow deletion of serialized stock items regardless of global setting
|
||||||
|
"""
|
||||||
|
if not ignore_serial_check and not get_global_setting(
|
||||||
|
'STOCK_ALLOW_DELETE_SERIALIZED', cache=False
|
||||||
|
):
|
||||||
if self.serialized:
|
if self.serialized:
|
||||||
raise ValidationError(_('Serialized stock items cannot be deleted'))
|
raise ValidationError(_('Serialized stock items cannot be deleted'))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user