diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index e4417f939a..7c9308fbbe 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -11,6 +11,7 @@ from django.contrib.auth.models import User from django.urls import reverse from django.utils.translation import ugettext as _ +import tablib from datetime import datetime from company.models import Company, SupplierPart @@ -99,6 +100,55 @@ class PurchaseOrder(Order): help_text=_('Company') ) + def export_to_file(self, **kwargs): + """ Export order information to external file """ + + file_format = kwargs.get('format', 'csv').lower() + + data = tablib.Dataset(headers=[ + 'Line', + 'Part', + 'Description', + 'Manufacturer', + 'MPN', + 'Order Code', + 'Quantity', + 'Received', + 'Reference', + 'Notes', + ]) + + idx = 0 + + for item in self.lines.all(): + + line = [] + + line.append(idx) + + if item.part: + line.append(item.part.part.name) + line.append(item.part.part.description) + + line.append(item.part.manufacturer) + line.append(item.part.MPN) + line.append(item.part.SKU) + + else: + line += [[] * 5] + + line.append(item.quantity) + line.append(item.received) + line.append(item.reference) + line.append(item.notes) + + idx += 1 + + data.append(line) + + return data.export(file_format) + + def get_absolute_url(self): return reverse('purchase-order-detail', kwargs={'pk': self.id}) diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index 4360f4de4f..185eba4cad 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -64,6 +64,7 @@ InvenTree | {{ order }} {% if order.status == OrderStatus.PENDING and order.lines.count > 0 %} {% endif %} +

Order Items

@@ -152,6 +153,10 @@ $("#edit-order").click(function() { ); }); +$("#export-order").click(function() { + location.href = "{% url 'purchase-order-export' order.id %}"; +}); + {% if order.status == OrderStatus.PENDING %} $('#new-po-line').click(function() { launchModalForm("{% url 'po-line-item-create' %}", diff --git a/InvenTree/order/urls.py b/InvenTree/order/urls.py index 0c064ee9ee..695628bad0 100644 --- a/InvenTree/order/urls.py +++ b/InvenTree/order/urls.py @@ -14,6 +14,8 @@ purchase_order_detail_urls = [ url(r'^edit/?', views.PurchaseOrderEdit.as_view(), name='purchase-order-edit'), url(r'^issue/?', views.PurchaseOrderIssue.as_view(), name='purchase-order-issue'), + url(r'^export/?', views.PurchaseOrderExport.as_view(), name='purchase-order-export'), + url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='purchase-order-detail'), ] diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index ea9da7e373..578021b2cb 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -5,6 +5,7 @@ Django views for interacting with Order app # -*- coding: utf-8 -*- from __future__ import unicode_literals +from django.shortcuts import get_object_or_404 from django.utils.translation import ugettext as _ from django.views.generic import DetailView, ListView from django.forms import HiddenInput @@ -20,7 +21,7 @@ from part.models import Part from . import forms as order_forms from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView -from InvenTree.helpers import str2bool +from InvenTree.helpers import DownloadFile, str2bool from InvenTree.status_codes import OrderStatus @@ -142,6 +143,28 @@ class PurchaseOrderIssue(AjaxUpdateView): return self.renderJsonResponse(request, form, data) +class PurchaseOrderExport(AjaxView): + """ File download for a purchase order + + - File format can be optionally passed as a query param e.g. ?format=CSV + - Default file format is CSV + """ + + model = PurchaseOrder + + def get(self, request, *args, **kwargs): + + order = get_object_or_404(PurchaseOrder, pk=self.kwargs['pk']) + + export_format = request.GET.get('format', 'csv') + + filename = str(order) + '.' + export_format + + filedata = order.export_to_file(format=export_format) + + return DownloadFile(filedata, filename) + + class OrderParts(AjaxView): """ View for adding various SupplierPart items to a Purchase Order. diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 9f8b8652bd..1224d1de22 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -585,10 +585,6 @@ class BomDownload(AjaxView): # TODO - This should no longer extend an AjaxView! model = Part - # form_class = BomExportForm - # template_name = 'part/bom_export.html' - # ajax_form_title = 'Export Bill of Materials' - # context_object_name = 'part' def get(self, request, *args, **kwargs):