mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Refactored DuplicatePart form
- API endpoint now takes care of duplication of other data
This commit is contained in:
parent
2cb0b448b7
commit
0e8fb6a5ad
@ -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))
|
||||||
|
@ -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 %}
|
||||||
|
|
||||||
|
@ -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'),
|
||||||
|
|
||||||
|
@ -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'
|
||||||
|
@ -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" %}', {
|
||||||
|
Loading…
Reference in New Issue
Block a user