diff --git a/InvenTree/part/templates/part/import_wizard/ajax_match_fields.html b/InvenTree/part/templates/part/import_wizard/ajax_match_fields.html new file mode 100644 index 0000000000..293ddbc4d8 --- /dev/null +++ b/InvenTree/part/templates/part/import_wizard/ajax_match_fields.html @@ -0,0 +1,89 @@ +{% extends "part/import_wizard/ajax_part_upload.html" %} +{% load inventree_extras %} +{% load i18n %} +{% load static %} + +{% block form_alert %} +{% if missing_columns and missing_columns|length > 0 %} + +{% endif %} +{% if duplicates and duplicates|length > 0 %} + +{% endif %} +{% endblock form_alert %} + +{% block form_content %} + + + {% trans "File Fields" %} + + {% for col in form %} + +
+ + {{ col.name }} + +
+ + {% endfor %} + + + + + {% trans "Match Fields" %} + + {% for col in form %} + + {{ col }} + {% for duplicate in duplicates %} + {% if duplicate == col.value %} + + {% endif %} + {% endfor %} + + {% endfor %} + + {% for row in rows %} + {% with forloop.counter as row_index %} + + + + + {{ row_index }} + {% for item in row.data %} + + + {{ item }} + + {% endfor %} + + {% endwith %} + {% endfor %} + +{% endblock form_content %} + +{% block js_ready %} +{{ block.super }} + +$('.fieldselect').select2({ + width: '100%', + matcher: partialMatcher, +}); + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/import_wizard/ajax_match_references.html b/InvenTree/part/templates/part/import_wizard/ajax_match_references.html new file mode 100644 index 0000000000..e57fb066d3 --- /dev/null +++ b/InvenTree/part/templates/part/import_wizard/ajax_match_references.html @@ -0,0 +1,84 @@ +{% extends "part/import_wizard/ajax_part_upload.html" %} +{% load inventree_extras %} +{% load i18n %} +{% load static %} +{% load crispy_forms_tags %} + +{% block form_alert %} +{% if form.errors %} +{% endif %} +{% if form_errors %} + +{% endif %} +{% endblock form_alert %} + +{% block form_content %} + + + + {% trans "Row" %} + {% for col in columns %} + + + + + {% if col.guess %} + {{ col.guess }} + {% else %} + {{ col.name }} + {% endif %} + + {% endfor %} + + + + {% comment %} Dummy row for javascript del_row method {% endcomment %} + {% for row in rows %} + + + + + + {% add row.index 1 %} + + {% for item in row.data %} + + {% if item.column.guess %} + {% with row_name=item.column.guess|lower %} + {% for field in form.visible_fields %} + {% if field.name == row|keyvalue:row_name %} + {{ field|as_crispy_field }} + {% endif %} + {% endfor %} + {% endwith %} + {% else %} + {{ item.cell }} + {% endif %} + + + {% endfor %} + + {% endfor %} + +{% endblock form_content %} + +{% block form_buttons_bottom %} +{% endblock form_buttons_bottom %} + +{% block js_ready %} +{{ block.super }} + +$('.bomselect').select2({ + dropdownAutoWidth: true, + matcher: partialMatcher, +}); + +$('.currencyselect').select2({ + dropdownAutoWidth: true, +}); + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/import_wizard/ajax_part_upload.html b/InvenTree/part/templates/part/import_wizard/ajax_part_upload.html new file mode 100644 index 0000000000..f2a1e5c844 --- /dev/null +++ b/InvenTree/part/templates/part/import_wizard/ajax_part_upload.html @@ -0,0 +1,33 @@ +{% extends "modal_form.html" %} + +{% load inventree_extras %} +{% load i18n %} + +{% block form %} + +{% if roles.part.change %} + +

{% blocktrans with step=wizard.steps.step1 count=wizard.steps.count %}Step {{step}} of {{count}}{% endblocktrans %} + {% if description %}- {{ description }}{% endif %}

+ + {% block form_alert %} + {% endblock form_alert %} + +
+ {% csrf_token %} + {% load crispy_forms_tags %} + + + {{ wizard.management_form }} + {% block form_content %} + {% crispy wizard.form %} + {% endblock form_content %} +
+ +{% else %} + +{% endif %} + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 131797ea03..5dbd0326d8 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -122,6 +122,7 @@ part_urls = [ # Upload a part url(r'^import/', views.PartImport.as_view(), name='part-import'), + url(r'^import-api/', views.PartImportAjax.as_view(), name='api-part-import'), # Create a new BOM item url(r'^bom/new/?', views.BomItemCreate.as_view(), name='bom-item-create'), diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 91ff3bacf6..0e3833cefc 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -41,7 +41,7 @@ from .models import PartSellPriceBreak from common.models import InvenTreeSetting from company.models import SupplierPart from common.files import FileManager -from common.views import FileManagementFormView +from common.views import FileManagementFormView, FileManagementAjaxView from stock.models import StockLocation @@ -874,6 +874,17 @@ class PartImport(FileManagementFormView): return HttpResponseRedirect(reverse('part-index')) +class PartImportAjax(FileManagementAjaxView, PartImport): + ajax_form_steps_template = [ + 'part/import_wizard/ajax_part_upload.html', + 'part/import_wizard/ajax_match_fields.html', + 'part/import_wizard/ajax_match_references.html', + ] + + def validate(self, obj, form, **kwargs): + return PartImport.validate(self, self.steps.current, form, **kwargs) + + class PartNotes(UpdateView): """ View for editing the 'notes' field of a Part object. Presents a live markdown editor. diff --git a/InvenTree/templates/InvenTree/settings/part.html b/InvenTree/templates/InvenTree/settings/part.html index c054ef7111..7c7245f96e 100644 --- a/InvenTree/templates/InvenTree/settings/part.html +++ b/InvenTree/templates/InvenTree/settings/part.html @@ -138,7 +138,7 @@ }); $("#import-part").click(function() { - launchModalForm("{% url 'part-import' %}", {}); + launchModalForm("{% url 'api-part-import' %}", {}); }); {% endblock %} \ No newline at end of file