From dda4569f76bf700cbc187daf51b29e19185bd69a Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 7 Aug 2019 09:52:49 +1000 Subject: [PATCH 1/5] Export selected parts - Select which parts to export in the table - Export base information - Include supplier part information --- .../InvenTree/static/script/inventree/part.js | 13 +++ InvenTree/part/models.py | 2 +- InvenTree/part/templates/part/category.html | 1 + InvenTree/part/urls.py | 3 + InvenTree/part/views.py | 85 +++++++++++++++++++ 5 files changed, 103 insertions(+), 1 deletion(-) diff --git a/InvenTree/InvenTree/static/script/inventree/part.js b/InvenTree/InvenTree/static/script/inventree/part.js index 71f78855f7..18909fff0d 100644 --- a/InvenTree/InvenTree/static/script/inventree/part.js +++ b/InvenTree/InvenTree/static/script/inventree/part.js @@ -241,4 +241,17 @@ function loadPartTable(table, url, options={}) { reload: true, }); }); + + $('#multi-part-export').click(function() { + var selections = $(table).bootstrapTable("getSelections"); + + var parts = ''; + + selections.forEach(function(item) { + parts += item.pk; + parts += ','; + }); + + location.href = '/part/export/?parts=' + parts; + }); } \ No newline at end of file diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 2e9e748e99..3c061472c9 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -858,7 +858,7 @@ class Part(models.Model): self.save() - def export_bom(self, **kwargs): + def export_bom(self, **kwargs): """ Export Bill of Materials to a spreadsheet file. Includes a row for each item in the BOM. Also includes extra information such as supplier data. diff --git a/InvenTree/part/templates/part/category.html b/InvenTree/part/templates/part/category.html index 4bbb606bec..1a4b1cb8a5 100644 --- a/InvenTree/part/templates/part/category.html +++ b/InvenTree/part/templates/part/category.html @@ -50,6 +50,7 @@ diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index e39375f032..3ec99e7255 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -78,6 +78,9 @@ part_urls = [ # Download a BOM upload template url(r'^bom_template/?', views.BomUploadTemplate.as_view(), name='bom-upload-template'), + # Export data for multiple parts + url(r'^export/', views.PartExport.as_view(), name='part-export'), + # Individual part url(r'^(?P\d+)/', include(part_detail_urls)), diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index fae82bfc72..16de788064 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -14,6 +14,8 @@ from django.views.generic import DetailView, ListView, FormView from django.forms.models import model_to_dict from django.forms import HiddenInput, CheckboxInput +import tablib + from fuzzywuzzy import fuzz from .models import PartCategory, Part, PartAttachment @@ -1159,6 +1161,89 @@ class BomUpload(FormView): return self.render_to_response(self.get_context_data(form=self.form)) +class PartExport(AjaxView): + """ Export a CSV file containing information on multiple parts """ + + def get(self, request, *args, **kwargs): + part = request.GET.get('parts', '') + parts = [] + + for pk in part.split(','): + try: + parts.append(Part.objects.get(pk=int(pk))) + except (Part.DoesNotExist, ValueError): + continue + + headers = [ + 'Name', + 'Description', + 'Category', + 'Category ID', + 'IPN', + 'Revision', + 'URL', + 'Notes', + 'Assembly', + 'Component', + 'Trackable', + 'Salable', + 'Active', + 'Virtual' + ] + + # Construct list of suppliers for each part + supplier_names = set() + + for part in parts: + supplier_parts = part.supplier_parts.all() + part.suppliers = {} + + for sp in supplier_parts: + name = sp.supplier.name + supplier_names.add(name) + part.suppliers[name] = sp + + if len(supplier_names) > 0: + headers.append('') + for name in supplier_names: + headers.append(name) + + data = tablib.Dataset(headers=headers) + + for part in parts: + line = [] + + line.append(part.name) + line.append(part.description) + line.append(str(part.category)) + line.append(part.category.pk) + line.append(part.IPN) + line.append(part.revision) + line.append(part.URL) + line.append(part.notes) + line.append(part.assembly) + line.append(part.component) + line.append(part.trackable) + line.append(part.salable) + line.append(part.active) + line.append(part.virtual) + + if len(supplier_names) > 0: + line.append('') + + for name in supplier_names: + sp = part.suppliers.get(name, None) + if sp: + line.append(sp.SKU) + else: + line.append('') + + data.append(line) + + csv = data.export('csv') + return DownloadFile(csv, 'InvenTree_Parts.csv') + + class BomUploadTemplate(AjaxView): """ Provide a BOM upload template file for download. From ab0da6aaaee0edcb61c9e89f0d0a099aa1902c76 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 7 Aug 2019 09:55:18 +1000 Subject: [PATCH 2/5] Include more part data in export --- InvenTree/part/views.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 16de788064..bd3bc252e7 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1175,6 +1175,7 @@ class PartExport(AjaxView): continue headers = [ + 'ID', 'Name', 'Description', 'Category', @@ -1182,9 +1183,11 @@ class PartExport(AjaxView): 'IPN', 'Revision', 'URL', + 'Keywords', 'Notes', 'Assembly', 'Component', + 'Template', 'Trackable', 'Salable', 'Active', @@ -1213,6 +1216,7 @@ class PartExport(AjaxView): for part in parts: line = [] + line.append(part.ID) line.append(part.name) line.append(part.description) line.append(str(part.category)) @@ -1220,9 +1224,11 @@ class PartExport(AjaxView): line.append(part.IPN) line.append(part.revision) line.append(part.URL) + line.append(part.keywords) line.append(part.notes) line.append(part.assembly) line.append(part.component) + line.append(part.template) line.append(part.trackable) line.append(part.salable) line.append(part.active) From 8904733ac075beef565df693cde1d9f12c749ef4 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 7 Aug 2019 10:05:12 +1000 Subject: [PATCH 3/5] Include part stock information --- InvenTree/part/views.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index bd3bc252e7..74adc490b8 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1191,7 +1191,12 @@ class PartExport(AjaxView): 'Trackable', 'Salable', 'Active', - 'Virtual' + 'Virtual', + 'Stock Info', # Spacer between part data and stock data + 'In Stock', + 'Allocated', + 'Building', + 'On Order', ] # Construct list of suppliers for each part @@ -1207,7 +1212,7 @@ class PartExport(AjaxView): part.suppliers[name] = sp if len(supplier_names) > 0: - headers.append('') + headers.append('Suppliers') for name in supplier_names: headers.append(name) @@ -1216,7 +1221,7 @@ class PartExport(AjaxView): for part in parts: line = [] - line.append(part.ID) + line.append(part.pk) line.append(part.name) line.append(part.description) line.append(str(part.category)) @@ -1228,12 +1233,19 @@ class PartExport(AjaxView): line.append(part.notes) line.append(part.assembly) line.append(part.component) - line.append(part.template) + line.append(part.is_template) line.append(part.trackable) line.append(part.salable) line.append(part.active) line.append(part.virtual) + # Stock information + line.append('') + line.append(part.total_stock) + line.append(part.allocation_count) + line.append(part.quantity_being_built) + line.append(part.on_order) + if len(supplier_names) > 0: line.append('') From 4fc2a22ba62f2ed896968a8120395654b1ece626 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 7 Aug 2019 10:07:30 +1000 Subject: [PATCH 4/5] PEP fix --- InvenTree/part/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 3c061472c9..2e9e748e99 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -858,7 +858,7 @@ class Part(models.Model): self.save() - def export_bom(self, **kwargs): + def export_bom(self, **kwargs): """ Export Bill of Materials to a spreadsheet file. Includes a row for each item in the BOM. Also includes extra information such as supplier data. From adbc4db3d5c854ae07c2564eaaa0793b213bf7d4 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 7 Aug 2019 10:11:00 +1000 Subject: [PATCH 5/5] Remove 'set part category' button (doesn't do anything) --- InvenTree/part/templates/part/category.html | 1 - 1 file changed, 1 deletion(-) diff --git a/InvenTree/part/templates/part/category.html b/InvenTree/part/templates/part/category.html index 1a4b1cb8a5..343d7a8c40 100644 --- a/InvenTree/part/templates/part/category.html +++ b/InvenTree/part/templates/part/category.html @@ -49,7 +49,6 @@