2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-04-05 02:50:58 +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): def filter_overdue(self, queryset, name, value):
"""Filter the queryset to either include or exclude orders which are overdue.""" """Filter the queryset to either include or exclude orders which are overdue."""
if str2bool(value): if str2bool(value):
return queryset.filter(Build.OVERDUE_FILTER) return queryset.filter(Build.get_overdue_filter())
return queryset.exclude(Build.OVERDUE_FILTER) return queryset.exclude(Build.get_overdue_filter())
assigned_to_me = rest_filters.BooleanFilter( assigned_to_me = rest_filters.BooleanFilter(
label=_('Assigned to me'), method='filter_assigned_to_me' label=_('Assigned to me'), method='filter_assigned_to_me'

View File

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

View File

@@ -168,7 +168,8 @@ class BuildSerializer(
queryset = queryset.annotate( queryset = queryset.annotate(
overdue=Case( overdue=Case(
When( 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()), default=Value(False, output_field=BooleanField()),
) )

View File

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

View File

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

View File

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

View File

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

View File

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