Implement duplicate action for stock item

This commit is contained in:
Oliver Walters
2026-07-04 14:18:46 +00:00
parent ebabc3359f
commit 427eb6d4b3
4 changed files with 74 additions and 2 deletions
+23
View File
@@ -1250,9 +1250,28 @@ class StockList(
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
# Extract 'duplicate' options (if provided) - these are not valid model fields
duplicate = serializer.validated_data.pop('duplicate', None)
# Extract location information
location = serializer.validated_data.get('location', None)
def apply_duplicate_options(item):
"""Apply any provided 'duplicate' options to a newly created StockItem."""
if not duplicate:
return
original = duplicate['original']
if duplicate.get('copy_notes', True):
item.copy_notes_from(original)
if duplicate.get('copy_history', False):
item.copyHistoryFrom(original)
if duplicate.get('copy_tests', False):
item.copyTestResultsFrom(original)
with transaction.atomic():
if serials:
# Create multiple serialized StockItem objects
@@ -1268,6 +1287,8 @@ class StockList(
item.set_status(status_value)
item.save()
apply_duplicate_options(item)
if entry := item.add_tracking_entry(
StockHistoryCode.CREATED,
user,
@@ -1300,6 +1321,8 @@ class StockList(
item.save(user=user)
item.refresh_from_db()
apply_duplicate_options(item)
response_data = [
StockSerializers.StockItemSerializer(
item, context=self.get_serializer_context()
@@ -324,6 +324,8 @@ class StockItemSerializer(
export_exclude_fields = ['tags', 'tracking_items']
SKIP_CREATE_FIELDS = ['duplicate']
export_child_fields = [
'part_detail.name',
'part_detail.description',
@@ -380,6 +382,7 @@ class StockItemSerializer(
'purchase_price_currency',
'use_pack_size',
'serial_numbers',
'duplicate',
# Annotated fields
'allocated',
'expired',
@@ -467,6 +470,28 @@ class StockItemSerializer(
help_text=_('Enter serial numbers for new items'),
)
# Extra field used only for creation of a new StockItem instance
duplicate = InvenTree.serializers.DuplicateOptionsSerializer(
StockItem.objects.all(),
label=_('Duplicate Stock Item'),
help_text=_('Copy initial data from another stock item'),
copy_notes=True,
copy_fields=[
{
'name': 'copy_tests',
'label': _('Copy Test Results'),
'help_text': _('Copy test results from the original stock item'),
'default': False,
},
{
'name': 'copy_history',
'label': _('Copy History'),
'help_text': _('Copy stock history from the original stock item'),
'default': False,
},
],
)
def validate_part(self, part):
"""Ensure the provided Part instance is valid."""
if part.virtual: