diff --git a/InvenTree/part/templates/part/variant_part.html b/InvenTree/part/templates/part/variant_part.html new file mode 100644 index 0000000000..eac8762947 --- /dev/null +++ b/InvenTree/part/templates/part/variant_part.html @@ -0,0 +1,12 @@ +{% extends "modal_form.html" %} + +{% block pre_form_content %} + +{{ block.super }} + +
+ Create new part variant
+ Create a new variant of template '{{ part.full_name }}'. +
+ +{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/variants.html b/InvenTree/part/templates/part/variants.html index 0cf9735364..98ac08a8d3 100644 --- a/InvenTree/part/templates/part/variants.html +++ b/InvenTree/part/templates/part/variants.html @@ -60,4 +60,13 @@ sortable: true, }); + $('#new-variant').click(function() { + launchModalForm( + "{% url 'make-part-variant' part.id %}", + { + follow: true, + } + ); + }); + {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index c8582160bb..0147cd4d07 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -24,6 +24,7 @@ part_detail_urls = [ url(r'^bom-export/?', views.BomDownload.as_view(), name='bom-export'), 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'), url(r'^variants/?', views.PartDetail.as_view(template_name='part/variants.html'), name='part-variants'), diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 02b5b19909..1d33cec347 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -124,6 +124,77 @@ class PartAttachmentDelete(AjaxDeleteView): } +class MakePartVariant(AjaxCreateView): + """ View for creating a new variant based on an existing template Part + + - Part is provided in the URL '/part//make_variant/' + - Automatically copy relevent data (BOM, etc, etc) + + """ + + model = Part + form_class = part_forms.EditPartForm + + ajax_form_title = 'Create Variant' + ajax_template_name = 'part/variant_part.html' + + def get_part_template(self): + return get_object_or_404(Part, id=self.kwargs['pk']) + + def get_context_data(self): + return { + 'part': self.get_part_template(), + } + + def get_form(self): + form = super(AjaxCreateView, self).get_form() + + # Hide some variant-related fields + form.fields['is_template'].widget = HiddenInput() + form.fields['variant_of'].widget = HiddenInput() + + return form + + def post(self, request, *args, **kwargs): + + form = self.get_form() + context = self.get_context_data() + part_template = self.get_part_template() + + valid = form.is_valid() + + data = { + 'form_valid': valid, + } + + if valid: + # Create the new part variant + part = form.save(commit=False) + part.variant_of = part_template + part.is_template = False + + part.save() + + data['pk'] = part.pk + data['text'] = str(part) + data['url'] = part.get_absolute_url() + + # Copy relevent information from the template part + part.deepCopy(part_template, bom=True) + + return self.renderJsonResponse(request, form, data, context=context) + + def get_initial(self): + + part_template = self.get_part_template() + + initials = model_to_dict(part_template) + initials['is_template'] = False + initials['variant_of'] = part_template + + return initials + + class PartDuplicate(AjaxCreateView): """ View for duplicating an existing Part object. @@ -209,7 +280,7 @@ class PartDuplicate(AjaxCreateView): original = self.get_part_to_copy() if original: - part.deepCopy(original, bom=deep_copy) + part.deepCopy(original, bom=deep_copy) try: data['url'] = part.get_absolute_url()