From 759c882a9566e4cb4fedc580f2aa9a3d4d46f509 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 17 Oct 2025 11:53:51 +1100 Subject: [PATCH] Allow adjument of build outputs (#10600) * Auto-select location * Allow stock adjustments for "in production" items * Tweak stock move check * Allow splitting of production stock * Update CHANGELOG.md --- CHANGELOG.md | 1 + src/backend/InvenTree/stock/models.py | 8 ++++---- src/backend/InvenTree/stock/serializers.py | 2 +- src/frontend/src/forms/StockForms.tsx | 4 ++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29411a85e1..ce309cc1e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added ability to partially complete and partially scrap build outputs in [#10499](https://github.com/inventree/InvenTree/pull/10499) - Added support for Redis ACL user-based authentication in [#10551](https://github.com/inventree/InvenTree/pull/10551) - Expose stock adjustment forms to the UI plugin context in [#10584](https://github.com/inventree/InvenTree/pull/10584) +- Allow stock adjustments for "in production" items in [#10600](https://github.com/inventree/InvenTree/pull/10600) ### Changed diff --git a/src/backend/InvenTree/stock/models.py b/src/backend/InvenTree/stock/models.py index 7718dd0a00..d66895b30b 100644 --- a/src/backend/InvenTree/stock/models.py +++ b/src/backend/InvenTree/stock/models.py @@ -1743,7 +1743,6 @@ class StockItem( self.belongs_to is None, # Not installed inside another StockItem self.customer is None, # Not assigned to a customer self.consumed_by is None, # Not consumed by a build - not self.is_building, # Not part of an active build ]) @property @@ -2221,7 +2220,6 @@ class StockItem( - The new item will have a different StockItem ID, while this will remain the same. """ # Run initial checks to test if the stock item can actually be "split" - allow_production = kwargs.get('allow_production', False) # Cannot split a stock item which is in production @@ -2346,7 +2344,9 @@ class StockItem( 'STOCK_ALLOW_OUT_OF_STOCK_TRANSFER', backup_value=False, cache=False ) - if not allow_out_of_stock_transfer and not self.is_in_stock(check_status=False): + if not allow_out_of_stock_transfer and not self.is_in_stock( + check_status=False, check_in_production=False + ): raise ValidationError(_('StockItem cannot be moved as it is not in stock')) if quantity <= 0: @@ -2362,7 +2362,7 @@ class StockItem( kwargs['notes'] = notes # Split the existing StockItem in two - self.splitStock(quantity, location, user, **kwargs) + self.splitStock(quantity, location, user, allow_production=True, **kwargs) return True diff --git a/src/backend/InvenTree/stock/serializers.py b/src/backend/InvenTree/stock/serializers.py index 222f177ae8..7447307b8d 100644 --- a/src/backend/InvenTree/stock/serializers.py +++ b/src/backend/InvenTree/stock/serializers.py @@ -1602,7 +1602,7 @@ class StockAdjustmentItemSerializer(serializers.Serializer): ) if not allow_out_of_stock_transfer and not stock_item.is_in_stock( - check_status=False, check_quantity=False + check_status=False, check_quantity=False, check_in_production=False ): raise ValidationError(_('Stock item is not in stock')) elif self.require_in_stock == False: diff --git a/src/frontend/src/forms/StockForms.tsx b/src/frontend/src/forms/StockForms.tsx index f3c407eba9..d00af0a968 100644 --- a/src/frontend/src/forms/StockForms.tsx +++ b/src/frontend/src/forms/StockForms.tsx @@ -712,6 +712,9 @@ function stockTransferFields(items: any[]): ApiFormFieldSet { const records = Object.fromEntries(items.map((item) => [item.pk, item])); + // Extract all location values from the items + const locations = [...new Set(items.map((item) => item.location))]; + const fields: ApiFormFieldSet = { items: { field_type: 'table', @@ -740,6 +743,7 @@ function stockTransferFields(items: any[]): ApiFormFieldSet { ] }, location: { + value: locations.length === 1 ? locations[0] : undefined, filters: { structural: false }