List PO/SO/BO by reference in API (#4083)

* API: Add filter by reference to SO, PO. Add filtering by customer to SO list

* API: Add filtering by reference to Build order list

* Add test for changes

* Increment API version

* Add test for BO reference

* Add missing description of API version
This commit is contained in:
miggland 2022-12-21 11:48:30 +01:00 committed by GitHub
parent 0e8563ebee
commit d4341e81f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 3 deletions

View File

@ -2,11 +2,14 @@
# InvenTree API version
INVENTREE_API_VERSION = 83
INVENTREE_API_VERSION = 84
"""
Increment this API version number whenever there is a significant change to the API that any clients need to know about
v84 -> 2022-12-21: https://github.com/inventree/InvenTree/pull/4083
- Add support for listing PO, BO, SO by their reference
v83 -> 2022-11-19 : https://github.com/inventree/InvenTree/pull/3949
- Add support for structural Stock locations

View File

@ -65,6 +65,13 @@ class BuildFilter(rest_filters.FilterSet):
return queryset
# Exact match for reference
reference = rest_filters.CharFilter(
label='Filter by exact reference',
field_name='reference',
lookup_expr="iexact"
)
class BuildList(APIDownloadMixin, ListCreateAPI):
"""API endpoint for accessing a list of Build objects.

View File

@ -63,6 +63,14 @@ class TestBuildAPI(InvenTreeAPITestCase):
response = self.client.get(url, {'part': 99999}, format='json')
self.assertEqual(len(response.data), 0)
# Get a certain reference
response = self.client.get(url, {'reference': 'BO-0001'}, format='json')
self.assertEqual(len(response.data), 1)
# Get a certain reference
response = self.client.get(url, {'reference': 'BO-9999XX'}, format='json')
self.assertEqual(len(response.data), 0)
def test_get_build_item_list(self):
"""Test that we can retrieve list of BuildItem objects."""
url = reverse('api-build-item-list')

View File

@ -78,8 +78,15 @@ class GeneralExtraLineList:
]
class PurchaseOrderFilter(rest_filters.FilterSet):
"""Custom API filters for the PurchaseOrderList endpoint."""
class OrderFilter(rest_filters.FilterSet):
"""Base class for custom API filters for the OrderList endpoint."""
# Exact match for reference
reference = rest_filters.CharFilter(
label='Filter by exact reference',
field_name='reference',
lookup_expr="iexact"
)
assigned_to_me = rest_filters.BooleanFilter(label='assigned_to_me', method='filter_assigned_to_me')
@ -97,6 +104,9 @@ class PurchaseOrderFilter(rest_filters.FilterSet):
return queryset
class PurchaseOrderFilter(OrderFilter):
"""Custom API filters for the PurchaseOrderList endpoint."""
class Meta:
"""Metaclass options."""
@ -106,6 +116,17 @@ class PurchaseOrderFilter(rest_filters.FilterSet):
]
class SalesOrderFilter(OrderFilter):
"""Custom API filters for the SalesOrderList endpoint."""
class Meta:
"""Metaclass options."""
model = models.SalesOrder
fields = [
'customer',
]
class PurchaseOrderList(APIDownloadMixin, ListCreateAPI):
"""API endpoint for accessing a list of PurchaseOrder objects.
@ -613,6 +634,7 @@ class SalesOrderList(APIDownloadMixin, ListCreateAPI):
queryset = models.SalesOrder.objects.all()
serializer_class = serializers.SalesOrderSerializer
filterset_class = SalesOrderFilter
def create(self, request, *args, **kwargs):
"""Save user information on create."""

View File

@ -72,6 +72,14 @@ class PurchaseOrderTest(OrderTest):
self.filter({'status': 10}, 3)
self.filter({'status': 40}, 1)
# Filter by "reference"
self.filter({'reference': 'PO-0001'}, 1)
self.filter({'reference': 'PO-9999'}, 0)
# Filter by "assigned_to_me"
self.filter({'assigned_to_me': 1}, 0)
self.filter({'assigned_to_me': 0}, 7)
# Filter by "part"
self.filter({'part': 1}, 2)
self.filter({'part': 2}, 0) # Part not assigned to any PO
@ -878,6 +886,14 @@ class SalesOrderTest(OrderTest):
self.filter({'status': 20}, 1) # SHIPPED
self.filter({'status': 99}, 0) # Invalid
# Filter by "reference"
self.filter({'reference': 'ABC123'}, 1)
self.filter({'reference': 'XXX999'}, 0)
# Filter by "assigned_to_me"
self.filter({'assigned_to_me': 1}, 0)
self.filter({'assigned_to_me': 0}, 5)
def test_overdue(self):
"""Test "overdue" status."""
self.filter({'overdue': True}, 0)