Refactor MakeVariant form

- Now is essentially identical to the DuplicatePart form
- Uses the API form structure
This commit is contained in:
Oliver Walters 2021-08-05 00:24:38 +10:00
parent 0e8fb6a5ad
commit aa4ed9feb0
6 changed files with 15 additions and 182 deletions

View File

@ -177,82 +177,6 @@ class SetPartCategoryForm(forms.Form):
part_category = TreeNodeChoiceField(queryset=PartCategory.objects.all(), required=True, help_text=_('Select part category')) part_category = TreeNodeChoiceField(queryset=PartCategory.objects.all(), required=True, help_text=_('Select part category'))
class EditPartForm(HelperForm):
"""
Form for editing a Part object.
"""
field_prefix = {
'keywords': 'fa-key',
'link': 'fa-link',
'IPN': 'fa-hashtag',
'default_expiry': 'fa-stopwatch',
}
bom_copy = forms.BooleanField(required=False,
initial=True,
help_text=_("Duplicate all BOM data for this part"),
label=_('Copy BOM'),
widget=forms.HiddenInput())
parameters_copy = forms.BooleanField(required=False,
initial=True,
help_text=_("Duplicate all parameter data for this part"),
label=_('Copy Parameters'),
widget=forms.HiddenInput())
confirm_creation = forms.BooleanField(required=False,
initial=False,
help_text=_('Confirm part creation'),
widget=forms.HiddenInput())
selected_category_templates = forms.BooleanField(required=False,
initial=False,
label=_('Include category parameter templates'),
widget=forms.HiddenInput())
parent_category_templates = forms.BooleanField(required=False,
initial=False,
label=_('Include parent categories parameter templates'),
widget=forms.HiddenInput())
initial_stock = forms.IntegerField(required=False,
initial=0,
label=_('Initial stock amount'),
help_text=_('Create stock for this part'))
class Meta:
model = Part
fields = [
'confirm_creation',
'category',
'selected_category_templates',
'parent_category_templates',
'name',
'IPN',
'description',
'revision',
'bom_copy',
'parameters_copy',
'keywords',
'variant_of',
'link',
'default_location',
'default_supplier',
'default_expiry',
'units',
'minimum_stock',
'initial_stock',
'component',
'assembly',
'is_template',
'trackable',
'purchaseable',
'salable',
'virtual',
]
class EditPartParameterTemplateForm(HelperForm): class EditPartParameterTemplateForm(HelperForm):
""" Form for editing a PartParameterTemplate object """ """ Form for editing a PartParameterTemplate object """

View File

@ -525,10 +525,11 @@
loadPartVariantTable($('#variants-table'), {{ part.pk }}); loadPartVariantTable($('#variants-table'), {{ part.pk }});
$('#new-variant').click(function() { $('#new-variant').click(function() {
launchModalForm(
"{% url 'make-part-variant' part.id %}", duplicatePart(
{{ part.pk}},
{ {
follow: true, variant: true,
} }
); );
}); });

View File

@ -155,25 +155,6 @@ class PartDetailTest(PartViewTestCase):
self.assertIn('streaming_content', dir(response)) self.assertIn('streaming_content', dir(response))
class PartTests(PartViewTestCase):
""" Tests for Part forms """
def test_part_duplicate(self):
""" Launch form to duplicate part """
# First try with an invalid part
response = self.client.get(reverse('part-duplicate', args=(9999,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse('part-duplicate', args=(1,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(response.status_code, 200)
def test_make_variant(self):
response = self.client.get(reverse('make-part-variant', args=(1,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(response.status_code, 200)
class PartRelatedTests(PartViewTestCase): class PartRelatedTests(PartViewTestCase):
def test_valid_create(self): def test_valid_create(self):

View File

@ -40,7 +40,7 @@ part_detail_urls = [
url(r'^bom-export/?', views.BomExport.as_view(), name='bom-export'), url(r'^bom-export/?', views.BomExport.as_view(), name='bom-export'),
url(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'), url(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'),
url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'), url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'),
url(r'^make-variant/', views.MakePartVariant.as_view(), name='make-part-variant'),
url(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'), url(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'),
url(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'), url(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'),

View File

@ -233,87 +233,6 @@ class PartSetCategory(AjaxUpdateView):
return ctx return ctx
class MakePartVariant(AjaxCreateView):
""" View for creating a new variant based on an existing template Part
- Part <pk> is provided in the URL '/part/<pk>/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['variant_of'].widget = HiddenInput()
# 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):
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()
bom_copy = str2bool(request.POST.get('bom_copy', False))
parameters_copy = str2bool(request.POST.get('parameters_copy', False))
# Copy relevent information from the template part
part.deep_copy(part_template, bom=bom_copy, parameters=parameters_copy)
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
initials['bom_copy'] = InvenTreeSetting.get_setting('PART_COPY_BOM')
initials['parameters_copy'] = InvenTreeSetting.get_setting('PART_COPY_PARAMETERS')
return initials
class PartImport(FileManagementFormView): class PartImport(FileManagementFormView):
''' Part: Upload file, match to fields and import parts(using multi-Step form) ''' ''' Part: Upload file, match to fields and import parts(using multi-Step form) '''
permission_required = 'part.add' permission_required = 'part.add'

View File

@ -189,22 +189,30 @@ function editPart(pk, options={}) {
} }
// Launch form to duplicate a part
function duplicatePart(pk, options={}) { function duplicatePart(pk, options={}) {
// First we need all the part information // First we need all the part information
inventreeGet(`/api/part/${pk}/`, {}, { inventreeGet(`/api/part/${pk}/`, {}, {
success: function(response) { success: function(data) {
var fields = partFields({ var fields = partFields({
duplicate: pk, duplicate: pk,
}); });
// If we are making a "variant" part
if (options.variant) {
// Override the "variant_of" field
data.variant_of = pk;
}
constructForm('{% url "api-part-list" %}', { constructForm('{% url "api-part-list" %}', {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
title: '{% trans "Duplicate Part" %}', title: '{% trans "Duplicate Part" %}',
data: response, data: data,
onSuccess: function(data) { onSuccess: function(data) {
// Follow the new part // Follow the new part
location.href = `/part/${data.pk}/`; location.href = `/part/${data.pk}/`;