Merge pull request #2119 from SchrodingersGat/sales-order-export

Adds view for exporting sales order
This commit is contained in:
Oliver 2021-10-07 13:54:34 +11:00 committed by GitHub
commit 50d861e763
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 122 additions and 24 deletions

View File

@ -77,6 +77,14 @@ class POLineItemResource(ModelResource):
class SOLineItemResource(ModelResource):
""" Class for managing import / export of SOLineItem data """
part_name = Field(attribute='part__name', readonly=True)
IPN = Field(attribute='part__IPN', readonly=True)
description = Field(attribute='part__description', readonly=True)
fulfilled = Field(attribute='fulfilled_quantity', readonly=True)
class Meta:
model = SalesOrderLineItem
skip_unchanged = True

View File

@ -39,6 +39,9 @@ src="{% static 'img/blank_image.png' %}"
<button type='button' class='btn btn-default' id='print-order-report' title='{% trans "Print" %}'>
<span class='fas fa-print'></span>
</button>
<button type='button' class='btn btn-default' id='export-order' title='{% trans "Export order to file" %}'>
<span class='fas fa-file-download'></span>
</button>
{% if roles.purchase_order.change %}
<button type='button' class='btn btn-default' id='edit-order' title='{% trans "Edit order information" %}'>
<span class='fas fa-edit icon-green'></span>
@ -61,9 +64,6 @@ src="{% static 'img/blank_image.png' %}"
</button>
{% endif %}
{% endif %}
<button type='button' class='btn btn-default' id='export-order' title='{% trans "Export order to file" %}'>
<span class='fas fa-file-download'></span>
</button>
</div>
</div>
{% endblock %}
@ -224,7 +224,7 @@ $("#cancel-order").click(function() {
});
$("#export-order").click(function() {
location.href = "{% url 'po-export' order.id %}";
exportOrder('{% url "po-export" order.id %}');
});

View File

@ -50,6 +50,9 @@ src="{% static 'img/blank_image.png' %}"
<button type='button' class='btn btn-default' id='print-order-report' title='{% trans "Print" %}'>
<span class='fas fa-print'></span>
</button>
<button type='button' class='btn btn-default' id='export-order' title='{% trans "Export order to file" %}'>
<span class='fas fa-file-download'></span>
</button>
{% if roles.sales_order.change %}
<button type='button' class='btn btn-default' id='edit-order' title='{% trans "Edit order information" %}'>
<span class='fas fa-edit icon-green'></span>
@ -63,9 +66,11 @@ src="{% static 'img/blank_image.png' %}"
</button>
{% endif %}
{% endif %}
<!--
<button type='button' disabled='' class='btn btn-default' id='packing-list' title='{% trans "Packing List" %}'>
<span class='fas fa-clipboard-list'></span>
</button>
-->
</div>
</div>
{% endblock %}
@ -196,4 +201,8 @@ $('#print-order-report').click(function() {
printSalesOrderReports([{{ order.pk }}]);
});
$('#export-order').click(function() {
exportOrder('{% url "so-export" order.id %}');
});
{% endblock %}

View File

@ -36,6 +36,7 @@ purchase_order_urls = [
sales_order_detail_urls = [
url(r'^cancel/', views.SalesOrderCancel.as_view(), name='so-cancel'),
url(r'^ship/', views.SalesOrderShip.as_view(), name='so-ship'),
url(r'^export/', views.SalesOrderExport.as_view(), name='so-export'),
url(r'^.*$', views.SalesOrderDetail.as_view(), name='so-detail'),
]

View File

@ -23,7 +23,7 @@ from decimal import Decimal, InvalidOperation
from .models import PurchaseOrder, PurchaseOrderLineItem
from .models import SalesOrder, SalesOrderLineItem
from .models import SalesOrderAllocation
from .admin import POLineItemResource
from .admin import POLineItemResource, SOLineItemResource
from build.models import Build
from company.models import Company, SupplierPart # ManufacturerPart
from stock.models import StockItem
@ -436,6 +436,33 @@ class PurchaseOrderUpload(FileManagementFormView):
return HttpResponseRedirect(reverse('po-detail', kwargs={'pk': self.kwargs['pk']}))
class SalesOrderExport(AjaxView):
"""
Export a sales order
- File format can optionally be passed as a query parameter e.g. ?format=CSV
- Default file format is CSV
"""
model = SalesOrder
role_required = 'sales_order.view'
def get(self, request, *args, **kwargs):
order = get_object_or_404(SalesOrder, pk=self.kwargs.get('pk', None))
export_format = request.GET.get('format', 'csv')
filename = f"{str(order)} - {order.customer.name}.{export_format}"
dataset = SOLineItemResource().export(queryset=order.lines.all())
filedata = dataset.export(format=export_format)
return DownloadFile(filedata, filename)
class PurchaseOrderExport(AjaxView):
""" File download for a purchase order
@ -450,7 +477,7 @@ class PurchaseOrderExport(AjaxView):
def get(self, request, *args, **kwargs):
order = get_object_or_404(PurchaseOrder, pk=self.kwargs['pk'])
order = get_object_or_404(PurchaseOrder, pk=self.kwargs.get('pk', None))
export_format = request.GET.get('format', 'csv')

View File

@ -10,6 +10,7 @@
/* exported
attachClipboard,
enableDragAndDrop,
exportFormatOptions,
inventreeDocReady,
inventreeLoad,
inventreeSave,
@ -46,6 +47,31 @@ function attachClipboard(selector, containerselector, textElement) {
}
/**
* Return a standard list of export format options *
*/
function exportFormatOptions() {
return [
{
value: 'csv',
display_name: 'CSV',
},
{
value: 'tsv',
display_name: 'TSV',
},
{
value: 'xls',
display_name: 'XLS',
},
{
value: 'xlsx',
display_name: 'XLSX',
},
];
}
function inventreeDocReady() {
/* Run this function when the HTML document is loaded.
* This will be called for every page that extends "base.html"

View File

@ -21,6 +21,7 @@
/* exported
createSalesOrder,
editPurchaseOrderLineItem,
exportOrder,
loadPurchaseOrderLineItemTable,
loadPurchaseOrderTable,
loadSalesOrderAllocationTable,
@ -187,6 +188,49 @@ function newSupplierPartFromOrderWizard(e) {
});
}
/**
* Export an order (PurchaseOrder or SalesOrder)
*
* - Display a simple form which presents the user with export options
*
*/
function exportOrder(redirect_url, options={}) {
var format = options.format;
// If default format is not provided, lookup
if (!format) {
format = inventreeLoad('order-export-format', 'csv');
}
constructFormBody({}, {
title: '{% trans "Export Order" %}',
fields: {
format: {
label: '{% trans "Format" %}',
help_text: '{% trans "Select file format" %}',
required: true,
type: 'choice',
value: format,
choices: exportFormatOptions(),
}
},
onSubmit: function(fields, opts) {
var format = getFormFieldValue('format', fields['format'], opts);
// Save the format for next time
inventreeSave('order-export-format', format);
// Hide the modal
$(opts.modal).modal('hide');
// Download the file!
location.href = `${redirect_url}?format=${format}`;
}
});
}
function newPurchaseOrderFromOrderWizard(e) {
/* Create a new purchase order directly from an order form.
* Launches a secondary modal and (if successful),

View File

@ -98,24 +98,7 @@ function exportStock(params={}) {
required: true,
type: 'choice',
value: 'csv',
choices: [
{
value: 'csv',
display_name: 'CSV',
},
{
value: 'tsv',
display_name: 'TSV',
},
{
value: 'xls',
display_name: 'XLS',
},
{
value: 'xlsx',
display_name: 'XLSX',
},
],
choices: exportFormatOptions(),
},
sublocations: {
label: '{% trans "Include Sublocations" %}',