2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-29 20:16:44 +00:00

Add 'variant_stock' to Part API serializer

This commit is contained in:
Oliver Walters 2022-04-22 00:14:37 +10:00
parent aa20d84cc1
commit 8b9aa86a0a

View File

@ -8,7 +8,7 @@ from decimal import Decimal
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.db import models, transaction from django.db import models, transaction
from django.db.models import ExpressionWrapper, F, Q, Func from django.db.models import ExpressionWrapper, F, Q, Func
from django.db.models import Subquery, OuterRef, IntegerField, FloatField from django.db.models import Subquery, OuterRef, FloatField
from django.db.models.functions import Coalesce from django.db.models.functions import Coalesce
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -310,9 +310,6 @@ class PartSerializer(InvenTreeModelSerializer):
to reduce database trips. to reduce database trips.
""" """
# TODO: Update the "in_stock" annotation to include stock for variants of the part
# Ref: https://github.com/inventree/InvenTree/issues/2240
# Annotate with the total 'in stock' quantity # Annotate with the total 'in stock' quantity
queryset = queryset.annotate( queryset = queryset.annotate(
in_stock=Coalesce( in_stock=Coalesce(
@ -327,6 +324,24 @@ class PartSerializer(InvenTreeModelSerializer):
stock_item_count=SubqueryCount('stock_items') stock_item_count=SubqueryCount('stock_items')
) )
# Annotate with the total variant stock quantity
variant_query = StockItem.objects.filter(
part__tree_id=OuterRef('tree_id'),
part__lft__gt=OuterRef('lft'),
part__rght__lt=OuterRef('rght'),
).filter(StockItem.IN_STOCK_FILTER)
queryset = queryset.annotate(
variant_stock=Coalesce(
Subquery(
variant_query.annotate(
total=Func(F('quantity'), function='SUM', output_field=FloatField())
).values('total')),
0,
output_field=FloatField(),
)
)
# Filter to limit builds to "active" # Filter to limit builds to "active"
build_filter = Q( build_filter = Q(
status__in=BuildStatus.ACTIVE_CODES status__in=BuildStatus.ACTIVE_CODES
@ -431,6 +446,7 @@ class PartSerializer(InvenTreeModelSerializer):
unallocated_stock = serializers.FloatField(read_only=True) unallocated_stock = serializers.FloatField(read_only=True)
building = serializers.FloatField(read_only=True) building = serializers.FloatField(read_only=True)
in_stock = serializers.FloatField(read_only=True) in_stock = serializers.FloatField(read_only=True)
variant_stock = serializers.FloatField(read_only=True)
ordering = serializers.FloatField(read_only=True) ordering = serializers.FloatField(read_only=True)
stock_item_count = serializers.IntegerField(read_only=True) stock_item_count = serializers.IntegerField(read_only=True)
suppliers = serializers.IntegerField(read_only=True) suppliers = serializers.IntegerField(read_only=True)
@ -465,6 +481,7 @@ class PartSerializer(InvenTreeModelSerializer):
'full_name', 'full_name',
'image', 'image',
'in_stock', 'in_stock',
'variant_stock',
'ordering', 'ordering',
'building', 'building',
'IPN', 'IPN',
@ -730,7 +747,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
part__tree_id=OuterRef('sub_part__tree_id'), part__tree_id=OuterRef('sub_part__tree_id'),
part__lft__gt=OuterRef('sub_part__lft'), part__lft__gt=OuterRef('sub_part__lft'),
part__rght__lt=OuterRef('sub_part__rght'), part__rght__lt=OuterRef('sub_part__rght'),
) ).filter(StockItem.IN_STOCK_FILTER)
queryset = queryset.alias( queryset = queryset.alias(
variant_stock_total=Coalesce( variant_stock_total=Coalesce(