mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Added match parts step, need to process fields data
This commit is contained in:
parent
7cdf0af04a
commit
64fb492b97
@ -18,25 +18,17 @@ class FileManager:
|
|||||||
name = ''
|
name = ''
|
||||||
|
|
||||||
# Fields which are absolutely necessary for valid upload
|
# Fields which are absolutely necessary for valid upload
|
||||||
REQUIRED_HEADERS = [
|
REQUIRED_HEADERS = []
|
||||||
'Quantity'
|
|
||||||
]
|
|
||||||
|
|
||||||
# Fields which are used for part matching (only one of them is needed)
|
# Fields which are used for part matching (only one of them is needed)
|
||||||
PART_MATCH_HEADERS = [
|
PART_MATCH_HEADERS = []
|
||||||
'Part_Name',
|
|
||||||
'Part_IPN',
|
|
||||||
'Part_ID',
|
|
||||||
]
|
|
||||||
|
|
||||||
# Fields which would be helpful but are not required
|
# Fields which would be helpful but are not required
|
||||||
OPTIONAL_HEADERS = [
|
OPTIONAL_HEADERS = []
|
||||||
]
|
|
||||||
|
|
||||||
EDITABLE_HEADERS = [
|
EDITABLE_HEADERS = []
|
||||||
]
|
|
||||||
|
|
||||||
HEADERS = REQUIRED_HEADERS + PART_MATCH_HEADERS + OPTIONAL_HEADERS
|
HEADERS = []
|
||||||
|
|
||||||
def __init__(self, file, name=None):
|
def __init__(self, file, name=None):
|
||||||
""" Initialize the FileManager class with a user-uploaded file object """
|
""" Initialize the FileManager class with a user-uploaded file object """
|
||||||
@ -48,6 +40,9 @@ class FileManager:
|
|||||||
# Process initial file
|
# Process initial file
|
||||||
self.process(file)
|
self.process(file)
|
||||||
|
|
||||||
|
# Update headers
|
||||||
|
self.update_headers()
|
||||||
|
|
||||||
def process(self, file):
|
def process(self, file):
|
||||||
""" Process file """
|
""" Process file """
|
||||||
|
|
||||||
@ -69,6 +64,37 @@ class FileManager:
|
|||||||
raise ValidationError(_(f'Error reading {self.name} file (invalid format)'))
|
raise ValidationError(_(f'Error reading {self.name} file (invalid format)'))
|
||||||
except tablib.core.InvalidDimensions:
|
except tablib.core.InvalidDimensions:
|
||||||
raise ValidationError(_(f'Error reading {self.name} file (incorrect dimension)'))
|
raise ValidationError(_(f'Error reading {self.name} file (incorrect dimension)'))
|
||||||
|
|
||||||
|
def update_headers(self):
|
||||||
|
""" Update headers """
|
||||||
|
|
||||||
|
self.HEADERS = self.REQUIRED_HEADERS + self.PART_MATCH_HEADERS + self.OPTIONAL_HEADERS
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
""" Setup headers depending on the file name """
|
||||||
|
|
||||||
|
if not self.name:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self.name == 'order':
|
||||||
|
self.REQUIRED_HEADERS = [
|
||||||
|
'Quantity',
|
||||||
|
]
|
||||||
|
|
||||||
|
self.PART_MATCH_HEADERS = [
|
||||||
|
'Manufacturer_MPN',
|
||||||
|
'Supplier_SKU',
|
||||||
|
]
|
||||||
|
|
||||||
|
self.OPTIONAL_HEADERS = [
|
||||||
|
'Unit_Price',
|
||||||
|
'Extended_Price',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Update headers
|
||||||
|
self.update_headers()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def guess_header(self, header, threshold=80):
|
def guess_header(self, header, threshold=80):
|
||||||
""" Try to match a header (from the file) to a list of known headers
|
""" Try to match a header (from the file) to a list of known headers
|
||||||
|
@ -117,22 +117,45 @@ class MultiStepFormView(SessionWizardView):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
form_list = []
|
form_list = []
|
||||||
|
form_steps_template = []
|
||||||
form_steps_description = []
|
form_steps_description = []
|
||||||
|
file_manager = None
|
||||||
media_folder = ''
|
media_folder = ''
|
||||||
file_storage = FileSystemStorage(settings.MEDIA_ROOT)
|
file_storage = FileSystemStorage(settings.MEDIA_ROOT)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
""" Override init method to set media folder """
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
self.process_media_folder()
|
||||||
|
|
||||||
|
def process_media_folder(self):
|
||||||
|
""" Process media folder """
|
||||||
|
|
||||||
if self.media_folder:
|
if self.media_folder:
|
||||||
media_folder_abs = os.path.join(settings.MEDIA_ROOT, self.media_folder)
|
media_folder_abs = os.path.join(settings.MEDIA_ROOT, self.media_folder)
|
||||||
if not os.path.exists(media_folder_abs):
|
if not os.path.exists(media_folder_abs):
|
||||||
os.mkdir(media_folder_abs)
|
os.mkdir(media_folder_abs)
|
||||||
self.file_storage = FileSystemStorage(location=media_folder_abs)
|
self.file_storage = FileSystemStorage(location=media_folder_abs)
|
||||||
|
|
||||||
|
def get_template_names(self):
|
||||||
|
""" Select template """
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get template
|
||||||
|
template = self.form_steps_template[int(self.steps.current)]
|
||||||
|
except IndexError:
|
||||||
|
return self.template_name
|
||||||
|
|
||||||
|
return template
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
""" Update context data """
|
||||||
|
|
||||||
|
# Retrieve current context
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
# Get description
|
|
||||||
|
# Get form description
|
||||||
try:
|
try:
|
||||||
description = self.form_steps_description[int(self.steps.current)]
|
description = self.form_steps_description[int(self.steps.current)]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
@ -309,9 +309,9 @@ class UploadFile(forms.Form):
|
|||||||
|
|
||||||
class MatchField(forms.Form):
|
class MatchField(forms.Form):
|
||||||
""" Step 2 """
|
""" Step 2 """
|
||||||
last_name = forms.CharField(max_length=100)
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MatchPart(forms.Form):
|
class MatchPart(forms.Form):
|
||||||
""" Step 3 """
|
""" Step 3 """
|
||||||
age = forms.IntegerField()
|
pass
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
{% extends "order/order_wizard/po_upload.html" %}
|
||||||
|
{% load inventree_extras %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block form %}
|
||||||
|
|
||||||
|
{% if missing_columns and missing_columns|length > 0 %}
|
||||||
|
<div class='alert alert-danger alert-block' role='alert'>
|
||||||
|
{% trans "Missing selections for the following required columns" %}:
|
||||||
|
<br>
|
||||||
|
<ul>
|
||||||
|
{% for col in missing_columns %}
|
||||||
|
<li>{{ col }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form method="post" action='' class='js-modal-form' enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{{ wizard.management_form }}
|
||||||
|
|
||||||
|
{% if wizard.steps.prev %}
|
||||||
|
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}" class="save btn btn-default">{% trans "Previous Step" %}</button>
|
||||||
|
{% endif %}
|
||||||
|
<button type="submit" class="save btn btn-default">{% trans "Submit Selections" %}</button>
|
||||||
|
|
||||||
|
<table class='table table-striped' style='margin-top: 12px'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>{% trans "File Fields" %}</th>
|
||||||
|
{% for col in columns %}
|
||||||
|
<th>
|
||||||
|
<div>
|
||||||
|
<input type='hidden' name='col_name_{{ forloop.counter0 }}' value='{{ col.name }}'/>
|
||||||
|
{{ col.name }}
|
||||||
|
<button class='btn btn-default btn-remove' onClick='removeColFromBomWizard()' id='del_col_{{ forloop.counter0 }}' style='display: inline; float: right;' title='{% trans "Remove column" %}'>
|
||||||
|
<span col_id='{{ forloop.counter0 }}' class='fas fa-trash-alt icon-red'></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>{% trans "Match Fields" %}</td>
|
||||||
|
{% for col in columns %}
|
||||||
|
<td>
|
||||||
|
<select class='select' id='id_col_{{ forloop.counter0 }}' name='col_guess_{{ forloop.counter0 }}'>
|
||||||
|
<option value=''>---------</option>
|
||||||
|
{% for req in headers %}
|
||||||
|
<option value='{{ req }}'{% if req == col.guess %}selected='selected'{% endif %}>{{ req }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
{% if col.duplicate %}
|
||||||
|
<p class='help-inline'>{% trans "Duplicate column selection" %}</p>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% for row in rows %}
|
||||||
|
{% with forloop.counter as row_index %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ row_index }}' style='display: inline; float: right;' title='{% trans "Remove row" %}'>
|
||||||
|
<span row_id='{{ row_index }}' class='fas fa-trash-alt icon-red'></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td>{{ row_index }}</td>
|
||||||
|
{% for item in row.data %}
|
||||||
|
<td>
|
||||||
|
<input type='hidden' name='row_{{ row_index }}_col_{{ forloop.counter0 }}' value='{{ item }}'/>
|
||||||
|
{{ item }}
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
112
InvenTree/order/templates/order/order_wizard/match_parts.html
Normal file
112
InvenTree/order/templates/order/order_wizard/match_parts.html
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
{% extends "order/order_wizard/po_upload.html" %}
|
||||||
|
{% load inventree_extras %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block form %}
|
||||||
|
|
||||||
|
{% if form_errors %}
|
||||||
|
<div class='alert alert-danger alert-block' role='alert'>
|
||||||
|
{% trans "Errors exist in the submitted data" %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form method="post" action='' class='js-modal-form' enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{{ wizard.management_form }}
|
||||||
|
|
||||||
|
{% if wizard.steps.prev %}
|
||||||
|
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}" class="save btn btn-default">{% trans "Previous Step" %}</button>
|
||||||
|
{% endif %}
|
||||||
|
<button type="submit" class="save btn btn-default">{% trans "Submit Selections" %}</button>
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<table class='table table-striped'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th>{% trans "Row" %}</th>
|
||||||
|
<th>{% trans "Select Part" %}</th>
|
||||||
|
{% for col in bom_columns %}
|
||||||
|
<th>
|
||||||
|
<input type='hidden' name='col_name_{{ forloop.counter0 }}' value='{{ col.name }}'/>
|
||||||
|
<input type='hidden' name='col_guess_{{ forloop.counter0 }}' value='{{ col.guess }}'/>
|
||||||
|
{% if col.guess %}
|
||||||
|
{{ col.guess }}
|
||||||
|
{% else %}
|
||||||
|
{{ col.name }}
|
||||||
|
{% endif %}
|
||||||
|
</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for row in bom_rows %}
|
||||||
|
<tr {% if row.errors %} style='background: #ffeaea;'{% endif %} part-name='{{ row.part_name }}' part-description='{{ row.description }}' part-select='#select_part_{{ row.index }}'>
|
||||||
|
<td>
|
||||||
|
<button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='{% trans "Remove row" %}'>
|
||||||
|
<span row_id='{{ forloop.counter }}' class='fas fa-trash-alt icon-red'></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
<td>{% add row.index 1 %}</td>
|
||||||
|
<td>
|
||||||
|
<button class='btn btn-default btn-create' onClick='newPartFromBomWizard()' id='new_part_row_{{ row.index }}' title='{% trans "Create new part" %}' type='button'>
|
||||||
|
<span row_id='{{ row.index }}' class='fas fa-plus icon-green'/>
|
||||||
|
</button>
|
||||||
|
<select class='select bomselect' id='select_part_{{ row.index }}' name='part_{{ row.index }}'>
|
||||||
|
<option value=''>--- {% trans "Select Part" %} ---</option>
|
||||||
|
{% for part in row.part_options %}
|
||||||
|
<option value='{{ part.id }}' {% if part.id == row.part.id %} selected='selected' {% elif part.id == row.part_match.id %} selected='selected' {% endif %}>
|
||||||
|
{{ part }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
{% if row.errors.part %}
|
||||||
|
<p class='help-inline'>{{ row.errors.part }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% for item in row.data %}
|
||||||
|
<td>
|
||||||
|
{% if item.column.guess == 'Part' %}
|
||||||
|
<i>{{ item.cell }}</i>
|
||||||
|
{% if row.errors.part %}
|
||||||
|
<p class='help-inline'>{{ row.errors.part }}</p>
|
||||||
|
{% endif %}
|
||||||
|
{% elif item.column.guess == 'Quantity' %}
|
||||||
|
<input name='quantity_{{ row.index }}' class='numberinput' type='number' min='1' step='any' value='{% decimal row.quantity %}'/>
|
||||||
|
{% if row.errors.quantity %}
|
||||||
|
<p class='help-inline'>{{ row.errors.quantity }}</p>
|
||||||
|
{% endif %}
|
||||||
|
{% elif item.column.guess == 'Reference' %}
|
||||||
|
<input name='reference_{{ row.index }}' value='{{ row.reference }}'/>
|
||||||
|
{% elif item.column.guess == 'Note' %}
|
||||||
|
<input name='notes_{{ row.index }}' value='{{ row.notes }}'/>
|
||||||
|
{% elif item.column.guess == 'Overage' %}
|
||||||
|
<input name='overage_{{ row.index }}' value='{{ row.overage }}'/>
|
||||||
|
{% else %}
|
||||||
|
{{ item.cell }}
|
||||||
|
{% endif %}
|
||||||
|
<input type='hidden' name='row_{{ row.index }}_col_{{ forloop.counter0 }}' value='{{ item.cell }}'/>
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js_ready %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
$('.bomselect').select2({
|
||||||
|
dropdownAutoWidth: true,
|
||||||
|
matcher: partialMatcher,
|
||||||
|
});
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -1,5 +1,4 @@
|
|||||||
{% extends "order/order_base.html" %}
|
{% extends "order/order_base.html" %}
|
||||||
|
|
||||||
{% load inventree_extras %}
|
{% load inventree_extras %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
@ -17,7 +16,11 @@
|
|||||||
|
|
||||||
<p>{% trans "Step" %} {{ wizard.steps.step1 }} {% trans "of" %} {{ wizard.steps.count }}
|
<p>{% trans "Step" %} {{ wizard.steps.step1 }} {% trans "of" %} {{ wizard.steps.count }}
|
||||||
{% if description %}- {{ description }}{% endif %}</p>
|
{% if description %}- {{ description }}{% endif %}</p>
|
||||||
<form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
|
|
||||||
|
{% block form %}
|
||||||
|
|
||||||
|
<form action="" method="post" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
<table>
|
<table>
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{{ wizard.management_form }}
|
{{ wizard.management_form }}
|
||||||
@ -29,15 +32,16 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
{% crispy wizard.form %}
|
{% crispy wizard.form %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
|
||||||
{% if wizard.steps.prev %}
|
|
||||||
|
|
||||||
|
{% if wizard.steps.prev %}
|
||||||
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}" class="save btn btn-default">{% trans "Previous Step" %}</button>
|
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}" class="save btn btn-default">{% trans "Previous Step" %}</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button type="submit" class="save btn btn-default">{% trans "Submit" %}</button>
|
<button type="submit" class="save btn btn-default">{% trans "Upload File" %}</button>
|
||||||
</form>
|
</form>
|
||||||
|
</table>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock form %}
|
||||||
|
{% endblock details %}
|
||||||
|
|
||||||
{% block js_ready %}
|
{% block js_ready %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
@ -567,21 +567,30 @@ class SalesOrderShip(AjaxUpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class PurchaseOrderUpload(MultiStepFormView):
|
class PurchaseOrderUpload(MultiStepFormView):
|
||||||
''' PurchaseOrder: Upload file and match to parts, using multi-Step form '''
|
''' PurchaseOrder: Upload file, match to fields and parts (using multi-Step form) '''
|
||||||
|
|
||||||
form_list = [
|
form_list = [
|
||||||
order_forms.UploadFile,
|
order_forms.UploadFile,
|
||||||
order_forms.MatchField,
|
order_forms.MatchField,
|
||||||
order_forms.MatchPart,
|
order_forms.MatchPart,
|
||||||
]
|
]
|
||||||
|
form_steps_template = [
|
||||||
|
'order/order_wizard/po_upload.html',
|
||||||
|
'order/order_wizard/match_fields.html',
|
||||||
|
'order/order_wizard/match_parts.html',
|
||||||
|
]
|
||||||
form_steps_description = [
|
form_steps_description = [
|
||||||
_("Upload File"),
|
_("Upload File"),
|
||||||
_("Select Fields"),
|
_("Match Fields"),
|
||||||
_("Select Parts"),
|
_("Match Parts"),
|
||||||
]
|
]
|
||||||
template_name = "order/po_upload.html"
|
|
||||||
media_folder = 'order_uploads/'
|
media_folder = 'order_uploads/'
|
||||||
|
|
||||||
|
# Used for data table
|
||||||
|
headers = None
|
||||||
|
rows = None
|
||||||
|
columns = None
|
||||||
|
|
||||||
def get_context_data(self, form, **kwargs):
|
def get_context_data(self, form, **kwargs):
|
||||||
context = super().get_context_data(form=form, **kwargs)
|
context = super().get_context_data(form=form, **kwargs)
|
||||||
|
|
||||||
@ -589,25 +598,52 @@ class PurchaseOrderUpload(MultiStepFormView):
|
|||||||
|
|
||||||
context.update({'order': order})
|
context.update({'order': order})
|
||||||
|
|
||||||
|
if self.headers:
|
||||||
|
context.update({'headers': self.headers})
|
||||||
|
# print(f'{self.headers}')
|
||||||
|
if self.columns:
|
||||||
|
context.update({'columns': self.columns})
|
||||||
|
# print(f'{self.columns}')
|
||||||
|
if self.rows:
|
||||||
|
context.update({'rows': self.rows})
|
||||||
|
# print(f'{self.rows}')
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_form_step_data(self, form):
|
def process_step(self, form):
|
||||||
# print(f'{self.steps.current=}\n{form.data=}')
|
print(f'{self.steps.current=} | {form.data}')
|
||||||
return form.data
|
return self.get_form_step_data(form)
|
||||||
|
|
||||||
|
# def get_all_cleaned_data(self):
|
||||||
|
# cleaned_data = super().get_all_cleaned_data()
|
||||||
|
# print(f'{self.steps.current=} | {cleaned_data}')
|
||||||
|
# return cleaned_data
|
||||||
|
|
||||||
|
# def get_form_step_data(self, form):
|
||||||
|
# print(f'{self.steps.current=} | {form.data}')
|
||||||
|
# return form.data
|
||||||
|
|
||||||
def get_form_step_files(self, form):
|
def get_form_step_files(self, form):
|
||||||
# Check if user completed file upload
|
# Check if user completed file upload
|
||||||
if self.steps.current == '0':
|
if self.steps.current == '0':
|
||||||
# Extract columns and rows from FileManager
|
# Retrieve FileManager instance from form
|
||||||
self.extractDataFromFile(form.file_manager)
|
self.file_manager = form.file_manager
|
||||||
|
# Setup FileManager for order upload
|
||||||
|
setup_valid = self.file_manager.setup()
|
||||||
|
if setup_valid:
|
||||||
|
# Set headers
|
||||||
|
self.headers = self.file_manager.HEADERS
|
||||||
|
# Set columns and rows
|
||||||
|
self.columns = self.file_manager.columns()
|
||||||
|
self.rows = self.file_manager.rows()
|
||||||
|
|
||||||
return form.files
|
return form.files
|
||||||
|
|
||||||
def extractDataFromFile(self, file_manager):
|
def post(self, request, *args, **kwargs):
|
||||||
""" Read data from the file """
|
""" Perform the various 'POST' requests required.
|
||||||
|
"""
|
||||||
self.columns = file_manager.columns()
|
print('Posting!')
|
||||||
self.rows = file_manager.rows()
|
return super().post(*args, **kwargs)
|
||||||
|
|
||||||
def done(self, form_list, **kwargs):
|
def done(self, form_list, **kwargs):
|
||||||
return HttpResponseRedirect(reverse('po-detail', kwargs={'pk': self.kwargs['pk']}))
|
return HttpResponseRedirect(reverse('po-detail', kwargs={'pk': self.kwargs['pk']}))
|
||||||
|
Loading…
Reference in New Issue
Block a user