From 1d6a049c5a3f0aed0c35cda4661d4a9d98281167 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 6 Jan 2021 23:06:49 +1100 Subject: [PATCH] Annotate stock queryset with stale status --- InvenTree/stock/serializers.py | 21 +++++++++++++++++++++ InvenTree/templates/InvenTree/index.html | 1 + InvenTree/templates/js/stock.js | 4 +++- InvenTree/templates/js/table_filters.js | 5 +++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index 9db1d95dae..70ad1abc18 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -13,11 +13,15 @@ from django.db.models.functions import Coalesce from django.db.models import Case, When, Value from django.db.models import BooleanField +from django.db.models import Q from sql_util.utils import SubquerySum, SubqueryCount from decimal import Decimal +from datetime import datetime, timedelta + +import common.models from company.serializers import SupplierPartSerializer from part.serializers import PartBriefSerializer from InvenTree.serializers import UserSerializerBrief, InvenTreeModelSerializer @@ -119,6 +123,20 @@ class StockItemSerializer(InvenTreeModelSerializer): ) ) + # Add flag to indicate if the StockItem is stale + stale_days = common.models.InvenTreeSetting.get_setting('STOCK_STALE_DAYS') + stale_date = datetime.now().date() + timedelta(days=stale_days) + stale_filter = StockItem.IN_STOCK_FILTER & ~Q(expiry_date=None) & Q(expiry_date__lt=stale_date) + + queryset = queryset.annotate( + stale=Case( + When( + stale_filter, then=Value(True, output_field=BooleanField()), + ), + default=Value(False, output_field=BooleanField()), + ) + ) + return queryset status_text = serializers.CharField(source='get_status_display', read_only=True) @@ -137,6 +155,8 @@ class StockItemSerializer(InvenTreeModelSerializer): expired = serializers.BooleanField(required=False, read_only=True) + stale = serializers.BooleanField(required=False, read_only=True) + serial = serializers.CharField(required=False) required_tests = serializers.IntegerField(source='required_test_count', read_only=True, required=False) @@ -185,6 +205,7 @@ class StockItemSerializer(InvenTreeModelSerializer): 'required_tests', 'sales_order', 'serial', + 'stale', 'status', 'status_text', 'supplier_part', diff --git a/InvenTree/templates/InvenTree/index.html b/InvenTree/templates/InvenTree/index.html index d1e10cb00e..1b9a492a22 100644 --- a/InvenTree/templates/InvenTree/index.html +++ b/InvenTree/templates/InvenTree/index.html @@ -102,6 +102,7 @@ loadStockTable($("#expired-stock-table"), { loadStockTable($("#stale-stock-table"), { params: { stale: true, + expired: false, location_detail: true, part_detail: true, }, diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js index d32f52f92b..e3f124d252 100644 --- a/InvenTree/templates/js/stock.js +++ b/InvenTree/templates/js/stock.js @@ -534,7 +534,9 @@ function loadStockTable(table, options) { } if (row.expired) { - html += makeIconBadge('fa-stopwatch icon-red', '{% trans "Stock item has expired" %}'); + html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Stock item has expired" %}'); + } else if (row.stale) { + html += makeIconBadge('fa-stopwatch', '{% trans "Stock item will expire soon" %}'); } if (row.allocated) { diff --git a/InvenTree/templates/js/table_filters.js b/InvenTree/templates/js/table_filters.js index 054542a4a3..84aa12c139 100644 --- a/InvenTree/templates/js/table_filters.js +++ b/InvenTree/templates/js/table_filters.js @@ -111,6 +111,11 @@ function getAvailableTableFilters(tableKey) { title: '{% trans "Expired" %}', description: '{% trans "Show stock items which have expired" %}', }, + stale: { + type: 'bool', + title: '{% trans "Stale" %}', + description: '{% trans "Show stock which is close to expiring" %}', + }, in_stock: { type: 'bool', title: '{% trans "In Stock" %}',