Initial work towards uploading a BOM file

- Create a form with a single FileField
This commit is contained in:
Oliver Walters 2019-05-24 23:56:36 +10:00
parent 2dc43f0cf1
commit 8b207d0d1d
4 changed files with 74 additions and 13 deletions

View File

@ -38,24 +38,15 @@ class BomValidateForm(HelperForm):
]
class BomExportForm(HelperForm):
class BomImportForm(HelperForm):
""" Form for importing a BOM. Provides a file input box for upload """
# TODO - Define these choices somewhere else, and import them here
format_choices = (
('csv', 'CSV'),
('pdf', 'PDF'),
('xml', 'XML'),
('xlsx', 'XLSX'),
('html', 'HTML')
)
# Select export type
format = forms.CharField(label='Format', widget=forms.Select(choices=format_choices), required='true', help_text='Select export format')
bom_file = forms.FileField(label='BOM file', required=True, help_text="Select BOM file to upload")
class Meta:
model = Part
fields = [
'format',
'bom_file',
]

View File

@ -34,6 +34,7 @@
<div id='button-toolbar' class="btn-group" role="group" aria-label="...">
{% if editing_enabled %}
<button class='btn btn-danger' type='button' title='Remove selected BOM items' id='bom-item-delete'><span class='glyphicon glyphicon-trash'></span></button>
<button class='btn btn-primary' type='button' title='Import BOM data' id='bom-upload'><span class='glyphicon glyphicon-open-file'></span></button>
<button class='btn btn-primary' type='button' title='New BOM Item' id='bom-item-new'><span class='glyphicon glyphicon-plus'></span></button>
<button class='btn btn-success' type='button' title='Finish Editing' id='editing-finished'><span class='glyphicon glyphicon-ok'></span></button>
{% else %}
@ -106,6 +107,12 @@
);
});
$("#bom-upload").click(function() {
launchModalForm(
"{% url 'bom-import' part.id %}",
);
});
{% else %}
$("#validate-bom").click(function() {

View File

@ -22,6 +22,7 @@ part_detail_urls = [
url(r'^edit/?', views.PartEdit.as_view(), name='part-edit'),
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
url(r'^bom-export/?', views.BomDownload.as_view(), name='bom-export'),
url(r'^bom-import/?', views.BomUpload.as_view(), name='bom-import'),
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'),

View File

@ -616,6 +616,68 @@ class BomValidate(AjaxUpdateView):
return self.renderJsonResponse(request, form, data, context=self.get_context())
class BomUpload(AjaxView):
""" View for uploading a BOM file, and handling BOM data importing.
The BOM upload process is as follows:
1. (Client) Select and upload BOM file
2. (Server) Verify that supplied file is a file compatible with tablib library
3. (Server) Introspect data file, try to find sensible columns / values / etc
4. (Server) Send suggestions back to the client
5. (Client) Makes choices based on suggestions:
- Accept automatic matching to parts found in database
- Accept suggestions for 'partial' or 'fuzzy' matches
- Create new parts in case of parts not being available
6. (Client) Sends updated dataset back to server
7. (Server) Check POST data for validity, sanity checking, etc.
8. (Server) Respond to POST request
- If data are valid, proceed to 9.
- If data not valid, return to 4.
9. (Server) Send confirmation form to user
- Display the actions which will occur
- Provide final "CONFIRM" button
10. (Client) Confirm final changes
11. (Server) Apply changes to database, update BOM items.
During these steps, data are passed between the server/client as JSON objects.
"""
def get_form(self):
""" Return the correct form for the given step in the upload process """
if 1 or self.request.method == 'GET':
form = part_forms.BomImportForm()
return form
def get(self, request, *args, **kwargs):
""" Perform the initial 'GET' request.
Initially returns a form for file upload """
# A valid Part object must be supplied. This is the 'parent' part for the BOM
part = get_object_or_404(Part, pk=self.kwargs['pk'])
form = self.get_form()
return self.renderJsonResponse(request, form)
def post(self, request, *args, **kwargs):
""" Perform the various 'POST' requests required.
"""
data = {
'form_valid': False,
}
form = self.get_form()
form.errors['bom_file'] = ['Nah mate']
return self.renderJsonResponse(request, form, data=data)
class BomDownload(AjaxView):
"""
Provide raw download of a BOM file.