Add ability to filter parts by "low_stock"

- Huzzah for the "Coalesce" function, eh?
This commit is contained in:
Oliver Walters 2020-04-11 22:43:51 +10:00
parent f06078f4ac
commit e86bc4fa6d
2 changed files with 26 additions and 7 deletions

View File

@ -8,7 +8,8 @@ from __future__ import unicode_literals
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from django.conf import settings from django.conf import settings
from django.db.models import Q, Sum, Count from django.db.models import Q, F, Sum, Count
from django.db.models.functions import Coalesce
from rest_framework import status from rest_framework import status
from rest_framework.response import Response from rest_framework.response import Response
@ -19,6 +20,7 @@ from django.conf.urls import url, include
from django.urls import reverse from django.urls import reverse
import os import os
from decimal import Decimal
from .models import Part, PartCategory, BomItem, PartStar from .models import Part, PartCategory, BomItem, PartStar
from .models import PartParameter, PartParameterTemplate from .models import PartParameter, PartParameterTemplate
@ -210,13 +212,12 @@ class PartList(generics.ListCreateAPIView):
'active', 'active',
).annotate( ).annotate(
# Quantity of items which are "in stock" # Quantity of items which are "in stock"
in_stock=Sum('stock_items__quantity', filter=stock_filter), in_stock=Coalesce(Sum('stock_items__quantity', filter=stock_filter), Decimal(0)),
on_order=Sum('supplier_parts__purchase_order_line_items__quantity', filter=order_filter), on_order=Sum('supplier_parts__purchase_order_line_items__quantity', filter=order_filter),
building=Sum('builds__quantity', filter=build_filter), building=Sum('builds__quantity', filter=build_filter),
) )
# If we are filtering by 'has_stock' status, # If we are filtering by 'has_stock' status
# Check if the 'has_stock' quantity is zero
has_stock = self.request.query_params.get('has_stock', None) has_stock = self.request.query_params.get('has_stock', None)
if has_stock is not None: if has_stock is not None:
@ -224,11 +225,25 @@ class PartList(generics.ListCreateAPIView):
if has_stock: if has_stock:
# Filter items which have a non-null 'in_stock' quantity above zero # Filter items which have a non-null 'in_stock' quantity above zero
data = data.exclude(in_stock=None)
data = data.filter(in_stock__gt=0) data = data.filter(in_stock__gt=0)
else: else:
# Filter items which a null or zero 'in_stock' quantity # Filter items which a null or zero 'in_stock' quantity
data = data.filter(Q(in_stock__lte=0) | Q(in_stock=None)) data = data.filter(Q(in_stock__lte=0))
# If we are filtering by 'low_stock' status
low_stock = self.request.query_params.get('low_stock', None)
if low_stock is not None:
low_stock = str2bool(low_stock)
if low_stock:
# Ignore any parts which do not have a specified 'minimum_stock' level
data = data.exclude(minimum_stock=0)
# Filter items which have an 'in_stock' level lower than 'minimum_stock'
data = data.filter(Q(in_stock__lt=F('minimum_stock')))
else:
# Filter items which have an 'in_stock' level higher than 'minimum_stock'
data = data.filter(Q(in_stock__gte=F('minimum_stock')))
# Reduce the number of lookups we need to do for the part categories # Reduce the number of lookups we need to do for the part categories
categories = {} categories = {}

View File

@ -75,8 +75,12 @@ function getAvailableTableFilters(tableKey) {
}, },
has_stock: { has_stock: {
type: 'bool', type: 'bool',
title: '{% trans "Stock Available" %}' title: '{% trans "Stock available" %}'
}, },
low_stock: {
type: 'bool',
title: '{% trans "Low stock" %}',
}
}; };
} }