From 0e8fb6a5ad6df073770c243f9af96336f920365f Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 5 Aug 2021 00:16:42 +1000 Subject: [PATCH] Refactored DuplicatePart form - API endpoint now takes care of duplication of other data --- InvenTree/part/api.py | 28 +++++ InvenTree/part/templates/part/part_base.html | 7 +- InvenTree/part/urls.py | 1 - InvenTree/part/views.py | 124 ------------------- InvenTree/templates/js/translated/part.js | 15 ++- 5 files changed, 43 insertions(+), 132 deletions(-) diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 88866ad58c..789ba9b9b7 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -651,6 +651,34 @@ class PartList(generics.ListCreateAPIView): part.save(**{'add_category_templates': copy_templates}) + # Optionally copy data from another part (e.g. when duplicating) + copy_from = request.data.get('copy_from', None) + + if copy_from is not None: + + try: + original = Part.objects.get(pk=copy_from) + + copy_bom = str2bool(request.data.get('copy_bom', False)) + copy_parameters = str2bool(request.data.get('copy_parameters', False)) + copy_image = str2bool(request.data.get('copy_image', True)) + + # Copy image? + if copy_image: + part.image = original.image + part.save() + + # Copy BOM? + if copy_bom: + part.copy_bom_from(original) + + # Copy parameter data? + if copy_parameters: + part.copy_parameters_from(original) + + except (ValueError, Part.DoesNotExist): + pass + # Optionally create initial stock item try: initial_stock = Decimal(request.data.get('initial_stock', 0)) diff --git a/InvenTree/part/templates/part/part_base.html b/InvenTree/part/templates/part/part_base.html index ec637412a8..0c29f1c26b 100644 --- a/InvenTree/part/templates/part/part_base.html +++ b/InvenTree/part/templates/part/part_base.html @@ -486,12 +486,7 @@ {% if roles.part.add %} $("#part-duplicate").click(function() { - launchModalForm( - "{% url 'part-duplicate' part.id %}", - { - follow: true, - } - ); + duplicatePart({{ part.pk }}); }); {% endif %} diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 0802a94f1a..53d28f7ccb 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -40,7 +40,6 @@ part_detail_urls = [ url(r'^bom-export/?', views.BomExport.as_view(), name='bom-export'), url(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'), url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'), - url(r'^duplicate/', views.PartDuplicate.as_view(), name='part-duplicate'), url(r'^make-variant/', views.MakePartVariant.as_view(), name='make-part-variant'), url(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'), diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 3e4b6c59d7..c4ae2aee77 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -314,130 +314,6 @@ class MakePartVariant(AjaxCreateView): return initials -class PartDuplicate(AjaxCreateView): - """ View for duplicating an existing Part object. - - - Part is provided in the URL '/part//copy/' - - Option for 'deep-copy' which will duplicate all BOM items (default = True) - """ - - model = Part - form_class = part_forms.EditPartForm - - ajax_form_title = _("Duplicate Part") - ajax_template_name = "part/copy_part.html" - - def get_data(self): - return { - 'success': _('Copied part') - } - - def get_part_to_copy(self): - try: - return Part.objects.get(id=self.kwargs['pk']) - except (Part.DoesNotExist, ValueError): - return None - - def get_context_data(self): - return { - 'part': self.get_part_to_copy() - } - - def get_form(self): - form = super(AjaxCreateView, self).get_form() - - # Force display of the 'bom_copy' widget - form.fields['bom_copy'].widget = CheckboxInput() - - # Force display of the 'parameters_copy' widget - form.fields['parameters_copy'].widget = CheckboxInput() - - return form - - def post(self, request, *args, **kwargs): - """ Capture the POST request for part duplication - - - If the bom_copy object is set, copy all the BOM items too! - - If the parameters_copy object is set, copy all the parameters too! - """ - - form = self.get_form() - - context = self.get_context_data() - - valid = form.is_valid() - - name = request.POST.get('name', None) - - if name: - matches = match_part_names(name) - - if len(matches) > 0: - # Display the first five closest matches - context['matches'] = matches[:5] - - # Enforce display of the checkbox - form.fields['confirm_creation'].widget = CheckboxInput() - - # Check if the user has checked the 'confirm_creation' input - confirmed = str2bool(request.POST.get('confirm_creation', False)) - - if not confirmed: - msg = _('Possible matches exist - confirm creation of new part') - form.add_error('confirm_creation', msg) - form.pre_form_warning = msg - valid = False - - data = { - 'form_valid': valid - } - - if valid: - # Create the new Part - part = form.save(commit=False) - - part.creation_user = request.user - part.save() - - data['pk'] = part.pk - data['text'] = str(part) - - bom_copy = str2bool(request.POST.get('bom_copy', False)) - parameters_copy = str2bool(request.POST.get('parameters_copy', False)) - - original = self.get_part_to_copy() - - if original: - part.deep_copy(original, bom=bom_copy, parameters=parameters_copy) - - try: - data['url'] = part.get_absolute_url() - except AttributeError: - pass - - if valid: - pass - - return self.renderJsonResponse(request, form, data, context=context) - - def get_initial(self): - """ Get initial data based on the Part to be copied from. - """ - - part = self.get_part_to_copy() - - if part: - initials = model_to_dict(part) - else: - initials = super(AjaxCreateView, self).get_initial() - - initials['bom_copy'] = str2bool(InvenTreeSetting.get_setting('PART_COPY_BOM', True)) - - initials['parameters_copy'] = str2bool(InvenTreeSetting.get_setting('PART_COPY_PARAMETERS', True)) - - return initials - - class PartImport(FileManagementFormView): ''' Part: Upload file, match to fields and import parts(using multi-Step form) ''' permission_required = 'part.add' diff --git a/InvenTree/templates/js/translated/part.js b/InvenTree/templates/js/translated/part.js index f8b410c9c0..a1d40f7bf4 100644 --- a/InvenTree/templates/js/translated/part.js +++ b/InvenTree/templates/js/translated/part.js @@ -110,6 +110,19 @@ function partFields(options={}) { html: `

{% trans "Part Duplication Options" %}


`, }; + fields.copy_from = { + type: 'integer', + hidden: true, + value: options.duplicate, + }, + + fields.copy_image = { + type: 'boolean', + label: '{% trans "Copy Image" %}', + help_text: '{% trans "Copy image from original part" %}', + value: true, + }, + fields.copy_bom = { type: 'boolean', label: '{% trans "Copy BOM" %}', @@ -184,7 +197,7 @@ function duplicatePart(pk, options={}) { success: function(response) { var fields = partFields({ - duplicate: true + duplicate: pk, }); constructForm('{% url "api-part-list" %}', {