BOM delete fix (#7586)

* Fix order of operations for BOM item bulk delete

* Improve error messaging

* Add "validate_delete" method
This commit is contained in:
Oliver 2024-07-09 00:45:47 +10:00 committed by GitHub
parent 11e70c9ba0
commit 633873365d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 8 deletions

View File

@ -311,8 +311,26 @@ class BulkDeleteMixin:
- Speed (single API call and DB query)
"""
def validate_delete(self, queryset, request) -> None:
"""Perform validation right before deletion.
Arguments:
queryset: The queryset to be deleted
request: The request object
Returns:
None
Raises:
ValidationError: If the deletion should not proceed
"""
pass
def filter_delete_queryset(self, queryset, request):
"""Provide custom filtering for the queryset *before* it is deleted."""
"""Provide custom filtering for the queryset *before* it is deleted.
The default implementation does nothing, just returns the queryset.
"""
return queryset
def delete(self, request, *args, **kwargs):
@ -371,6 +389,9 @@ class BulkDeleteMixin:
if filters:
queryset = queryset.filter(**filters)
# Run a final validation step (should raise an error if the deletion should not proceed)
self.validate_delete(queryset, request)
n_deleted = queryset.count()
queryset.delete()

View File

@ -1875,14 +1875,12 @@ class BomList(BomMixin, DataExportViewMixin, ListCreateDestroyAPIView):
'pricing_updated': 'sub_part__pricing_data__updated',
}
def filter_delete_queryset(self, queryset, request):
def validate_delete(self, queryset, request) -> None:
"""Ensure that there are no 'locked' items."""
for bom_item in queryset:
# Note: Calling check_part_lock may raise a ValidationError
bom_item.check_part_lock(bom_item.part)
return super().filter_delete_queryset(queryset, request)
class BomDetail(BomMixin, RetrieveUpdateDestroyAPI):
"""API endpoint for detail view of a single BomItem object."""

View File

@ -4101,16 +4101,16 @@ class BomItem(
"""
# TODO: Perhaps control this with a global setting?
msg = _('BOM item cannot be modified - assembly is locked')
if assembly.locked:
raise ValidationError(msg)
raise ValidationError(_('BOM item cannot be modified - assembly is locked'))
# If this BOM item is inherited, check all variants of the assembly
if self.inherited:
for part in assembly.get_descendants(include_self=False):
if part.locked:
raise ValidationError(msg)
raise ValidationError(
_('BOM item cannot be modified - variant assembly is locked')
)
# A link to the parent part
# Each part will get a reverse lookup field 'bom_items'