Refactored DuplicatePart form

- API endpoint now takes care of duplication of other data
This commit is contained in:
Oliver Walters 2021-08-05 00:16:42 +10:00
parent 2cb0b448b7
commit 0e8fb6a5ad
5 changed files with 43 additions and 132 deletions

View File

@ -651,6 +651,34 @@ class PartList(generics.ListCreateAPIView):
part.save(**{'add_category_templates': copy_templates}) 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 # Optionally create initial stock item
try: try:
initial_stock = Decimal(request.data.get('initial_stock', 0)) initial_stock = Decimal(request.data.get('initial_stock', 0))

View File

@ -486,12 +486,7 @@
{% if roles.part.add %} {% if roles.part.add %}
$("#part-duplicate").click(function() { $("#part-duplicate").click(function() {
launchModalForm( duplicatePart({{ part.pk }});
"{% url 'part-duplicate' part.id %}",
{
follow: true,
}
);
}); });
{% endif %} {% endif %}

View File

@ -40,7 +40,6 @@ 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'^duplicate/', views.PartDuplicate.as_view(), name='part-duplicate'),
url(r'^make-variant/', views.MakePartVariant.as_view(), name='make-part-variant'), 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'),

View File

@ -314,130 +314,6 @@ class MakePartVariant(AjaxCreateView):
return initials return initials
class PartDuplicate(AjaxCreateView):
""" View for duplicating an existing Part object.
- Part <pk> is provided in the URL '/part/<pk>/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): 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

@ -110,6 +110,19 @@ function partFields(options={}) {
html: `<hr><h4><i>{% trans "Part Duplication Options" %}</i></h4><hr>`, html: `<hr><h4><i>{% trans "Part Duplication Options" %}</i></h4><hr>`,
}; };
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 = { fields.copy_bom = {
type: 'boolean', type: 'boolean',
label: '{% trans "Copy BOM" %}', label: '{% trans "Copy BOM" %}',
@ -184,7 +197,7 @@ function duplicatePart(pk, options={}) {
success: function(response) { success: function(response) {
var fields = partFields({ var fields = partFields({
duplicate: true duplicate: pk,
}); });
constructForm('{% url "api-part-list" %}', { constructForm('{% url "api-part-list" %}', {