mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add 'available_variant_stock' to BomItem serializer
- Note: This is definitely *not* the optimum solution here
This commit is contained in:
parent
d43158ab1b
commit
d535e4fa12
@ -2703,6 +2703,61 @@ class BomItem(models.Model, DataImportMixin):
|
|||||||
def get_api_url():
|
def get_api_url():
|
||||||
return reverse('api-bom-list')
|
return reverse('api-bom-list')
|
||||||
|
|
||||||
|
def available_variant_stock(self):
|
||||||
|
"""
|
||||||
|
Returns the total quantity of variant stock available for this BomItem.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- If "allow_variants" is False, this will return zero
|
||||||
|
- This is used for the API serializer, and is very inefficient
|
||||||
|
- This logic needs to be converted to a queryset annotation
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Variant stock is not allowed for this BOM item
|
||||||
|
if not self.allow_variants:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Extract a flattened list of part variants
|
||||||
|
variants = self.sub_part.get_descendants(include_self=False)
|
||||||
|
|
||||||
|
# Calculate 'in_stock' quantity - this is the total current stock count
|
||||||
|
query = StockModels.StockItem.objects.filter(StockModels.StockItem.IN_STOCK_FILTER)
|
||||||
|
|
||||||
|
query = query.filter(
|
||||||
|
part__in=variants,
|
||||||
|
)
|
||||||
|
|
||||||
|
query = query.aggregate(
|
||||||
|
in_stock=Coalesce(Sum('quantity'), Decimal(0))
|
||||||
|
)
|
||||||
|
|
||||||
|
in_stock = query['in_stock'] or 0
|
||||||
|
|
||||||
|
# Calculate the quantity allocated to sales orders
|
||||||
|
query = OrderModels.SalesOrderAllocation.objects.filter(
|
||||||
|
line__order__status__in=SalesOrderStatus.OPEN,
|
||||||
|
shipment__shipment_date=None,
|
||||||
|
item__part__in=variants,
|
||||||
|
).aggregate(
|
||||||
|
allocated=Coalesce(Sum('quantity'), Decimal(0)),
|
||||||
|
)
|
||||||
|
|
||||||
|
sales_order_allocations = query['allocated'] or 0
|
||||||
|
|
||||||
|
# Calculate the quantity allocated to build orders
|
||||||
|
query = BuildModels.BuildItem.objects.filter(
|
||||||
|
build__status__in=BuildStatus.ACTIVE_CODES,
|
||||||
|
stock_item__part__in=variants,
|
||||||
|
).aggregate(
|
||||||
|
allocated=Coalesce(Sum('quantity'), Decimal(0)),
|
||||||
|
)
|
||||||
|
|
||||||
|
build_order_allocations = query['allocated'] or 0
|
||||||
|
|
||||||
|
available = in_stock - sales_order_allocations - build_order_allocations
|
||||||
|
|
||||||
|
return max(available, 0)
|
||||||
|
|
||||||
def get_valid_parts_for_allocation(self, allow_variants=True, allow_substitutes=True):
|
def get_valid_parts_for_allocation(self, allow_variants=True, allow_substitutes=True):
|
||||||
"""
|
"""
|
||||||
Return a list of valid parts which can be allocated against this BomItem:
|
Return a list of valid parts which can be allocated against this BomItem:
|
||||||
|
@ -581,6 +581,12 @@ class BomItemSerializer(InvenTreeModelSerializer):
|
|||||||
available_stock = serializers.FloatField(read_only=True)
|
available_stock = serializers.FloatField(read_only=True)
|
||||||
available_substitute_stock = serializers.FloatField(read_only=True)
|
available_substitute_stock = serializers.FloatField(read_only=True)
|
||||||
|
|
||||||
|
# Note: 2022-04-15
|
||||||
|
# The 'available_variant_stock' field is calculated per-object,
|
||||||
|
# which means it is very inefficient!
|
||||||
|
# TODO: This needs to be converted into a query annotation, if possible!
|
||||||
|
available_variant_stock = serializers.FloatField(read_only=True)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
# part_detail and sub_part_detail serializers are only included if requested.
|
# part_detail and sub_part_detail serializers are only included if requested.
|
||||||
# This saves a bunch of database requests
|
# This saves a bunch of database requests
|
||||||
@ -790,6 +796,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
|
|||||||
# Annotated fields describing available quantity
|
# Annotated fields describing available quantity
|
||||||
'available_stock',
|
'available_stock',
|
||||||
'available_substitute_stock',
|
'available_substitute_stock',
|
||||||
|
'available_variant_stock',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user