2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-01 03:00:54 +00:00

Part duplicate bug fix (#4370)

* Make 'copy_category_parameters' part of actual serializer

* Parameter copying is now handled by the API serializer

* Make field not required

* linting fixes

* pre commit fix

* Fix unit tests

* Further fix for unit test

* Unit tests for category parameter duplication
This commit is contained in:
Oliver
2023-02-20 18:48:55 +11:00
committed by GitHub
parent 95ecd0cd32
commit 782ae133b7
6 changed files with 92 additions and 84 deletions

View File

@ -2,11 +2,12 @@
import imghdr
import io
import logging
from decimal import Decimal
from django.core.files.base import ContentFile
from django.core.validators import MinValueValidator
from django.db import models, transaction
from django.db import IntegrityError, models, transaction
from django.db.models import ExpressionWrapper, F, FloatField, Q
from django.db.models.functions import Coalesce
from django.urls import reverse_lazy
@ -42,6 +43,8 @@ from .models import (BomItem, BomItemSubstitute, Part, PartAttachment,
PartSellPriceBreak, PartStar, PartStocktake,
PartStocktakeReport, PartTestTemplate)
logger = logging.getLogger("inventree")
class CategorySerializer(InvenTreeModelSerializer):
"""Serializer for PartCategory."""
@ -454,6 +457,7 @@ class PartSerializer(RemoteImageMixin, InvenTreeModelSerializer):
'duplicate',
'initial_stock',
'initial_supplier',
'copy_category_parameters'
]
read_only_fields = [
@ -499,6 +503,7 @@ class PartSerializer(RemoteImageMixin, InvenTreeModelSerializer):
'duplicate',
'initial_stock',
'initial_supplier',
'copy_category_parameters'
]
return fields
@ -613,6 +618,12 @@ class PartSerializer(RemoteImageMixin, InvenTreeModelSerializer):
write_only=True, required=False,
)
copy_category_parameters = serializers.BooleanField(
default=True, required=False,
label=_('Copy Category Parameters'),
help_text=_('Copy parameter templates from selected part category'),
)
@transaction.atomic
def create(self, validated_data):
"""Custom method for creating a new Part instance using this serializer"""
@ -620,9 +631,15 @@ class PartSerializer(RemoteImageMixin, InvenTreeModelSerializer):
duplicate = validated_data.pop('duplicate', None)
initial_stock = validated_data.pop('initial_stock', None)
initial_supplier = validated_data.pop('initial_supplier', None)
copy_category_parameters = validated_data.pop('copy_category_parameters', False)
instance = super().create(validated_data)
# Save user information
if self.context['request']:
instance.creation_user = self.context['request'].user
instance.save()
# Copy data from original Part
if duplicate:
original = duplicate['part']
@ -637,6 +654,34 @@ class PartSerializer(RemoteImageMixin, InvenTreeModelSerializer):
if duplicate['copy_parameters']:
instance.copy_parameters_from(original)
# Duplicate parameter data from part category (and parents)
if copy_category_parameters and instance.category is not None:
# Get flattened list of parent categories
categories = instance.category.get_ancestors(include_self=True)
# All parameter templates within these categories
templates = PartCategoryParameterTemplate.objects.filter(
category__in=categories
)
for template in templates:
# First ensure that the part doesn't have that parameter
if PartParameter.objects.filter(
part=instance,
template=template.parameter_template
).exists():
continue
try:
PartParameter.create(
part=instance,
template=template.parameter_template,
data=template.default_value,
save=True
)
except IntegrityError:
logger.error(f"Could not create new PartParameter for part {instance}")
# Create initial stock entry
if initial_stock:
quantity = initial_stock['quantity']