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:
@ -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
|
||||
|
||||
|
@ -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."""
|
||||
|
@ -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',
|
||||
]
|
||||
|
||||
|
@ -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'
|
||||
)
|
||||
|
||||
|
||||
|
@ -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')
|
||||
|
@ -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" %}',
|
||||
},
|
||||
|
Reference in New Issue
Block a user