mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-07 07:48:50 +00:00
Adds ability to export sales order line table to a file (#4392)
* Adds ability to export sales order line table to a file * Fix expand / collapse buttons * Fix other expand / collapse buttons * Add export functionality for "extra" line items
This commit is contained in:
parent
71af30f0d2
commit
92a049be96
@ -26,20 +26,22 @@ from InvenTree.helpers import DownloadFile, str2bool
|
|||||||
from InvenTree.mixins import (CreateAPI, ListAPI, ListCreateAPI,
|
from InvenTree.mixins import (CreateAPI, ListAPI, ListCreateAPI,
|
||||||
RetrieveUpdateAPI, RetrieveUpdateDestroyAPI)
|
RetrieveUpdateAPI, RetrieveUpdateDestroyAPI)
|
||||||
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus
|
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus
|
||||||
from order.admin import (PurchaseOrderLineItemResource, PurchaseOrderResource,
|
from order.admin import (PurchaseOrderExtraLineResource,
|
||||||
SalesOrderResource)
|
PurchaseOrderLineItemResource, PurchaseOrderResource,
|
||||||
|
SalesOrderExtraLineResource,
|
||||||
|
SalesOrderLineItemResource, SalesOrderResource)
|
||||||
from part.models import Part
|
from part.models import Part
|
||||||
from plugin.serializers import MetadataSerializer
|
from plugin.serializers import MetadataSerializer
|
||||||
from users.models import Owner
|
from users.models import Owner
|
||||||
|
|
||||||
|
|
||||||
class GeneralExtraLineList:
|
class GeneralExtraLineList(APIDownloadMixin):
|
||||||
"""General template for ExtraLine API classes."""
|
"""General template for ExtraLine API classes."""
|
||||||
|
|
||||||
def get_serializer(self, *args, **kwargs):
|
def get_serializer(self, *args, **kwargs):
|
||||||
"""Return the serializer instance for this endpoint"""
|
"""Return the serializer instance for this endpoint"""
|
||||||
try:
|
try:
|
||||||
params = self.request.query_params
|
params = self.request.query_params3
|
||||||
|
|
||||||
kwargs['order_detail'] = str2bool(params.get('order_detail', False))
|
kwargs['order_detail'] = str2bool(params.get('order_detail', False))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@ -606,6 +608,15 @@ class PurchaseOrderExtraLineList(GeneralExtraLineList, ListCreateAPI):
|
|||||||
queryset = models.PurchaseOrderExtraLine.objects.all()
|
queryset = models.PurchaseOrderExtraLine.objects.all()
|
||||||
serializer_class = serializers.PurchaseOrderExtraLineSerializer
|
serializer_class = serializers.PurchaseOrderExtraLineSerializer
|
||||||
|
|
||||||
|
def download_queryset(self, queryset, export_format):
|
||||||
|
"""Download this queryset as a file"""
|
||||||
|
|
||||||
|
dataset = PurchaseOrderExtraLineResource().export(queryset=queryset)
|
||||||
|
filedata = dataset.export(export_format)
|
||||||
|
filename = f"InvenTree_ExtraPurchaseOrderLines.{export_format}"
|
||||||
|
|
||||||
|
return DownloadFile(filedata, filename)
|
||||||
|
|
||||||
|
|
||||||
class PurchaseOrderExtraLineDetail(RetrieveUpdateDestroyAPI):
|
class PurchaseOrderExtraLineDetail(RetrieveUpdateDestroyAPI):
|
||||||
"""API endpoint for detail view of a PurchaseOrderExtraLine object."""
|
"""API endpoint for detail view of a PurchaseOrderExtraLine object."""
|
||||||
@ -686,6 +697,7 @@ class SalesOrderList(APIDownloadMixin, ListCreateAPI):
|
|||||||
|
|
||||||
def download_queryset(self, queryset, export_format):
|
def download_queryset(self, queryset, export_format):
|
||||||
"""Download this queryset as a file"""
|
"""Download this queryset as a file"""
|
||||||
|
|
||||||
dataset = SalesOrderResource().export(queryset=queryset)
|
dataset = SalesOrderResource().export(queryset=queryset)
|
||||||
|
|
||||||
filedata = dataset.export(export_format)
|
filedata = dataset.export(export_format)
|
||||||
@ -857,7 +869,7 @@ class SalesOrderLineItemFilter(rest_filters.FilterSet):
|
|||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class SalesOrderLineItemList(ListCreateAPI):
|
class SalesOrderLineItemList(APIDownloadMixin, ListCreateAPI):
|
||||||
"""API endpoint for accessing a list of SalesOrderLineItem objects."""
|
"""API endpoint for accessing a list of SalesOrderLineItem objects."""
|
||||||
|
|
||||||
queryset = models.SalesOrderLineItem.objects.all()
|
queryset = models.SalesOrderLineItem.objects.all()
|
||||||
@ -898,6 +910,16 @@ class SalesOrderLineItemList(ListCreateAPI):
|
|||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
def download_queryset(self, queryset, export_format):
|
||||||
|
"""Download the requested queryset as a file"""
|
||||||
|
|
||||||
|
dataset = SalesOrderLineItemResource().export(queryset=queryset)
|
||||||
|
filedata = dataset.export(export_format)
|
||||||
|
|
||||||
|
filename = f"InvenTree_SalesOrderItems.{export_format}"
|
||||||
|
|
||||||
|
return DownloadFile(filedata, filename)
|
||||||
|
|
||||||
filter_backends = [
|
filter_backends = [
|
||||||
rest_filters.DjangoFilterBackend,
|
rest_filters.DjangoFilterBackend,
|
||||||
filters.SearchFilter,
|
filters.SearchFilter,
|
||||||
@ -924,6 +946,15 @@ class SalesOrderExtraLineList(GeneralExtraLineList, ListCreateAPI):
|
|||||||
queryset = models.SalesOrderExtraLine.objects.all()
|
queryset = models.SalesOrderExtraLine.objects.all()
|
||||||
serializer_class = serializers.SalesOrderExtraLineSerializer
|
serializer_class = serializers.SalesOrderExtraLineSerializer
|
||||||
|
|
||||||
|
def download_queryset(self, queryset, export_format):
|
||||||
|
"""Download this queryset as a file"""
|
||||||
|
|
||||||
|
dataset = SalesOrderExtraLineResource().export(queryset=queryset)
|
||||||
|
filedata = dataset.export(export_format)
|
||||||
|
filename = f"InvenTree_ExtraSalesOrderLines.{export_format}"
|
||||||
|
|
||||||
|
return DownloadFile(filedata, filename)
|
||||||
|
|
||||||
|
|
||||||
class SalesOrderExtraLineDetail(RetrieveUpdateDestroyAPI):
|
class SalesOrderExtraLineDetail(RetrieveUpdateDestroyAPI):
|
||||||
"""API endpoint for detail view of a SalesOrderExtraLine object."""
|
"""API endpoint for detail view of a SalesOrderExtraLine object."""
|
||||||
|
@ -31,8 +31,6 @@
|
|||||||
<div class='panel-content'>
|
<div class='panel-content'>
|
||||||
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
||||||
<div class='btn-group'>
|
<div class='btn-group'>
|
||||||
{% include "expand_rows.html" with label="sales-lines" %}
|
|
||||||
{% include "collapse_rows.html" with label="sales-lines" %}
|
|
||||||
{% include "filter_list.html" with id="sales-order-lines" %}
|
{% include "filter_list.html" with id="sales-order-lines" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -93,8 +91,6 @@
|
|||||||
{% if roles.sales_order.change %}
|
{% if roles.sales_order.change %}
|
||||||
<div id='pending-shipment-toolbar' class='btn-group' style='float: right;'>
|
<div id='pending-shipment-toolbar' class='btn-group' style='float: right;'>
|
||||||
<div class='btn-group' role='group'>
|
<div class='btn-group' role='group'>
|
||||||
{% include "expand_rows.html" with label="pending-shipments" %}
|
|
||||||
{% include "collapse_rows.html" with label="pending-shipments" %}
|
|
||||||
{% include "filter_list.html" with id="pending-shipments" %}
|
{% include "filter_list.html" with id="pending-shipments" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -111,8 +107,6 @@
|
|||||||
<div class='panel-content'>
|
<div class='panel-content'>
|
||||||
<div id='completed-shipment-toolbar' class='btn-group' style='float: right;'>
|
<div id='completed-shipment-toolbar' class='btn-group' style='float: right;'>
|
||||||
<div class='btn-group' role='group'>
|
<div class='btn-group' role='group'>
|
||||||
{% include "expand_rows.html" with label="completed-shipments" %}
|
|
||||||
{% include "collapse_rows.html" with label="completed-shipments" %}
|
|
||||||
{% include "filter_list.html" with id="completed-shipments" %}
|
{% include "filter_list.html" with id="completed-shipments" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
{% load i18n %}
|
|
||||||
|
|
||||||
<button id='{{ label }}-collapse' class='btn btn-outline-secondary' type='button' title='{% trans "Collapse all rows" %}'>
|
|
||||||
<span class='fas fa-compress'></span>
|
|
||||||
</button>
|
|
@ -1,5 +0,0 @@
|
|||||||
{% load i18n %}
|
|
||||||
|
|
||||||
<button id='{{ label }}-expand' class='btn btn-outline-secondary' type='button' title='{% trans "Expand all rows" %}'>
|
|
||||||
<span class='fas fa-expand'></span>
|
|
||||||
</button>
|
|
@ -2231,7 +2231,14 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
|
|||||||
|
|
||||||
var target = options.filter_target || '#filter-list-purchase-order-lines';
|
var target = options.filter_target || '#filter-list-purchase-order-lines';
|
||||||
|
|
||||||
setupFilterList('purchaseorderlineitem', $(table), target, {download: true});
|
setupFilterList(
|
||||||
|
'purchaseorderlineitem',
|
||||||
|
$(table),
|
||||||
|
target,
|
||||||
|
{
|
||||||
|
download: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
function setupCallbacks() {
|
function setupCallbacks() {
|
||||||
if (options.allow_edit) {
|
if (options.allow_edit) {
|
||||||
@ -2596,7 +2603,7 @@ function loadPurchaseOrderExtraLineTable(table, options={}) {
|
|||||||
|
|
||||||
var filter_target = options.filter_target || '#filter-list-purchase-order-extra-lines';
|
var filter_target = options.filter_target || '#filter-list-purchase-order-extra-lines';
|
||||||
|
|
||||||
setupFilterList('purchaseorderextraline', $(table), filter_target);
|
setupFilterList('purchaseorderextraline', $(table), filter_target, {download: true});
|
||||||
|
|
||||||
// Table columns to display
|
// Table columns to display
|
||||||
var columns = [
|
var columns = [
|
||||||
@ -3072,6 +3079,7 @@ function loadSalesOrderShipmentTable(table, options={}) {
|
|||||||
showColumns: true,
|
showColumns: true,
|
||||||
detailView: true,
|
detailView: true,
|
||||||
detailViewByClick: false,
|
detailViewByClick: false,
|
||||||
|
buttons: constructExpandCollapseButtons(table),
|
||||||
detailFilter: function(index, row) {
|
detailFilter: function(index, row) {
|
||||||
return row.allocations.length > 0;
|
return row.allocations.length > 0;
|
||||||
},
|
},
|
||||||
@ -3871,7 +3879,14 @@ function loadSalesOrderLineItemTable(table, options={}) {
|
|||||||
|
|
||||||
var filter_target = options.filter_target || '#filter-list-sales-order-lines';
|
var filter_target = options.filter_target || '#filter-list-sales-order-lines';
|
||||||
|
|
||||||
setupFilterList('salesorderlineitem', $(table), filter_target);
|
setupFilterList(
|
||||||
|
'salesorderlineitem',
|
||||||
|
$(table),
|
||||||
|
filter_target,
|
||||||
|
{
|
||||||
|
download: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Is the order pending?
|
// Is the order pending?
|
||||||
var pending = options.pending;
|
var pending = options.pending;
|
||||||
@ -4333,6 +4348,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
|
|||||||
uniqueId: 'pk',
|
uniqueId: 'pk',
|
||||||
detailView: show_detail,
|
detailView: show_detail,
|
||||||
detailViewByClick: false,
|
detailViewByClick: false,
|
||||||
|
buttons: constructExpandCollapseButtons(table),
|
||||||
detailFilter: function(index, row) {
|
detailFilter: function(index, row) {
|
||||||
if (pending) {
|
if (pending) {
|
||||||
// Order is pending
|
// Order is pending
|
||||||
@ -4395,7 +4411,7 @@ function loadSalesOrderExtraLineTable(table, options={}) {
|
|||||||
|
|
||||||
var filter_target = options.filter_target || '#filter-list-sales-order-extra-lines';
|
var filter_target = options.filter_target || '#filter-list-sales-order-extra-lines';
|
||||||
|
|
||||||
setupFilterList('salesorderextraline', $(table), filter_target);
|
setupFilterList('salesorderextraline', $(table), filter_target, {download: true});
|
||||||
|
|
||||||
// Table columns to display
|
// Table columns to display
|
||||||
var columns = [
|
var columns = [
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
reloadtable,
|
reloadtable,
|
||||||
renderLink,
|
renderLink,
|
||||||
reloadTableFilters,
|
reloadTableFilters,
|
||||||
|
constructExpandCollapseButtons,
|
||||||
constructOrderTableButtons,
|
constructOrderTableButtons,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -98,6 +99,28 @@ function constructOrderTableButtons(options={}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Construct buttons to expand / collapse all rows in a table
|
||||||
|
*/
|
||||||
|
function constructExpandCollapseButtons(table, idx=0) {
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
html: `<button type='button' name='${idx++}' class='btn btn-outline-secondary' title='{% trans "Expand all rows" %}'><span class='fas fa-expand'></span></button>`,
|
||||||
|
event: function() {
|
||||||
|
$(table).bootstrapTable('expandAllRows');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
html: `<button type='button' name='${idx++}' class='btn btn-outline-secondary' title='{% trans "Collapse all rows" %}'><span class='fas fa-compress'></span></button>`,
|
||||||
|
event: function() {
|
||||||
|
$(table).bootstrapTable('collapseAllRows');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return the 'selected' data rows from a bootstrap table.
|
/* Return the 'selected' data rows from a bootstrap table.
|
||||||
* If allowEmpty = false, and the returned dataset is empty,
|
* If allowEmpty = false, and the returned dataset is empty,
|
||||||
* then instead try to return *all* the data
|
* then instead try to return *all* the data
|
||||||
|
Loading…
x
Reference in New Issue
Block a user