diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index a672e79051..8f31eb0b77 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -454,6 +454,26 @@ class PartSerialNumberDetail(generics.RetrieveAPIView): return Response(data) +class PartCopyBOM(generics.CreateAPIView): + """ + API endpoint for duplicating a BOM + """ + + queryset = Part.objects.all() + serializer_class = part_serializers.PartCopyBOMSerializer + + def get_serializer_context(self): + + ctx = super().get_serializer_context() + + try: + ctx['part'] = Part.objects.get(pk=self.kwargs.get('pk', None)) + except: + pass + + return ctx + + class PartDetail(generics.RetrieveUpdateDestroyAPIView): """ API endpoint for detail view of a single Part object """ @@ -1585,6 +1605,9 @@ part_api_urls = [ # Endpoint for extra serial number information url(r'^serial-numbers/', PartSerialNumberDetail.as_view(), name='api-part-serial-number-detail'), + # Endpoint for duplicating a BOM + url(r'^copy-bom/', PartCopyBOM.as_view(), name='api-part-copy-bom'), + # Part detail endpoint url(r'^.*$', PartDetail.as_view(), name='api-part-detail'), ])), diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index 2d9ae4dc30..5afd037c63 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -55,39 +55,6 @@ class PartImageDownloadForm(HelperForm): ] -class BomDuplicateForm(HelperForm): - """ - Simple confirmation form for BOM duplication. - - Select which parent to select from. - """ - - parent = PartModelChoiceField( - label=_('Parent Part'), - help_text=_('Select parent part to copy BOM from'), - queryset=Part.objects.filter(is_template=True), - ) - - clear = forms.BooleanField( - required=False, initial=True, - help_text=_('Clear existing BOM items') - ) - - confirm = forms.BooleanField( - required=False, initial=False, - label=_('Confirm'), - help_text=_('Confirm BOM duplication') - ) - - class Meta: - model = Part - fields = [ - 'parent', - 'clear', - 'confirm', - ] - - class BomValidateForm(HelperForm): """ Simple confirmation form for BOM validation. User is presented with a single checkbox input, diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index 820962b613..79e6596124 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -9,6 +9,7 @@ from django.urls import reverse_lazy from django.db import models from django.db.models import Q from django.db.models.functions import Coalesce +from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers from sql_util.utils import SubqueryCount, SubquerySum @@ -636,3 +637,53 @@ class CategoryParameterTemplateSerializer(InvenTreeModelSerializer): 'parameter_template', 'default_value', ] + + +class PartCopyBOMSerializer(serializers.Serializer): + """ + Serializer for copying a BOM from another part + """ + + class Meta: + fields = [ + 'part', + 'remove_existing', + ] + + part = serializers.PrimaryKeyRelatedField( + queryset=Part.objects.all(), + many=False, + required=True, + allow_null=False, + label=_('Part'), + help_text=_('Select part to copy BOM from'), + ) + + def validate_part(self, part): + """ + Check that a 'valid' part was selected + """ + + # Check if the BOM can be copied from the provided part + base_part = self.context['part'] + + return part + + remove_existing = serializers.BooleanField( + label=_('Remove Existing Data'), + help_text=_('Remove existing BOM items before copying') + ) + + def save(self): + """ + Actually duplicate the BOM + """ + + base_part = self.context['part'] + + data = self.validated_data + + part = data['part'] + clear = data.get('remove_existing', True) + + base_part.copy_bom_from(part, clear=clear) diff --git a/InvenTree/part/templates/part/bom_duplicate.html b/InvenTree/part/templates/part/bom_duplicate.html deleted file mode 100644 index 1d8ccc7d1a..0000000000 --- a/InvenTree/part/templates/part/bom_duplicate.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends "modal_form.html" %} -{% load i18n %} - -{% block pre_form_content %} - -
- {% trans "Select parent part to copy BOM from" %} -
- -{% if part.has_bom %} -