From 49cc5fb1372e02da1b15331d111ffdef83a0a48d Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 19 Aug 2025 17:03:19 +1000 Subject: [PATCH] Build order consume (#8191) * Adds "consumed" field to BuildLine model * Expose new field to serializer * Add "consumed" column to BuildLineTable * Boolean column tweaks * Increase consumed count when completing allocation * Add comment * Update migration * Add serializer for consuming build items * Improve build-line sub-table * Refactor BuildItem.complete_allocation method - Allow optional quantity to be specified - Adjust the allocated quantity when consuming * Perform consumption * Add "BuildConsume" API endpoint * Implement frontend form * Fixes for serializer * Enhance front-end form * Fix rendering of BuildLineTable * Further improve rendering * Bump API version * Update API description * Add option to consume by specifying a list of BuildLine objects * Add form to consume stock via BuildLine reference * Fix api_version * Fix backup colors * Fix typo * Fix migrations * Fix build forms * Forms fixes * Fix formatting * Fixes for BuildLineTable * Account for consumed stock in requirements calculation * Reduce API requirements for BuildLineTable * Docs updates * Updated playwright testing * Update src/frontend/src/forms/BuildForms.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/frontend/src/tables/build/BuildLineTable.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add unit test for filters * Add functional tests * Tweak query count * Increase max query time for testing * adjust unit test again * Prevent consumption of "tracked" items * Adjust playwright tests * Fix table * Fix rendering --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../images/build/parts_allocated_consumed.png | Bin 0 -> 150651 bytes docs/docs/manufacturing/allocate.md | 43 ++++ .../InvenTree/InvenTree/api_version.py | 6 +- src/backend/InvenTree/build/api.py | 24 +- .../migrations/0058_buildline_consumed.py | 19 ++ src/backend/InvenTree/build/models.py | 56 ++++- src/backend/InvenTree/build/serializers.py | 208 +++++++++++++++- src/backend/InvenTree/build/test_api.py | 180 +++++++++++++- src/backend/InvenTree/part/models.py | 5 +- src/frontend/lib/components/YesNoButton.tsx | 22 +- src/frontend/lib/enums/ApiEndpoints.tsx | 1 + src/frontend/src/components/render/Part.tsx | 4 + src/frontend/src/components/render/Stock.tsx | 4 + src/frontend/src/forms/BuildForms.tsx | 231 +++++++++++++++++- src/frontend/src/forms/StockForms.tsx | 3 +- src/frontend/src/tables/ColumnRenderers.tsx | 6 +- .../tables/build/BuildAllocatedStockTable.tsx | 54 +++- .../src/tables/build/BuildLineTable.tsx | 211 +++++++++++----- .../src/tables/build/BuildOutputTable.tsx | 28 ++- .../tables/part/PartBuildAllocationsTable.tsx | 38 ++- src/frontend/tests/pages/pui_build.spec.ts | 53 ++++ src/frontend/tests/pages/pui_part.spec.ts | 9 +- src/frontend/tests/pages/pui_stock.spec.ts | 1 + src/frontend/tests/pui_plugins.spec.ts | 15 -- 24 files changed, 1079 insertions(+), 142 deletions(-) create mode 100644 docs/docs/assets/images/build/parts_allocated_consumed.png create mode 100644 src/backend/InvenTree/build/migrations/0058_buildline_consumed.py diff --git a/docs/docs/assets/images/build/parts_allocated_consumed.png b/docs/docs/assets/images/build/parts_allocated_consumed.png new file mode 100644 index 0000000000000000000000000000000000000000..8c0e60a22f690d854ee8d50d38c06146e4ca7f61 GIT binary patch literal 150651 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�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 `odo1&gRwmTV0b)x)#+~ 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 literal 0 HcmV?d00001 diff --git a/docs/docs/manufacturing/allocate.md b/docs/docs/manufacturing/allocate.md index 0293d644c1..f6627f35fe 100644 --- a/docs/docs/manufacturing/allocate.md +++ b/docs/docs/manufacturing/allocate.md @@ -126,6 +126,49 @@ Here we can see that the incomplete build outputs (serial numbers 15 and 14) now !!! note "Example: Tracked Stock" Let's say we have 5 units of "Tracked Part" in stock - with 1 unit allocated to the build output. Once we complete the build output, there will be 4 units of "Tracked Part" in stock, with 1 unit being marked as "installed" within the assembled part +## Consuming Stock + +Allocating stock items to a build order does not immediately remove them from stock. Instead, the stock items are marked as "allocated" against the build order, and are only removed from stock when they are "consumed" by the build order. + +In the *Required Parts* tab, you can see the *consumed* vs *allocated* state of each line item in the BOM: + +{{ image("build/parts_allocated_consumed.png", "Partially allocated and consumed") }} + +Consuming items against the build order can be performed in two ways: + +- Manually, by consuming selected stock allocations against the build order +- Automatically, by completing the build order + +### Manual Consumption + +Manual consuming stock items (before the build order is completed) can be performed at any point after stock has been allocated against the build order. Manual stock consumption may be desired in some situations, for example if the build order is being performed in stages, or to ensure that stock levels are kept up to date. + +Manual consumption of stock items can be performed in the in the following ways: + +#### Required Parts Tab + +Consuming stock items can be performed against BOM line items in the *Required Parts* tab, either against a single line or multiple selected lines: + +- Navigate to the *Required Parts* tab +- Select the individual line items which you wish to consume +- Click the *Consume Stock* button + +#### Allocated Stock Tab + +Consuming stock items can also be performed against the *Allocated Stock* tab, either against a single allocation or multiple allocations: + +- Navigate to the *Allocated Stock* tab +- Select the individual stock allocations which you wish to consume +- Click the *Consume Stock* button + +### Automatic Consumption + +When a build order is completed, all remaining allocated stock items are automatically consumed by the build order. + +### Returning Items to Stock + +Consumed items may be manually returned into stock if required. This can be performed in the *Consumed Stock* tab. + ## Completing a Build !!! warning "Complete Build Outputs" diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index 19b161bf37..ba2be6f219 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,11 +1,15 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 385 +INVENTREE_API_VERSION = 386 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v386 -> 2025-08-11 : https://github.com/inventree/InvenTree/pull/8191 + - Adds "consumed" field to the BuildItem API + - Adds API endpoint to consume stock against a BuildOrder + v385 -> 2025-08-15 : https://github.com/inventree/InvenTree/pull/10174 - Adjust return type of PurchaseOrderReceive API serializer - Now returns list of of the created stock items when receiving diff --git a/src/backend/InvenTree/build/api.py b/src/backend/InvenTree/build/api.py index 4bd5cce971..1ddeff9fda 100644 --- a/src/backend/InvenTree/build/api.py +++ b/src/backend/InvenTree/build/api.py @@ -479,6 +479,14 @@ class BuildLineFilter(rest_filters.FilterSet): return queryset.filter(allocated__gte=F('quantity')) return queryset.filter(allocated__lt=F('quantity')) + consumed = rest_filters.BooleanFilter(label=_('Consumed'), method='filter_consumed') + + def filter_consumed(self, queryset, name, value): + """Filter by whether each BuildLine is fully consumed.""" + if str2bool(value): + return queryset.filter(consumed__gte=F('quantity')) + return queryset.filter(consumed__lt=F('quantity')) + available = rest_filters.BooleanFilter( label=_('Available'), method='filter_available' ) @@ -494,6 +502,7 @@ class BuildLineFilter(rest_filters.FilterSet): """ flt = Q( quantity__lte=F('allocated') + + F('consumed') + F('available_stock') + F('available_substitute_stock') + F('available_variant_stock') @@ -504,7 +513,7 @@ class BuildLineFilter(rest_filters.FilterSet): return queryset.exclude(flt) -class BuildLineEndpoint: +class BuildLineMixin: """Mixin class for BuildLine API endpoints.""" queryset = BuildLine.objects.all() @@ -553,7 +562,7 @@ class BuildLineEndpoint: ) -class BuildLineList(BuildLineEndpoint, DataExportViewMixin, ListCreateAPI): +class BuildLineList(BuildLineMixin, DataExportViewMixin, ListCreateAPI): """API endpoint for accessing a list of BuildLine objects.""" filterset_class = BuildLineFilter @@ -562,6 +571,7 @@ class BuildLineList(BuildLineEndpoint, DataExportViewMixin, ListCreateAPI): ordering_fields = [ 'part', 'allocated', + 'consumed', 'reference', 'quantity', 'consumable', @@ -605,7 +615,7 @@ class BuildLineList(BuildLineEndpoint, DataExportViewMixin, ListCreateAPI): return source_build -class BuildLineDetail(BuildLineEndpoint, RetrieveUpdateDestroyAPI): +class BuildLineDetail(BuildLineMixin, RetrieveUpdateDestroyAPI): """API endpoint for detail view of a BuildLine object.""" def get_source_build(self) -> Build | None: @@ -734,6 +744,13 @@ class BuildAllocate(BuildOrderContextMixin, CreateAPI): serializer_class = build.serializers.BuildAllocationSerializer +class BuildConsume(BuildOrderContextMixin, CreateAPI): + """API endpoint to consume stock against a build order.""" + + queryset = Build.objects.none() + serializer_class = build.serializers.BuildConsumeSerializer + + class BuildIssue(BuildOrderContextMixin, CreateAPI): """API endpoint for issuing a BuildOrder.""" @@ -953,6 +970,7 @@ build_api_urls = [ '/', include([ path('allocate/', BuildAllocate.as_view(), name='api-build-allocate'), + path('consume/', BuildConsume.as_view(), name='api-build-consume'), path( 'auto-allocate/', BuildAutoAllocate.as_view(), diff --git a/src/backend/InvenTree/build/migrations/0058_buildline_consumed.py b/src/backend/InvenTree/build/migrations/0058_buildline_consumed.py new file mode 100644 index 0000000000..70e6af9455 --- /dev/null +++ b/src/backend/InvenTree/build/migrations/0058_buildline_consumed.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.15 on 2024-09-26 10:11 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('build', '0057_build_external'), + ] + + operations = [ + migrations.AddField( + model_name='buildline', + name='consumed', + field=models.DecimalField(decimal_places=5, default=0, help_text='Quantity of consumed stock', max_digits=15, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Consumed'), + ), + ] diff --git a/src/backend/InvenTree/build/models.py b/src/backend/InvenTree/build/models.py index 40c0d6bb2c..cdfe725543 100644 --- a/src/backend/InvenTree/build/models.py +++ b/src/backend/InvenTree/build/models.py @@ -1106,7 +1106,7 @@ class Build( # Remove stock for item in items: - item.complete_allocation(user) + item.complete_allocation(user=user) # Delete allocation items.all().delete() @@ -1151,7 +1151,7 @@ class Build( # Complete or discard allocations for build_item in allocated_items: if not discard_allocations: - build_item.complete_allocation(user) + build_item.complete_allocation(user=user) # Delete allocations allocated_items.delete() @@ -1200,7 +1200,7 @@ class Build( for build_item in allocated_items: # Complete the allocation of stock for that item - build_item.complete_allocation(user) + build_item.complete_allocation(user=user) # Delete the BuildItem objects from the database allocated_items.all().delete() @@ -1569,6 +1569,7 @@ class BuildLine(report.mixins.InvenTreeReportMixin, InvenTree.models.InvenTreeMo build: Link to a Build object bom_item: Link to a BomItem object quantity: Number of units required for the Build + consumed: Number of units which have been consumed against this line item """ class Meta: @@ -1614,6 +1615,15 @@ class BuildLine(report.mixins.InvenTreeReportMixin, InvenTree.models.InvenTreeMo help_text=_('Required quantity for build order'), ) + consumed = models.DecimalField( + decimal_places=5, + max_digits=15, + default=0, + validators=[MinValueValidator(0)], + verbose_name=_('Consumed'), + help_text=_('Quantity of consumed stock'), + ) + @property def part(self): """Return the sub_part reference from the link bom_item.""" @@ -1645,6 +1655,10 @@ class BuildLine(report.mixins.InvenTreeReportMixin, InvenTree.models.InvenTreeMo """Return True if this BuildLine is over-allocated.""" return self.allocated_quantity() > self.quantity + def is_fully_consumed(self): + """Return True if this BuildLine is fully consumed.""" + return self.consumed >= self.quantity + class BuildItem(InvenTree.models.InvenTreeMetadataModel): """A BuildItem links multiple StockItem objects to a Build. @@ -1812,20 +1826,36 @@ class BuildItem(InvenTree.models.InvenTreeMetadataModel): return self.build_line.bom_item if self.build_line else None @transaction.atomic - def complete_allocation(self, user, notes=''): + def complete_allocation(self, quantity=None, notes='', user=None): """Complete the allocation of this BuildItem into the output stock item. + Arguments: + quantity: The quantity to allocate (default is the full quantity) + notes: Additional notes to add to the transaction + user: The user completing the allocation + - If the referenced part is trackable, the stock item will be *installed* into the build output - If the referenced part is *not* trackable, the stock item will be *consumed* by the build order TODO: This is quite expensive (in terms of number of database hits) - and requires some thought + TODO: Revisit, and refactor! """ + # If the quantity is not provided, use the quantity of this BuildItem + if quantity is None: + quantity = self.quantity + item = self.stock_item + # Ensure we are not allocating more than available + if quantity > item.quantity: + raise ValidationError({ + 'quantity': _('Allocated quantity exceeds available stock quantity') + }) + # Split the allocated stock if there are more available than allocated - if item.quantity > self.quantity: - item = item.splitStock(self.quantity, None, user, notes=notes) + if item.quantity > quantity: + item = item.splitStock(quantity, None, user, notes=notes) # For a trackable part, special consideration needed! if item.part.trackable: @@ -1835,7 +1865,7 @@ class BuildItem(InvenTree.models.InvenTreeMetadataModel): # Install the stock item into the output self.install_into.installStockItem( - item, self.quantity, user, notes, build=self.build + item, quantity, user, notes, build=self.build ) else: @@ -1851,6 +1881,18 @@ class BuildItem(InvenTree.models.InvenTreeMetadataModel): deltas={'buildorder': self.build.pk, 'quantity': float(item.quantity)}, ) + # Increase the "consumed" count for the associated BuildLine + self.build_line.consumed += quantity + self.build_line.save() + + # Decrease the allocated quantity + self.quantity = max(0, self.quantity - quantity) + + if self.quantity <= 0: + self.delete() + else: + self.save() + build_line = models.ForeignKey( BuildLine, on_delete=models.CASCADE, null=True, related_name='allocations' ) diff --git a/src/backend/InvenTree/build/serializers.py b/src/backend/InvenTree/build/serializers.py index 46ef73c4e9..172fdd6f2e 100644 --- a/src/backend/InvenTree/build/serializers.py +++ b/src/backend/InvenTree/build/serializers.py @@ -171,6 +171,9 @@ class BuildSerializer( def __init__(self, *args, **kwargs): """Determine if extra serializer fields are required.""" part_detail = kwargs.pop('part_detail', True) + user_detail = kwargs.pop('user_detail', True) + project_code_detail = kwargs.pop('project_code_detail', True) + kwargs.pop('create', False) super().__init__(*args, **kwargs) @@ -181,6 +184,15 @@ class BuildSerializer( if not part_detail: self.fields.pop('part_detail', None) + if not user_detail: + self.fields.pop('issued_by_detail', None) + self.fields.pop('responsible_detail', None) + + if not project_code_detail: + self.fields.pop('project_code', None) + self.fields.pop('project_code_label', None) + self.fields.pop('project_code_detail', None) + def validate_reference(self, reference): """Custom validation for the Build reference field.""" # Ensure the reference matches the required pattern @@ -1000,7 +1012,7 @@ class BuildAllocationItemSerializer(serializers.Serializer): class BuildAllocationSerializer(serializers.Serializer): - """DRF serializer for allocation stock items against a build order.""" + """Serializer for allocating stock items against a build order.""" class Meta: """Serializer metaclass.""" @@ -1302,6 +1314,8 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali 'build', 'bom_item', 'quantity', + 'consumed', + 'allocations', 'part', # Build detail fields 'build_reference', @@ -1353,6 +1367,7 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali if not part_detail: self.fields.pop('part_detail', None) + self.fields.pop('part_category_name', None) if not build_detail: self.fields.pop('build_detail', None) @@ -1379,7 +1394,7 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali read_only=True, ) - allocations = BuildItemSerializer(many=True, read_only=True) + allocations = BuildItemSerializer(many=True, read_only=True, build_detail=False) # BOM item info fields reference = serializers.CharField( @@ -1405,6 +1420,7 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali ) quantity = serializers.FloatField(label=_('Quantity')) + consumed = serializers.FloatField(label=_('Consumed')) bom_item = serializers.PrimaryKeyRelatedField(label=_('BOM Item'), read_only=True) @@ -1437,17 +1453,23 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali read_only=True, pricing=False, ) + build_detail = BuildSerializer( label=_('Build'), source='build', - part_detail=False, many=False, read_only=True, allow_null=True, + part_detail=False, + user_detail=False, + project_code_detail=False, ) # Annotated (calculated) fields - allocated = serializers.FloatField(label=_('Allocated Stock'), read_only=True) + + # Total quantity of allocated stock + allocated = serializers.FloatField(label=_('Allocated'), read_only=True) + on_order = serializers.FloatField(label=_('On Order'), read_only=True) in_production = serializers.FloatField(label=_('In Production'), read_only=True) scheduled_to_build = serializers.FloatField( @@ -1498,6 +1520,9 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali 'allocations__stock_item', 'allocations__stock_item__part', 'allocations__stock_item__location', + 'bom_item', + 'bom_item__part', + 'bom_item__sub_part', 'bom_item__sub_part__stock_items', 'bom_item__sub_part__stock_items__allocations', 'bom_item__sub_part__stock_items__sales_order_allocations', @@ -1518,7 +1543,6 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali 'build__destination', 'build__take_from', 'build__completed_by', - 'build__issued_by', 'build__sales_order', 'build__parent', 'build__notes', @@ -1692,3 +1716,177 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali ) return queryset + + +class BuildConsumeAllocationSerializer(serializers.Serializer): + """Serializer for an individual BuildItem to be consumed against a BuildOrder.""" + + class Meta: + """Serializer metaclass.""" + + fields = ['build_item', 'quantity'] + + build_item = serializers.PrimaryKeyRelatedField( + queryset=BuildItem.objects.all(), many=False, allow_null=False, required=True + ) + + quantity = serializers.DecimalField( + max_digits=15, decimal_places=5, min_value=Decimal(0), required=True + ) + + def validate_quantity(self, quantity): + """Perform validation on the 'quantity' field.""" + if quantity <= 0: + raise ValidationError(_('Quantity must be greater than zero')) + + return quantity + + def validate(self, data): + """Validate the serializer data.""" + data = super().validate(data) + + build_item = data['build_item'] + quantity = data['quantity'] + + if quantity > build_item.quantity: + raise ValidationError({ + 'quantity': _('Consumed quantity exceeds allocated quantity') + }) + + return data + + +class BuildConsumeLineItemSerializer(serializers.Serializer): + """Serializer for an individual BuildLine to be consumed against a BuildOrder.""" + + class Meta: + """Serializer metaclass.""" + + fields = ['build_line'] + + build_line = serializers.PrimaryKeyRelatedField( + queryset=BuildLine.objects.all(), many=False, allow_null=False, required=True + ) + + +class BuildConsumeSerializer(serializers.Serializer): + """Serializer for consuming allocations against a BuildOrder. + + - Consumes allocated stock items, increasing the 'consumed' field for each BuildLine. + - Stock can be consumed by passing either a list of BuildItem objects, or a list of BuildLine objects. + """ + + class Meta: + """Serializer metaclass.""" + + fields = ['items', 'lines', 'notes'] + + items = BuildConsumeAllocationSerializer(many=True, required=False) + + lines = BuildConsumeLineItemSerializer(many=True, required=False) + + notes = serializers.CharField( + label=_('Notes'), + help_text=_('Optional notes for the stock consumption'), + required=False, + allow_blank=True, + ) + + def validate_items(self, items): + """Validate the BuildItem list passed to the serializer.""" + build_order = self.context['build'] + + seen = set() + + for item in items: + build_item = item['build_item'] + + # BuildItem must point to the correct build order + if build_item.build != build_order: + raise ValidationError( + _('Build item must point to the correct build order') + ) + + # Prevent duplicate item allocation + if build_item.pk in seen: + raise ValidationError(_('Duplicate build item allocation')) + + seen.add(build_item.pk) + + return items + + def validate_lines(self, lines): + """Validate the BuildLine list passed to the serializer.""" + build_order = self.context['build'] + + seen = set() + + for line in lines: + build_line = line['build_line'] + + # BuildLine must point to the correct build order + if build_line.build != build_order: + raise ValidationError( + _('Build line must point to the correct build order') + ) + + # Prevent duplicate line allocation + if build_line.pk in seen: + raise ValidationError(_('Duplicate build line allocation')) + + seen.add(build_line.pk) + + return lines + + def validate(self, data): + """Validate the serializer data.""" + items = data.get('items', []) + lines = data.get('lines', []) + + if len(items) == 0 and len(lines) == 0: + raise ValidationError(_('At least one item or line must be provided')) + + return data + + def save(self): + """Perform the stock consumption step.""" + data = self.validated_data + request = self.context.get('request') + notes = data.get('notes', '') + + items = data.get('items', []) + lines = data.get('lines', []) + + with transaction.atomic(): + # Process the provided BuildItem objects + for item in items: + build_item = item['build_item'] + quantity = item['quantity'] + + if build_item.install_into: + # If the build item is tracked into an output, we do not consume now + # Instead, it gets consumed when the output is completed + continue + + build_item.complete_allocation( + quantity=quantity, + notes=notes, + user=request.user if request else None, + ) + + # Process the provided BuildLine objects + for line in lines: + build_line = line['build_line'] + + # In this case, perform full consumption of all allocated stock + for item in build_line.allocations.all(): + # If the build item is tracked into an output, we do not consume now + # Instead, it gets consumed when the output is completed + if item.install_into: + continue + + item.complete_allocation( + quantity=item.quantity, + notes=notes, + user=request.user if request else None, + ) diff --git a/src/backend/InvenTree/build/test_api.py b/src/backend/InvenTree/build/test_api.py index 41bec87577..511ba7a3de 100644 --- a/src/backend/InvenTree/build/test_api.py +++ b/src/backend/InvenTree/build/test_api.py @@ -990,11 +990,12 @@ class BuildOverallocationTest(BuildAPITest): self.assertEqual(si.quantity, oq) # Accept overallocated stock + # TODO: (2025-07-16) Look into optimizing this API query to reduce DB hits self.post( self.url, {'accept_overallocated': 'accept'}, expected_code=201, - max_query_count=375, + max_query_count=400, ) self.build.refresh_from_db() @@ -1009,11 +1010,12 @@ class BuildOverallocationTest(BuildAPITest): def test_overallocated_can_trim(self): """Test build order will trim/de-allocate overallocated stock when requested.""" + # TODO: (2025-07-16) Look into optimizing this API query to reduce DB hits self.post( self.url, {'accept_overallocated': 'trim'}, expected_code=201, - max_query_count=400, + max_query_count=450, ) # Note: Large number of queries is due to pricing recalculation for each stock item @@ -1323,3 +1325,177 @@ class BuildLineTests(BuildAPITest): self.assertGreater(n_f, 0) self.assertEqual(n_t + n_f, BuildLine.objects.count()) + + def test_filter_consumed(self): + """Filter for the 'consumed' status.""" + # Create a new build order + assembly = Part.objects.create( + name='Test Assembly', + description='Test Assembly Description', + assembly=True, + trackable=True, + ) + + for idx in range(3): + component = Part.objects.create( + name=f'Test Component {idx}', + description=f'Test Component Description {idx}', + trackable=True, + component=True, + ) + + # Create a BOM item for the assembly + BomItem.objects.create(part=assembly, sub_part=component, quantity=10) + + build = Build.objects.create( + part=assembly, reference='BO-12348', quantity=10, title='Test Build' + ) + + lines = list(build.build_lines.all()) + self.assertEqual(len(lines), 3) + + for line in lines: + self.assertEqual(line.quantity, 100) + self.assertEqual(line.consumed, 0) + + # Artificially "consume" some of the build lines + lines[0].consumed = 1 + lines[0].save() + + lines[1].consumed = 50 + lines[1].save() + + lines[2].consumed = 100 + lines[2].save() + + url = reverse('api-build-line-list') + + response = self.get(url, {'build': build.pk, 'consumed': True}) + + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]['pk'], lines[2].pk) + self.assertEqual(response.data[0]['consumed'], 100) + self.assertEqual(response.data[0]['quantity'], 100) + + response = self.get(url, {'build': build.pk, 'consumed': False}) + + self.assertEqual(len(response.data), 2) + self.assertEqual(response.data[0]['pk'], lines[0].pk) + self.assertEqual(response.data[0]['consumed'], 1) + self.assertEqual(response.data[0]['quantity'], 100) + self.assertEqual(response.data[1]['pk'], lines[1].pk) + self.assertEqual(response.data[1]['consumed'], 50) + self.assertEqual(response.data[1]['quantity'], 100) + + # Check that the 'available' filter works correctly also when lines are partially consumed + for line in lines: + StockItem.objects.create(part=line.bom_item.sub_part, quantity=60) + + # Note: The max_query_time is bumped up here, as postgresql backend has some strange issues (only during testing) + response = self.get( + url, {'build': build.pk, 'available': True}, max_query_time=15 + ) + + # We expect 2 lines to have "available" stock + self.assertEqual(len(response.data), 2) + + # Note: The max_query_time is bumped up here, as postgresql backend has some strange issues (only during testing) + response = self.get( + url, {'build': build.pk, 'available': False}, max_query_time=15 + ) + + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]['pk'], lines[0].pk) + + +class BuildConsumeTest(BuildAPITest): + """Test consuming allocated stock.""" + + def setUp(self): + """Set up test data.""" + super().setUp() + + self.assembly = Part.objects.create( + name='Test Assembly', description='Test Assembly Description', assembly=True + ) + + self.components = [ + Part.objects.create( + name=f'Test Component {i}', + description=f'Test Component Description {i}', + component=True, + ) + for i in range(3) + ] + + self.stock_items = [ + StockItem.objects.create(part=component, quantity=1000) + for component in self.components + ] + + self.bom_items = [ + BomItem.objects.create(part=self.assembly, sub_part=component, quantity=10) + for component in self.components + ] + + self.build = Build.objects.create( + part=self.assembly, reference='BO-12349', quantity=10, title='Test Build' + ) + + def allocate_stock(self): + """Allocate stock items to the build.""" + data = { + 'items': [ + {'build_line': line.pk, 'stock_item': si.pk, 'quantity': 100} + for line, si in zip(self.build.build_lines.all(), self.stock_items) + ] + } + + self.post( + reverse('api-build-allocate', kwargs={'pk': self.build.pk}), + data, + expected_code=201, + ) + + def test_consume_lines(self): + """Test consuming against build lines.""" + self.allocate_stock() + + self.assertEqual(self.build.allocated_stock.count(), 3) + self.assertEqual(self.build.consumed_stock.count(), 0) + url = reverse('api-build-consume', kwargs={'pk': self.build.pk}) + + data = { + 'lines': [{'build_line': line.pk} for line in self.build.build_lines.all()] + } + + self.post(url, data, expected_code=201) + + self.assertEqual(self.build.allocated_stock.count(), 0) + self.assertEqual(self.build.consumed_stock.count(), 3) + + for line in self.build.build_lines.all(): + self.assertEqual(line.consumed, 100) + + def test_consume_items(self): + """Test consuming against build items.""" + self.allocate_stock() + + self.assertEqual(self.build.allocated_stock.count(), 3) + self.assertEqual(self.build.consumed_stock.count(), 0) + url = reverse('api-build-consume', kwargs={'pk': self.build.pk}) + + data = { + 'items': [ + {'build_item': item.pk, 'quantity': item.quantity} + for item in self.build.allocated_stock.all() + ] + } + + self.post(url, data, expected_code=201) + + self.assertEqual(self.build.allocated_stock.count(), 0) + self.assertEqual(self.build.consumed_stock.count(), 3) + + for line in self.build.build_lines.all(): + self.assertEqual(line.consumed, 100) diff --git a/src/backend/InvenTree/part/models.py b/src/backend/InvenTree/part/models.py index 496cd24ef6..37642a3787 100644 --- a/src/backend/InvenTree/part/models.py +++ b/src/backend/InvenTree/part/models.py @@ -1400,9 +1400,10 @@ class Part( # Match BOM item to build for bom_item in bom_items: - build_quantity = build.quantity * bom_item.quantity + build_line = build.build_lines.filter(bom_item=bom_item).first() - quantity += build_quantity + line_quantity = max(0, build_line.quantity - build_line.consumed) + quantity += line_quantity return quantity diff --git a/src/frontend/lib/components/YesNoButton.tsx b/src/frontend/lib/components/YesNoButton.tsx index ee52e2af2c..a112692c08 100644 --- a/src/frontend/lib/components/YesNoButton.tsx +++ b/src/frontend/lib/components/YesNoButton.tsx @@ -1,24 +1,31 @@ import { t } from '@lingui/core/macro'; -import { Badge, Skeleton } from '@mantine/core'; +import { Badge, type MantineColor, Skeleton } from '@mantine/core'; import { isTrue } from '../functions/Conversion'; export function PassFailButton({ value, passText, - failText + failText, + passColor, + failColor }: Readonly<{ value: any; passText?: string; failText?: string; + passColor?: MantineColor; + failColor?: MantineColor; }>) { const v = isTrue(value); const pass = passText ?? t`Pass`; const fail = failText ?? t`Fail`; + const pColor = passColor ?? 'green'; + const fColor = failColor ?? 'red'; + return ( ) { - return ; + return ( + + ); } export function YesNoUndefinedButton({ value }: Readonly<{ value?: boolean }>) { diff --git a/src/frontend/lib/enums/ApiEndpoints.tsx b/src/frontend/lib/enums/ApiEndpoints.tsx index 628b858c34..badd9e14c2 100644 --- a/src/frontend/lib/enums/ApiEndpoints.tsx +++ b/src/frontend/lib/enums/ApiEndpoints.tsx @@ -96,6 +96,7 @@ export enum ApiEndpoints { build_output_delete = 'build/:id/delete-outputs/', build_order_auto_allocate = 'build/:id/auto-allocate/', build_order_allocate = 'build/:id/allocate/', + build_order_consume = 'build/:id/consume/', build_order_deallocate = 'build/:id/unallocate/', build_line_list = 'build/line/', diff --git a/src/frontend/src/components/render/Part.tsx b/src/frontend/src/components/render/Part.tsx index a76c45502a..dc6ae39db8 100644 --- a/src/frontend/src/components/render/Part.tsx +++ b/src/frontend/src/components/render/Part.tsx @@ -60,6 +60,10 @@ export function RenderPartCategory( ): ReactNode { const { instance } = props; + if (!instance) { + return ''; + } + const suffix: ReactNode = ( @@ -670,15 +674,220 @@ export function useAllocateStockToBuildForm({ successMessage: t`Stock items allocated`, onFormSuccess: onFormSuccess, initialData: { - items: lineItems.map((item) => { - return { - build_line: item.pk, - stock_item: undefined, - quantity: Math.max(0, item.requiredQuantity - item.allocatedQuantity), - output: outputId - }; - }) + items: lineItems + .filter((item) => { + return item.requiredQuantity > item.allocatedQuantity + item.consumed; + }) + .map((item) => { + return { + build_line: item.pk, + stock_item: undefined, + quantity: Math.max( + 0, + item.requiredQuantity - item.allocatedQuantity - item.consumed + ), + output: outputId + }; + }) }, size: '80%' }); } + +function BuildConsumeItemRow({ + props, + record +}: { + props: TableFieldRowProps; + record: any; +}) { + return ( + + + + + + + + + {record.location_detail && ( + + )} + + {record.quantity} + + { + props.changeFn(props.idx, 'quantity', value); + } + }} + error={props.rowErrors?.quantity?.message} + /> + + + props.removeFn(props.idx)} /> + + + ); +} + +/** + * Dynamic form for consuming stock against multiple BuildItem records + */ +export function useConsumeBuildItemsForm({ + buildId, + allocatedItems, + onFormSuccess +}: { + buildId: number; + allocatedItems: any[]; + onFormSuccess: (response: any) => void; +}) { + const consumeFields: ApiFormFieldSet = useMemo(() => { + return { + items: { + field_type: 'table', + value: [], + headers: [ + { title: t`Part` }, + { title: t`Stock Item` }, + { title: t`Location` }, + { title: t`Allocated` }, + { title: t`Quantity` } + ], + modelRenderer: (row: TableFieldRowProps) => { + const record = allocatedItems.find( + (item) => item.pk == row.item.build_item + ); + + return ( + + ); + } + }, + notes: {} + }; + }, [allocatedItems]); + + return useCreateApiFormModal({ + url: ApiEndpoints.build_order_consume, + pk: buildId, + title: t`Consume Stock`, + successMessage: t`Stock items consumed`, + onFormSuccess: onFormSuccess, + size: '80%', + fields: consumeFields, + initialData: { + items: allocatedItems.map((item) => { + return { + build_item: item.pk, + quantity: item.quantity + }; + }) + } + }); +} + +function BuildConsumeLineRow({ + props, + record +}: { + props: TableFieldRowProps; + record: any; +}) { + const allocated: number = record.allocatedQuantity ?? record.allocated; + const required: number = record.requiredQuantity ?? record.required; + const remaining: number = Math.max(0, required - record.consumed); + + return ( + + + + + + {remaining <= 0 ? ( + + + + {t`Fully consumed`} + + + ) : ( + + )} + + + + + + props.removeFn(props.idx)} /> + + + ); +} + +/** + * Dynamic form for consuming stock against multiple BuildLine records + */ +export function useConsumeBuildLinesForm({ + buildId, + buildLines, + onFormSuccess +}: { + buildId: number; + buildLines: any[]; + onFormSuccess: (response: any) => void; +}) { + const filteredLines = useMemo(() => { + return buildLines.filter((line) => !line.part_detail?.trackable); + }, [buildLines]); + + const consumeFields: ApiFormFieldSet = useMemo(() => { + return { + lines: { + field_type: 'table', + value: [], + headers: [ + { title: t`Part` }, + { title: t`Allocated` }, + { title: t`Consumed` } + ], + modelRenderer: (row: TableFieldRowProps) => { + const record = filteredLines.find( + (item) => item.pk == row.item.build_line + ); + + return ( + + ); + } + }, + notes: {} + }; + }, [filteredLines]); + + return useCreateApiFormModal({ + url: ApiEndpoints.build_order_consume, + pk: buildId, + title: t`Consume Stock`, + successMessage: t`Stock items consumed`, + onFormSuccess: onFormSuccess, + fields: consumeFields, + initialData: { + lines: filteredLines.map((item) => { + return { + build_line: item.pk + }; + }) + } + }); +} diff --git a/src/frontend/src/forms/StockForms.tsx b/src/frontend/src/forms/StockForms.tsx index b0ab6c25bc..3df3dd8543 100644 --- a/src/frontend/src/forms/StockForms.tsx +++ b/src/frontend/src/forms/StockForms.tsx @@ -46,6 +46,7 @@ import { import { Thumbnail } from '../components/images/Thumbnail'; import { StylishText } from '../components/items/StylishText'; import { StatusRenderer } from '../components/render/StatusRenderer'; +import { RenderStockLocation } from '../components/render/Stock'; import { InvenTreeIcon } from '../functions/icons'; import { useApiFormModal, @@ -576,7 +577,7 @@ function StockOperationsRow({ - {record.location ? record.location_detail?.pathstring : '-'} + {record.batch ? record.batch : '-'} diff --git a/src/frontend/src/tables/ColumnRenderers.tsx b/src/frontend/src/tables/ColumnRenderers.tsx index 155a2a8097..e840731e06 100644 --- a/src/frontend/src/tables/ColumnRenderers.tsx +++ b/src/frontend/src/tables/ColumnRenderers.tsx @@ -2,7 +2,7 @@ * Common rendering functions for table column data. */ import { t } from '@lingui/core/macro'; -import { Anchor, Group, Skeleton, Text, Tooltip } from '@mantine/core'; +import { Anchor, Center, Group, Skeleton, Text, Tooltip } from '@mantine/core'; import { IconBell, IconExclamationCircle, @@ -210,7 +210,9 @@ export function BooleanColumn(props: TableColumn): TableColumn { sortable: true, switchable: true, render: (record: any) => ( - +
+ +
), ...props }; diff --git a/src/frontend/src/tables/build/BuildAllocatedStockTable.tsx b/src/frontend/src/tables/build/BuildAllocatedStockTable.tsx index 9ce710ce25..e8ee86db27 100644 --- a/src/frontend/src/tables/build/BuildAllocatedStockTable.tsx +++ b/src/frontend/src/tables/build/BuildAllocatedStockTable.tsx @@ -10,8 +10,11 @@ import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; import { ModelType } from '@lib/enums/ModelType'; import { UserRoles } from '@lib/enums/Roles'; import { apiUrl } from '@lib/functions/Api'; +import { ActionButton } from '@lib/index'; import type { TableFilter } from '@lib/types/Filters'; import type { TableColumn } from '@lib/types/Tables'; +import { IconCircleDashedCheck } from '@tabler/icons-react'; +import { useConsumeBuildItemsForm } from '../../forms/BuildForms'; import type { StockOperationProps } from '../../forms/StockForms'; import { useDeleteApiFormModal, @@ -160,10 +163,10 @@ export default function BuildAllocatedStockTable({ ]; }, []); - const [selectedItem, setSelectedItem] = useState(0); + const [selectedItemId, setSelectedItemId] = useState(0); const editItem = useEditApiFormModal({ - pk: selectedItem, + pk: selectedItemId, url: ApiEndpoints.build_item_list, title: t`Edit Stock Allocation`, fields: { @@ -176,12 +179,23 @@ export default function BuildAllocatedStockTable({ }); const deleteItem = useDeleteApiFormModal({ - pk: selectedItem, + pk: selectedItemId, url: ApiEndpoints.build_item_list, title: t`Delete Stock Allocation`, table: table }); + const [selectedItems, setSelectedItems] = useState([]); + + const consumeStock = useConsumeBuildItemsForm({ + buildId: buildId ?? 0, + allocatedItems: selectedItems, + onFormSuccess: () => { + table.clearSelectedRecords(); + table.refreshTable(); + } + }); + const stockOperationProps: StockOperationProps = useMemo(() => { // Extract stock items from the selected records // Note that the table is actually a list of BuildItem instances, @@ -216,17 +230,28 @@ export default function BuildAllocatedStockTable({ const rowActions = useCallback( (record: any): RowAction[] => { return [ + { + color: 'green', + icon: , + title: t`Consume`, + tooltip: t`Consume Stock`, + hidden: !user.hasChangeRole(UserRoles.build), + onClick: () => { + setSelectedItems([record]); + consumeStock.open(); + } + }, RowEditAction({ hidden: !user.hasChangeRole(UserRoles.build), onClick: () => { - setSelectedItem(record.pk); + setSelectedItemId(record.pk); editItem.open(); } }), RowDeleteAction({ hidden: !user.hasDeleteRole(UserRoles.build), onClick: () => { - setSelectedItem(record.pk); + setSelectedItemId(record.pk); deleteItem.open(); } }) @@ -236,13 +261,28 @@ export default function BuildAllocatedStockTable({ ); const tableActions = useMemo(() => { - return [stockAdjustActions.dropdown]; - }, [stockAdjustActions.dropdown]); + return [ + stockAdjustActions.dropdown, + } + tooltip={t`Consume Stock`} + hidden={!user.hasChangeRole(UserRoles.build)} + disabled={table.selectedRecords.length == 0} + color='green' + onClick={() => { + setSelectedItems(table.selectedRecords); + consumeStock.open(); + }} + /> + ]; + }, [user, table.selectedRecords, stockAdjustActions.dropdown]); return ( <> {editItem.modal} {deleteItem.modal} + {consumeStock.modal} {stockAdjustActions.modals.map((modal) => modal.modal)} ) { const user = useUserState(); const navigate = useNavigate(); + const table = useTable('buildline-subtable'); const tableColumns: any[] = useMemo(() => { return [ @@ -96,59 +98,52 @@ export function BuildLineSubTable({ }, LocationColumn({ accessor: 'location_detail' - }), - { - accessor: '---actions---', - title: ' ', - width: 50, - render: (record: any) => { - return ( - { - onEditAllocation?.(record.pk); - } - }), - RowDeleteAction({ - hidden: - !onDeleteAllocation || !user.hasDeleteRole(UserRoles.build), - onClick: () => { - onDeleteAllocation?.(record.pk); - } - }) - ]} - /> - ); - } - } + }) ]; - }, [user, onEditAllocation, onDeleteAllocation]); + }, []); + + const rowActions = useCallback( + (record: any): RowAction[] => { + return [ + RowViewAction({ + title: t`View Stock Item`, + modelType: ModelType.stockitem, + modelId: record.stock_item, + navigate: navigate + }), + RowEditAction({ + hidden: !onEditAllocation || !user.hasChangeRole(UserRoles.build), + onClick: () => { + onEditAllocation?.(record.pk); + } + }), + RowDeleteAction({ + hidden: !onDeleteAllocation || !user.hasDeleteRole(UserRoles.build), + onClick: () => { + onDeleteAllocation?.(record.pk); + } + }) + ]; + }, + [user, onEditAllocation, onDeleteAllocation] + ); return ( - - - - + + ); } @@ -186,7 +181,12 @@ export default function BuildLineTable({ { name: 'allocated', label: t`Allocated`, - description: t`Show allocated lines` + description: t`Show fully allocated lines` + }, + { + name: 'consumed', + label: t`Consumed`, + description: t`Show fully consumed lines` }, { name: 'available', @@ -471,13 +471,56 @@ export default function BuildLineTable({ switchable: false, sortable: true, hidden: !isActive, + render: (record: any) => { + if (record?.bom_item_detail?.consumable) { + return ( + {t`Consumable item`} + ); + } + + let required = Math.max(0, record.quantity - record.consumed); + + if (output?.pk) { + // If an output is specified, we show the allocated quantity for that output + required = record.bom_item_detail?.quantity; + } + + if (required <= 0) { + return ( + + + + {record.consumed >= record.quantity + ? t`Fully consumed` + : t`Fully allocated`} + + + ); + } + + return ( + + ); + } + }, + { + accessor: 'consumed', + sortable: true, + hidden: !!output?.pk, render: (record: any) => { return record?.bom_item_detail?.consumable ? ( {t`Consumable item`} ) : ( ); @@ -544,6 +587,7 @@ export default function BuildLineTable({ buildId: build.pk, lineItems: selectedRows, onFormSuccess: () => { + table.clearSelectedRecords(); table.refreshTable(); } }); @@ -574,7 +618,10 @@ export default function BuildLineTable({ ), successMessage: t`Stock has been deallocated`, - table: table + onFormSuccess: () => { + table.clearSelectedRecords(); + table.refreshTable(); + } }); const [selectedAllocation, setSelectedAllocation] = useState(0); @@ -605,6 +652,15 @@ export default function BuildLineTable({ parts: partsToOrder }); + const consumeLines = useConsumeBuildLinesForm({ + buildId: build.pk, + buildLines: selectedRows, + onFormSuccess: () => { + table.clearSelectedRecords(); + table.refreshTable(); + } + }); + const rowActions = useCallback( (record: any): RowAction[] => { const part = record.part_detail ?? {}; @@ -613,11 +669,24 @@ export default function BuildLineTable({ const hasOutput = !!output?.pk; + const required = Math.max( + 0, + record.quantity - record.consumed - record.allocated + ); + + // Can consume + const canConsume = + in_production && + !consumable && + record.allocated > 0 && + user.hasChangeRole(UserRoles.build); + // Can allocate const canAllocate = in_production && !consumable && user.hasChangeRole(UserRoles.build) && + required > 0 && record.trackable == hasOutput; // Can de-allocate @@ -647,6 +716,16 @@ export default function BuildLineTable({ allocateStock.open(); } }, + { + icon: , + title: t`Consume Stock`, + color: 'green', + hidden: !canConsume || hasOutput, + onClick: () => { + setSelectedRows([record]); + consumeLines.open(); + } + }, { icon: , title: t`Deallocate Stock`, @@ -758,6 +837,18 @@ export default function BuildLineTable({ setSelectedLine(null); deallocateStock.open(); }} + />, + } + tooltip={t`Consume Stock`} + hidden={!visible || hasOutput} + disabled={!table.hasSelectedRecords} + color='green' + onClick={() => { + setSelectedRows(table.selectedRecords); + consumeLines.open(); + }} /> ]; }, [ @@ -843,6 +934,7 @@ export default function BuildLineTable({ {deallocateStock.modal} {editAllocation.modal} {deleteAllocation.modal} + {consumeLines.modal} {orderPartsWizard.wizard} + {t`Build Output Stock Allocation`} - - {output?.serial && ( - - {t`Serial Number`}: {output.serial} - - )} - {output?.batch && ( - - {t`Batch Code`}: {output.batch} - - )} + + + + {output?.serial && ( + + {t`Serial Number`}: {output.serial} + + )} + {output?.batch && ( + + {t`Batch Code`}: {output.batch} + + )} + + } diff --git a/src/frontend/src/tables/part/PartBuildAllocationsTable.tsx b/src/frontend/src/tables/part/PartBuildAllocationsTable.tsx index 5231e3d66f..2ca20d56de 100644 --- a/src/frontend/src/tables/part/PartBuildAllocationsTable.tsx +++ b/src/frontend/src/tables/part/PartBuildAllocationsTable.tsx @@ -12,6 +12,7 @@ import { UserRoles } from '@lib/enums/Roles'; import { apiUrl } from '@lib/functions/Api'; import type { TableFilter } from '@lib/types/Filters'; import type { TableColumn } from '@lib/types/Tables'; +import { IconCircleCheck } from '@tabler/icons-react'; import { useTable } from '../../hooks/UseTable'; import { useUserState } from '../../states/UserState'; import { @@ -92,13 +93,30 @@ export default function PartBuildAllocationsTable({ sortable: true, switchable: false, title: t`Required Stock`, - render: (record: any) => ( - - ) + render: (record: any) => { + const required = Math.max(0, record.quantity - record.consumed); + + if (required <= 0) { + return ( + + + + {record.consumed >= record.quantity + ? t`Fully consumed` + : t`Fully allocated`} + + + ); + } + + return ( + + ); + } } ]; }, [table.isRowExpanded]); @@ -142,11 +160,13 @@ export default function PartBuildAllocationsTable({ tableState={table} columns={tableColumns} props={{ - minHeight: 200, + minHeight: 300, params: { part: partId, consumable: false, - part_detail: true, + part_detail: false, + bom_item_detail: false, + project_code_detail: true, assembly_detail: true, build_detail: true, order_outstanding: true diff --git a/src/frontend/tests/pages/pui_build.spec.ts b/src/frontend/tests/pages/pui_build.spec.ts index eb933bb96e..9fd3d41c27 100644 --- a/src/frontend/tests/pages/pui_build.spec.ts +++ b/src/frontend/tests/pages/pui_build.spec.ts @@ -350,6 +350,59 @@ test('Build Order - Allocation', async ({ browser }) => { .waitFor(); }); +// Test partial stock consumption against build order +test('Build Order - Consume Stock', async ({ browser }) => { + const page = await doCachedLogin(browser, { + url: 'manufacturing/build-order/24/line-items' + }); + + // Check for expected progress values + await page.getByText('2 / 2', { exact: true }).waitFor(); + await page.getByText('8 / 10', { exact: true }).waitFor(); + await page.getByText('5 / 35', { exact: true }).waitFor(); + await page.getByText('5 / 40', { exact: true }).waitFor(); + + // Open the "Allocate Stock" dialog + await page.getByRole('checkbox', { name: 'Select all records' }).click(); + await page + .getByRole('button', { name: 'action-button-allocate-stock' }) + .click(); + await page + .getByLabel('Allocate Stock') + .getByText('5 / 35', { exact: true }) + .waitFor(); + await page.getByRole('button', { name: 'Cancel' }).click(); + + // Open the "Consume Stock" dialog + await page + .getByRole('button', { name: 'action-button-consume-stock' }) + .click(); + await page.getByLabel('Consume Stock').getByText('2 / 2').waitFor(); + await page.getByLabel('Consume Stock').getByText('8 / 10').waitFor(); + await page.getByLabel('Consume Stock').getByText('5 / 35').waitFor(); + await page.getByLabel('Consume Stock').getByText('5 / 40').waitFor(); + await page + .getByRole('textbox', { name: 'text-field-notes' }) + .fill('some notes here...'); + await page.getByRole('button', { name: 'Cancel' }).click(); + + // Try with a different build order + await navigate(page, 'manufacturing/build-order/26/line-items'); + await page.getByRole('checkbox', { name: 'Select all records' }).click(); + await page + .getByRole('button', { name: 'action-button-consume-stock' }) + .click(); + + await page.getByLabel('Consume Stock').getByText('306 / 1,900').waitFor(); + await page + .getByLabel('Consume Stock') + .getByText('Fully consumed') + .first() + .waitFor(); + + await page.waitForTimeout(1000); +}); + test('Build Order - Tracked Outputs', async ({ browser }) => { const page = await doCachedLogin(browser, { url: 'manufacturing/build-order/10/incomplete-outputs' diff --git a/src/frontend/tests/pages/pui_part.spec.ts b/src/frontend/tests/pages/pui_part.spec.ts index e40da22389..02f4b43808 100644 --- a/src/frontend/tests/pages/pui_part.spec.ts +++ b/src/frontend/tests/pages/pui_part.spec.ts @@ -249,7 +249,13 @@ test('Parts - Requirements', async ({ browser }) => { await page.getByText('5 / 100').waitFor(); // Allocated to sales orders await page.getByText('10 / 125').waitFor(); // In production - await page.waitForTimeout(2500); + // Also check requirements for part with open build orders which have been partially consumed + await navigate(page, 'part/105/details'); + + await page.getByText('Required: 2').waitFor(); + await page.getByText('Available: 32').waitFor(); + await page.getByText('In Stock: 34').waitFor(); + await page.getByText('2 / 2').waitFor(); // Allocated to build orders }); test('Parts - Allocations', async ({ browser }) => { @@ -377,7 +383,6 @@ test('Parts - Pricing (Supplier)', async ({ browser }) => { // Supplier Pricing await page.getByRole('button', { name: 'Supplier Pricing' }).click(); - await page.waitForTimeout(500); await page.getByRole('button', { name: 'SKU Not sorted' }).waitFor(); // Supplier Pricing - linkjumping diff --git a/src/frontend/tests/pages/pui_stock.spec.ts b/src/frontend/tests/pages/pui_stock.spec.ts index 2385b6058a..c198e39d5b 100644 --- a/src/frontend/tests/pages/pui_stock.spec.ts +++ b/src/frontend/tests/pages/pui_stock.spec.ts @@ -323,6 +323,7 @@ test('Stock - Return Items', async ({ browser }) => { name: 'action-menu-stock-operations-return-stock' }) .click(); + await page.getByText('#128').waitFor(); await page.getByText('Merge into existing stock').waitFor(); await page.getByRole('textbox', { name: 'number-field-quantity' }).fill('0'); diff --git a/src/frontend/tests/pui_plugins.spec.ts b/src/frontend/tests/pui_plugins.spec.ts index 1a7d0ea21f..4ae0b6bf6d 100644 --- a/src/frontend/tests/pui_plugins.spec.ts +++ b/src/frontend/tests/pui_plugins.spec.ts @@ -52,8 +52,6 @@ test('Plugins - Settings', async ({ browser, request }) => { .fill(originalValue == '999' ? '1000' : '999'); await page.getByRole('button', { name: 'Submit' }).click(); - await page.waitForTimeout(500); - // Change it back await page.getByLabel('edit-setting-NUMERICAL_SETTING').click(); await page.getByLabel('number-field-value').fill(originalValue); @@ -164,8 +162,6 @@ test('Plugins - Panels', async ({ browser, request }) => { value: true }); - await page.waitForTimeout(500); - // Ensure that the SampleUI plugin is enabled await setPluginState({ request, @@ -173,8 +169,6 @@ test('Plugins - Panels', async ({ browser, request }) => { state: true }); - await page.waitForTimeout(500); - // Navigate to the "part" page await navigate(page, 'part/69/'); @@ -186,20 +180,14 @@ test('Plugins - Panels', async ({ browser, request }) => { // Check out each of the plugin panels await loadTab(page, 'Broken Panel'); - await page.waitForTimeout(500); - await page.getByText('Error occurred while loading plugin content').waitFor(); - await loadTab(page, 'Dynamic Panel'); - await page.waitForTimeout(500); - await page.getByText('Instance ID: 69'); await page .getByText('This panel has been dynamically rendered by the plugin system') .waitFor(); await loadTab(page, 'Part Panel'); - await page.waitForTimeout(500); await page.getByText('This content has been rendered by a custom plugin'); // Disable the plugin, and ensure it is no longer visible @@ -260,8 +248,6 @@ test('Plugins - Locate Item', async ({ browser, request }) => { state: true }); - await page.waitForTimeout(500); - // Navigate to the "stock item" page await navigate(page, 'stock/item/287/'); await page.waitForLoadState('networkidle'); @@ -273,7 +259,6 @@ test('Plugins - Locate Item', async ({ browser, request }) => { // Show the location await page.getByLabel('breadcrumb-1-factory').click(); - await page.waitForTimeout(500); await page.getByLabel('action-button-locate-item').click(); await page.getByRole('button', { name: 'Submit' }).click();