diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index d18b1a2a8b..89f9103187 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -493,6 +493,22 @@ class BomItemSerializer(InvenTreeModelSerializer): purchase_price_range = serializers.SerializerMethodField() + def validate(self, data): + + # Check for duplicate BOM items + part = data['part'] + sub_part = data['sub_part'] + + if BomItem.objects.get(part=part, sub_part=sub_part).exists(): + raise serializers.ValidationError({ + 'part': _("Duplicate BOM item already exists"), + 'sub_part': _("Duplicate BOM items already exists"), + }) + + data = super().validate(data) + + return data + def __init__(self, *args, **kwargs): # part_detail and sub_part_detail serializers are only included if requested. # This saves a bunch of database requests @@ -962,8 +978,20 @@ class BomUploadSerializer(serializers.Serializer): items = data['items'] - with transaction.atomic(): + try: + with transaction.atomic(): - for item in items: - print(item) - \ No newline at end of file + for item in items: + + part = item['part'] + sub_part = item['sub_part'] + + # Ignore duplicate BOM items + if BomItem.objects.filter(part=part, sub_part=sub_part).exists(): + continue + + # Create a new BomItem object + BomItem.objects.create(**item) + + except Exception as e: + raise serializers.ValidationError(detail=serializers.as_serializer_error(e)) diff --git a/InvenTree/templates/js/translated/bom.js b/InvenTree/templates/js/translated/bom.js index 512cb0c46a..d5391ab70a 100644 --- a/InvenTree/templates/js/translated/bom.js +++ b/InvenTree/templates/js/translated/bom.js @@ -43,6 +43,7 @@ function constructBomUploadTable(data, options={}) { var field_options = { hideLabels: true, hideClearButton: true, + form_classes: 'bom-form-group', }; function constructRowField(field_name) { @@ -77,7 +78,7 @@ function constructBomUploadTable(data, options={}) { buttons += ``; var html = ` -