2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-16 20:15:44 +00:00

API date filter updates (#8544)

* Add 'stocktake_before' and 'stocktake_after' filters for StockItem API

* Enable new filters for StockItemTable

* Update CUI table filters

* Add more date filter options for orders

* Add date filters to BuildList

* Update BuildOrderTable filters

* Add more order date filters

* Cleanup PurchaseOrderFilter code

* Implement more PUI table filters

* Add "Completion Date" column to PurchaseOrderTable

* Update ReturnOrderTable

* Add 'text' option for TableFilter

* filter state management

* Bump API version

* Sorting for table filters

* Add playwright tests for stock table filtering

* Playwright updates

- Add some helper functions for common operations

* Refactoring for Playwright tests
This commit is contained in:
Oliver
2024-11-25 21:36:31 +11:00
committed by GitHub
parent 5e762bc7f7
commit 809a978f7d
22 changed files with 586 additions and 124 deletions

View File

@ -1,13 +1,20 @@
"""InvenTree API version information."""
# InvenTree API version
INVENTREE_API_VERSION = 283
INVENTREE_API_VERSION = 284
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
INVENTREE_API_TEXT = """
v284 - 2024-11-25 : https://github.com/inventree/InvenTree/pull/8544
- Adds new date filters to the StockItem API
- Adds new date filters to the BuildOrder API
- Adds new date filters to the SalesOrder API
- Adds new date filters to the PurchaseOrder API
- Adds new date filters to the ReturnOrder API
v283 - 2024-11-20 : https://github.com/inventree/InvenTree/pull/8524
- Adds "note" field to the PartRelated API endpoint

View File

@ -23,7 +23,7 @@ import build.serializers
from build.models import Build, BuildLine, BuildItem
import part.models
from users.models import Owner
from InvenTree.filters import SEARCH_ORDER_FILTER_ALIAS
from InvenTree.filters import InvenTreeDateFilter, SEARCH_ORDER_FILTER_ALIAS
class BuildFilter(rest_filters.FilterSet):
@ -179,6 +179,36 @@ class BuildFilter(rest_filters.FilterSet):
return queryset.exclude(project_code=None)
return queryset.filter(project_code=None)
created_before = InvenTreeDateFilter(
label=_('Created before'),
field_name='creation_date', lookup_expr='lt'\
)
created_after = InvenTreeDateFilter(
label=_('Created after'),
field_name='creation_date', lookup_expr='gt'
)
target_date_before = InvenTreeDateFilter(
label=_('Target date before'),
field_name='target_date', lookup_expr='lt'
)
target_date_after = InvenTreeDateFilter(
label=_('Target date after'),
field_name='target_date', lookup_expr='gt'
)
completed_before = InvenTreeDateFilter(
label=_('Completed before'),
field_name='completion_date', lookup_expr='lt'
)
completed_after = InvenTreeDateFilter(
label=_('Completed after'),
field_name='completion_date', lookup_expr='gt'
)
class BuildMixin:
"""Mixin class for Build API endpoints."""

View File

@ -21,7 +21,11 @@ import company.models
from generic.states.api import StatusView
from importer.mixins import DataExportViewMixin
from InvenTree.api import ListCreateDestroyAPIView, MetadataView
from InvenTree.filters import SEARCH_ORDER_FILTER, SEARCH_ORDER_FILTER_ALIAS
from InvenTree.filters import (
SEARCH_ORDER_FILTER,
SEARCH_ORDER_FILTER_ALIAS,
InvenTreeDateFilter,
)
from InvenTree.helpers import str2bool
from InvenTree.helpers_model import construct_absolute_url, get_base_url
from InvenTree.mixins import CreateAPI, ListAPI, ListCreateAPI, RetrieveUpdateDestroyAPI
@ -140,6 +144,22 @@ class OrderFilter(rest_filters.FilterSet):
queryset=Owner.objects.all(), field_name='responsible', label=_('Responsible')
)
created_before = InvenTreeDateFilter(
label=_('Created Before'), field_name='creation_date', lookup_expr='lt'
)
created_after = InvenTreeDateFilter(
label=_('Created After'), field_name='creation_date', lookup_expr='gt'
)
target_date_before = InvenTreeDateFilter(
label=_('Target Date Before'), field_name='target_date', lookup_expr='lt'
)
target_date_after = InvenTreeDateFilter(
label=_('Target Date After'), field_name='target_date', lookup_expr='gt'
)
class LineItemFilter(rest_filters.FilterSet):
"""Base class for custom API filters for order line item list(s)."""
@ -171,6 +191,41 @@ class PurchaseOrderFilter(OrderFilter):
model = models.PurchaseOrder
fields = ['supplier']
part = rest_filters.ModelChoiceFilter(
queryset=Part.objects.all(),
field_name='part',
label=_('Part'),
method='filter_part',
)
def filter_part(self, queryset, name, part: Part):
"""Filter by provided Part instance."""
orders = part.purchase_orders()
return queryset.filter(pk__in=[o.pk for o in orders])
supplier_part = rest_filters.ModelChoiceFilter(
queryset=company.models.SupplierPart.objects.all(),
label=_('Supplier Part'),
method='filter_supplier_part',
)
def filter_supplier_part(
self, queryset, name, supplier_part: company.models.SupplierPart
):
"""Filter by provided SupplierPart instance."""
orders = supplier_part.purchase_orders()
return queryset.filter(pk__in=[o.pk for o in orders])
completed_before = InvenTreeDateFilter(
label=_('Completed Before'), field_name='complete_date', lookup_expr='lt'
)
completed_after = InvenTreeDateFilter(
label=_('Completed After'), field_name='complete_date', lookup_expr='gt'
)
class PurchaseOrderMixin:
"""Mixin class for PurchaseOrder endpoints."""
@ -221,32 +276,6 @@ class PurchaseOrderList(PurchaseOrderMixin, DataExportViewMixin, ListCreateAPI):
params = self.request.query_params
# Attempt to filter by part
part = params.get('part', None)
if part is not None:
try:
part = Part.objects.get(pk=part)
queryset = queryset.filter(
id__in=[p.id for p in part.purchase_orders()]
)
except (Part.DoesNotExist, ValueError):
pass
# Attempt to filter by supplier part
supplier_part = params.get('supplier_part', None)
if supplier_part is not None:
try:
supplier_part = company.models.SupplierPart.objects.get(
pk=supplier_part
)
queryset = queryset.filter(
id__in=[p.id for p in supplier_part.purchase_orders()]
)
except (ValueError, company.models.SupplierPart.DoesNotExist):
pass
# Filter by 'date range'
min_date = params.get('min_date', None)
max_date = params.get('max_date', None)
@ -276,6 +305,7 @@ class PurchaseOrderList(PurchaseOrderMixin, DataExportViewMixin, ListCreateAPI):
'reference',
'supplier__name',
'target_date',
'complete_date',
'line_items',
'status',
'responsible',
@ -648,6 +678,14 @@ class SalesOrderFilter(OrderFilter):
# Now we have a list of matching IDs, filter the queryset
return queryset.filter(pk__in=sales_orders)
completed_before = InvenTreeDateFilter(
label=_('Completed Before'), field_name='shipment_date', lookup_expr='lt'
)
completed_after = InvenTreeDateFilter(
label=_('Completed After'), field_name='shipment_date', lookup_expr='gt'
)
class SalesOrderMixin:
"""Mixin class for SalesOrder endpoints."""
@ -1257,6 +1295,14 @@ class ReturnOrderFilter(OrderFilter):
# Now we have a list of matching IDs, filter the queryset
return queryset.filter(pk__in=return_orders)
completed_before = InvenTreeDateFilter(
label=_('Completed Before'), field_name='complete_date', lookup_expr='lt'
)
completed_after = InvenTreeDateFilter(
label=_('Completed After'), field_name='complete_date', lookup_expr='gt'
)
class ReturnOrderMixin:
"""Mixin class for ReturnOrder endpoints."""
@ -1325,6 +1371,7 @@ class ReturnOrderList(ReturnOrderMixin, DataExportViewMixin, ListCreateAPI):
'line_items',
'status',
'target_date',
'complete_date',
'project_code',
]

View File

@ -1159,10 +1159,10 @@ class PartFilter(rest_filters.FilterSet):
# Created date filters
created_before = InvenTreeDateFilter(
label='Updated before', field_name='creation_date', lookup_expr='lte'
label='Updated before', field_name='creation_date', lookup_expr='lt'
)
created_after = InvenTreeDateFilter(
label='Updated after', field_name='creation_date', lookup_expr='gte'
label='Updated after', field_name='creation_date', lookup_expr='gt'
)

View File

@ -807,19 +807,28 @@ class StockFilter(rest_filters.FilterSet):
# Update date filters
updated_before = InvenTreeDateFilter(
label='Updated before', field_name='updated', lookup_expr='lte'
label=_('Updated before'), field_name='updated', lookup_expr='lt'
)
updated_after = InvenTreeDateFilter(
label='Updated after', field_name='updated', lookup_expr='gte'
label=_('Updated after'), field_name='updated', lookup_expr='gt'
)
stocktake_before = InvenTreeDateFilter(
label=_('Stocktake Before'), field_name='stocktake_date', lookup_expr='lt'
)
stocktake_after = InvenTreeDateFilter(
label=_('Stocktake After'), field_name='stocktake_date', lookup_expr='gt'
)
# Stock "expiry" filters
expiry_date_lte = InvenTreeDateFilter(
label=_('Expiry date before'), field_name='expiry_date', lookup_expr='lte'
expiry_before = InvenTreeDateFilter(
label=_('Expiry date before'), field_name='expiry_date', lookup_expr='lt'
)
expiry_date_gte = InvenTreeDateFilter(
label=_('Expiry date after'), field_name='expiry_date', lookup_expr='gte'
expiry_after = InvenTreeDateFilter(
label=_('Expiry date after'), field_name='expiry_date', lookup_expr='gt'
)
stale = rest_filters.BooleanFilter(label=_('Stale'), method='filter_stale')

View File

@ -421,11 +421,11 @@ function getStockTableFilters() {
title: '{% trans "Has purchase price" %}',
description: '{% trans "Show stock items which have a purchase price set" %}',
},
expiry_date_lte: {
expiry_before: {
type: 'date',
title: '{% trans "Expiry Date before" %}',
},
expiry_date_gte: {
expiry_after: {
type: 'date',
title: '{% trans "Expiry Date after" %}',
},