mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Fix export of order data (#4714)
* Adds extra unit test for exporting sales orders - Exporting sales orders to .xls currently throws exception * Fix 'total_price' field when exporting orders * Fix for unit test
This commit is contained in:
parent
f6021c4749
commit
f6831558a4
@ -265,8 +265,7 @@ class InvenTreeAPITestCase(ExchangeRateMixin, UserMixin, APITestCase):
|
|||||||
"""Download a file from the server, and return an in-memory file."""
|
"""Download a file from the server, and return an in-memory file."""
|
||||||
response = self.client.get(url, data=data, format='json')
|
response = self.client.get(url, data=data, format='json')
|
||||||
|
|
||||||
if expected_code is not None:
|
self.checkResponse(url, 'DOWNLOAD_FILE', expected_code, response)
|
||||||
self.assertEqual(response.status_code, expected_code)
|
|
||||||
|
|
||||||
# Check that the response is of the correct type
|
# Check that the response is of the correct type
|
||||||
if not isinstance(response, StreamingHttpResponse):
|
if not isinstance(response, StreamingHttpResponse):
|
||||||
|
@ -24,6 +24,32 @@ class ProjectCodeResourceMixin:
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
class TotalPriceResourceMixin:
|
||||||
|
"""Mixin for exporting total price data"""
|
||||||
|
|
||||||
|
total_price = Field(attribute='total_price', column_name=_('Total Price'))
|
||||||
|
|
||||||
|
def dehydrate_total_price(self, order):
|
||||||
|
"""Return the total price amount, not the object itself"""
|
||||||
|
if order.total_price:
|
||||||
|
return order.total_price.amount
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
class PriceResourceMixin:
|
||||||
|
"""Mixin for 'price' field"""
|
||||||
|
|
||||||
|
price = Field(attribute='price', column_name=_('Price'))
|
||||||
|
|
||||||
|
def dehydrate_price(self, line):
|
||||||
|
"""Return the price amount, not the object itself"""
|
||||||
|
if line.price:
|
||||||
|
return line.price.amount
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
# region general classes
|
# region general classes
|
||||||
class GeneralExtraLineAdmin:
|
class GeneralExtraLineAdmin:
|
||||||
"""Admin class template for the 'ExtraLineItem' models"""
|
"""Admin class template for the 'ExtraLineItem' models"""
|
||||||
@ -108,7 +134,7 @@ class SalesOrderAdmin(ImportExportModelAdmin):
|
|||||||
autocomplete_fields = ('customer',)
|
autocomplete_fields = ('customer',)
|
||||||
|
|
||||||
|
|
||||||
class PurchaseOrderResource(ProjectCodeResourceMixin, InvenTreeResource):
|
class PurchaseOrderResource(ProjectCodeResourceMixin, TotalPriceResourceMixin, InvenTreeResource):
|
||||||
"""Class for managing import / export of PurchaseOrder data."""
|
"""Class for managing import / export of PurchaseOrder data."""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -127,7 +153,7 @@ class PurchaseOrderResource(ProjectCodeResourceMixin, InvenTreeResource):
|
|||||||
overdue = Field(attribute='is_overdue', widget=widgets.BooleanWidget(), readonly=True)
|
overdue = Field(attribute='is_overdue', widget=widgets.BooleanWidget(), readonly=True)
|
||||||
|
|
||||||
|
|
||||||
class PurchaseOrderLineItemResource(InvenTreeResource):
|
class PurchaseOrderLineItemResource(PriceResourceMixin, InvenTreeResource):
|
||||||
"""Class for managing import / export of PurchaseOrderLineItem data."""
|
"""Class for managing import / export of PurchaseOrderLineItem data."""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -146,7 +172,7 @@ class PurchaseOrderLineItemResource(InvenTreeResource):
|
|||||||
SKU = Field(attribute='part__SKU', readonly=True)
|
SKU = Field(attribute='part__SKU', readonly=True)
|
||||||
|
|
||||||
|
|
||||||
class PurchaseOrderExtraLineResource(InvenTreeResource):
|
class PurchaseOrderExtraLineResource(PriceResourceMixin, InvenTreeResource):
|
||||||
"""Class for managing import / export of PurchaseOrderExtraLine data."""
|
"""Class for managing import / export of PurchaseOrderExtraLine data."""
|
||||||
|
|
||||||
class Meta(GeneralExtraLineMeta):
|
class Meta(GeneralExtraLineMeta):
|
||||||
@ -155,7 +181,7 @@ class PurchaseOrderExtraLineResource(InvenTreeResource):
|
|||||||
model = models.PurchaseOrderExtraLine
|
model = models.PurchaseOrderExtraLine
|
||||||
|
|
||||||
|
|
||||||
class SalesOrderResource(ProjectCodeResourceMixin, InvenTreeResource):
|
class SalesOrderResource(ProjectCodeResourceMixin, TotalPriceResourceMixin, InvenTreeResource):
|
||||||
"""Class for managing import / export of SalesOrder data."""
|
"""Class for managing import / export of SalesOrder data."""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -174,7 +200,7 @@ class SalesOrderResource(ProjectCodeResourceMixin, InvenTreeResource):
|
|||||||
overdue = Field(attribute='is_overdue', widget=widgets.BooleanWidget(), readonly=True)
|
overdue = Field(attribute='is_overdue', widget=widgets.BooleanWidget(), readonly=True)
|
||||||
|
|
||||||
|
|
||||||
class SalesOrderLineItemResource(InvenTreeResource):
|
class SalesOrderLineItemResource(PriceResourceMixin, InvenTreeResource):
|
||||||
"""Class for managing import / export of SalesOrderLineItem data."""
|
"""Class for managing import / export of SalesOrderLineItem data."""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -203,7 +229,7 @@ class SalesOrderLineItemResource(InvenTreeResource):
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
class SalesOrderExtraLineResource(InvenTreeResource):
|
class SalesOrderExtraLineResource(PriceResourceMixin, InvenTreeResource):
|
||||||
"""Class for managing import / export of SalesOrderExtraLine data."""
|
"""Class for managing import / export of SalesOrderExtraLine data."""
|
||||||
|
|
||||||
class Meta(GeneralExtraLineMeta):
|
class Meta(GeneralExtraLineMeta):
|
||||||
@ -290,7 +316,7 @@ class SalesOrderAllocationAdmin(ImportExportModelAdmin):
|
|||||||
autocomplete_fields = ('line', 'shipment', 'item',)
|
autocomplete_fields = ('line', 'shipment', 'item',)
|
||||||
|
|
||||||
|
|
||||||
class ReturnOrderResource(ProjectCodeResourceMixin, InvenTreeResource):
|
class ReturnOrderResource(ProjectCodeResourceMixin, TotalPriceResourceMixin, InvenTreeResource):
|
||||||
"""Class for managing import / export of ReturnOrder data"""
|
"""Class for managing import / export of ReturnOrder data"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -327,7 +353,7 @@ class ReturnOrderAdmin(ImportExportModelAdmin):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ReturnOrderLineItemResource(InvenTreeResource):
|
class ReturnOrderLineItemResource(PriceResourceMixin, InvenTreeResource):
|
||||||
"""Class for managing import / export of ReturnOrderLineItem data"""
|
"""Class for managing import / export of ReturnOrderLineItem data"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -350,7 +376,7 @@ class ReturnOrderLineItemAdmin(ImportExportModelAdmin):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ReturnOrderExtraLineClass(InvenTreeResource):
|
class ReturnOrderExtraLineClass(PriceResourceMixin, InvenTreeResource):
|
||||||
"""Class for managing import/export of ReturnOrderExtraLine data"""
|
"""Class for managing import/export of ReturnOrderExtraLine data"""
|
||||||
|
|
||||||
class Meta(GeneralExtraLineMeta):
|
class Meta(GeneralExtraLineMeta):
|
||||||
|
@ -1452,6 +1452,28 @@ class SalesOrderTest(OrderTest):
|
|||||||
self.assertGreaterEqual(n_events, 1)
|
self.assertGreaterEqual(n_events, 1)
|
||||||
self.assertEqual(number_orders_incl_complete, n_events)
|
self.assertEqual(number_orders_incl_complete, n_events)
|
||||||
|
|
||||||
|
def test_export(self):
|
||||||
|
"""Test we can export the SalesOrder list"""
|
||||||
|
|
||||||
|
n = models.SalesOrder.objects.count()
|
||||||
|
|
||||||
|
# Check there are some sales orders
|
||||||
|
self.assertGreater(n, 0)
|
||||||
|
|
||||||
|
for order in models.SalesOrder.objects.all():
|
||||||
|
# Reconstruct the total price
|
||||||
|
order.save()
|
||||||
|
|
||||||
|
# Download file, check we get a 200 response
|
||||||
|
for fmt in ['csv', 'xls', 'xlsx']:
|
||||||
|
self.download_file(
|
||||||
|
reverse('api-so-list'),
|
||||||
|
{'export': fmt},
|
||||||
|
decode=True if fmt == 'csv' else False,
|
||||||
|
expected_code=200,
|
||||||
|
expected_fn=f"InvenTree_SalesOrders.{fmt}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SalesOrderLineItemTest(OrderTest):
|
class SalesOrderLineItemTest(OrderTest):
|
||||||
"""Tests for the SalesOrderLineItem API."""
|
"""Tests for the SalesOrderLineItem API."""
|
||||||
|
Loading…
Reference in New Issue
Block a user