2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-03-23 04:34:37 +00:00

Fix stuck-in-past expiry date filter (#11518)

* fix stuck-in-past expiry date filter

* also fix OVERDUE_FILTER date problem
This commit is contained in:
Jacob Felknor
2026-03-14 05:50:08 -06:00
committed by GitHub
parent 649ff009b9
commit c3cedd25c0
8 changed files with 42 additions and 32 deletions

View File

@@ -145,8 +145,8 @@ class BuildFilter(FilterSet):
def filter_overdue(self, queryset, name, value):
"""Filter the queryset to either include or exclude orders which are overdue."""
if str2bool(value):
return queryset.filter(Build.OVERDUE_FILTER)
return queryset.exclude(Build.OVERDUE_FILTER)
return queryset.filter(Build.get_overdue_filter())
return queryset.exclude(Build.get_overdue_filter())
assigned_to_me = rest_filters.BooleanFilter(
label=_('Assigned to me'), method='filter_assigned_to_me'

View File

@@ -132,11 +132,14 @@ class Build(
TRACKED = 'tracked' # Tracked BOM items
UNTRACKED = 'untracked' # Untracked BOM items
OVERDUE_FILTER = (
Q(status__in=BuildStatusGroups.ACTIVE_CODES)
& ~Q(target_date=None)
& Q(target_date__lte=InvenTree.helpers.current_date())
)
@classmethod
def get_overdue_filter(cls):
"""Filter for determining if a build order is overdue."""
return (
Q(status__in=BuildStatusGroups.ACTIVE_CODES)
& ~Q(target_date=None)
& Q(target_date__lte=InvenTree.helpers.current_date())
)
# Global setting for specifying reference pattern
REFERENCE_PATTERN_SETTING = 'BUILDORDER_REFERENCE_PATTERN'
@@ -465,7 +468,7 @@ class Build(
bool: Is the build overdue
"""
query = Build.objects.filter(pk=self.pk)
query = query.filter(Build.OVERDUE_FILTER)
query = query.filter(Build.get_overdue_filter())
return query.exists()

View File

@@ -168,7 +168,8 @@ class BuildSerializer(
queryset = queryset.annotate(
overdue=Case(
When(
Build.OVERDUE_FILTER, then=Value(True, output_field=BooleanField())
Build.get_overdue_filter(),
then=Value(True, output_field=BooleanField()),
),
default=Value(False, output_field=BooleanField()),
)

View File

@@ -1873,12 +1873,14 @@ class PurchaseOrderLineItem(OrderLineItem):
verbose_name = _('Purchase Order Line Item')
# Filter for determining if a particular PurchaseOrderLineItem is overdue
OVERDUE_FILTER = (
Q(received__lt=F('quantity'))
& ~Q(target_date=None)
& Q(target_date__lt=InvenTree.helpers.current_date())
)
@classmethod
def get_overdue_filter(cls):
"""Filter for determining if a particular PurchaseOrderLineItem is overdue."""
return (
Q(received__lt=F('quantity'))
& ~Q(target_date=None)
& Q(target_date__lt=InvenTree.helpers.current_date())
)
@staticmethod
def get_api_url() -> str:
@@ -2077,12 +2079,14 @@ class SalesOrderLineItem(OrderLineItem):
verbose_name = _('Sales Order Line Item')
# Filter for determining if a particular SalesOrderLineItem is overdue
OVERDUE_FILTER = (
Q(shipped__lt=F('quantity'))
& ~Q(target_date=None)
& Q(target_date__lt=InvenTree.helpers.current_date())
)
@classmethod
def get_overdue_filter(cls):
"""Filter for determining if a particular SalesOrderLineItem is overdue."""
return (
Q(shipped__lt=F('quantity'))
& ~Q(target_date=None)
& Q(target_date__lt=InvenTree.helpers.current_date())
)
@staticmethod
def get_api_url():

View File

@@ -594,7 +594,7 @@ class PurchaseOrderLineItemSerializer(
queryset = queryset.annotate(
overdue=Case(
When(
order.models.PurchaseOrderLineItem.OVERDUE_FILTER,
order.models.PurchaseOrderLineItem.get_overdue_filter(),
then=Value(True, output_field=BooleanField()),
),
default=Value(False, output_field=BooleanField()),
@@ -1172,7 +1172,7 @@ class SalesOrderLineItemSerializer(
overdue=Case(
When(
Q(order__status__in=SalesOrderStatusGroups.OPEN)
& order.models.SalesOrderLineItem.OVERDUE_FILTER,
& order.models.SalesOrderLineItem.get_overdue_filter(),
then=Value(True, output_field=BooleanField()),
),
default=Value(False, output_field=BooleanField()),

View File

@@ -685,8 +685,8 @@ class StockFilter(FilterSet):
return queryset
if str2bool(value):
return queryset.filter(StockItem.EXPIRED_FILTER)
return queryset.exclude(StockItem.EXPIRED_FILTER)
return queryset.filter(StockItem.get_expired_filter())
return queryset.exclude(StockItem.get_expired_filter())
external = rest_filters.BooleanFilter(
label=_('External Location'), method='filter_external'

View File

@@ -521,12 +521,14 @@ class StockItem(
status__in=StockStatusGroups.AVAILABLE_CODES,
)
# A query filter which can be used to filter StockItem objects which have expired
EXPIRED_FILTER = (
IN_STOCK_FILTER
& ~Q(expiry_date=None)
& Q(expiry_date__lt=InvenTree.helpers.current_date())
)
@classmethod
def get_expired_filter(cls):
"""A query filter which can be used to filter StockItem objects which have expired."""
return (
cls.IN_STOCK_FILTER
& ~Q(expiry_date=None)
& Q(expiry_date__lt=InvenTree.helpers.current_date())
)
@classmethod
def _create_serial_numbers(cls, serials: list, **kwargs) -> QuerySet:

View File

@@ -516,7 +516,7 @@ class StockItemSerializer(
queryset = queryset.annotate(
expired=Case(
When(
StockItem.EXPIRED_FILTER,
StockItem.get_expired_filter(),
then=Value(True, output_field=BooleanField()),
),
default=Value(False, output_field=BooleanField()),