From 0c17f447112b514ab7d2fde0903d8ee752baa2b9 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 1 Dec 2025 04:37:17 +0000 Subject: [PATCH] Reimplement checks for locked parts --- src/backend/InvenTree/InvenTree/models.py | 14 ++++++++++ src/backend/InvenTree/common/models.py | 33 ++++++++++++++++++++--- src/backend/InvenTree/part/models.py | 10 +++++++ 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/backend/InvenTree/InvenTree/models.py b/src/backend/InvenTree/InvenTree/models.py index 703629120b..c80baa5002 100644 --- a/src/backend/InvenTree/InvenTree/models.py +++ b/src/backend/InvenTree/InvenTree/models.py @@ -627,6 +627,20 @@ class InvenTreeParameterMixin(InvenTreePermissionCheckMixin, models.Model): return params + def check_parameter_delete(self, parameter): + """Run a check to determine if the provided parameter can be deleted. + + The default implementation always returns True, but this can be overridden in the implementing class. + """ + return True + + def check_parameter_save(self, parameter): + """Run a check to determine if the provided parameter can be saved. + + The default implementation always returns True, but this can be overridden in the implementing class. + """ + return True + class InvenTreeAttachmentMixin(InvenTreePermissionCheckMixin): """Provides an abstracted class for managing file attachments. diff --git a/src/backend/InvenTree/common/models.py b/src/backend/InvenTree/common/models.py index d60f384fb6..f0e9637bf1 100644 --- a/src/backend/InvenTree/common/models.py +++ b/src/backend/InvenTree/common/models.py @@ -2584,8 +2584,6 @@ class Parameter( - Update the numeric data field (if applicable) """ - # TODO: Custom call against the model type this is linked to... - self.calculate_numeric_value() # Convert 'boolean' values to 'True' / 'False' @@ -2593,11 +2591,12 @@ class Parameter( self.data = InvenTree.helpers.str2bool(self.data) self.data_numeric = 1 if self.data else 0 + self.check_save() super().save(*args, **kwargs) def delete(self): """Perform custom delete checks before deleting a Parameter instance.""" - # TODO: Custom delete checks against the model type this is linked to... + self.check_delete() super().delete() def clean(self): @@ -2681,6 +2680,34 @@ class Parameter( return model_class.check_related_permission(permission, user) + def check_save(self): + """Check if this parameter can be saved. + + The linked content_object can implement custom checks by overriding + the 'check_parameter_edit' method. + """ + from InvenTree.models import InvenTreeParameterMixin + + try: + instance = self.content_object + except InvenTree.models.InvenTreeModel.DoesNotExist: + return + + if instance and isinstance(instance, InvenTreeParameterMixin): + instance.check_parameter_save(self) + + def check_delete(self): + """Check if this parameter can be deleted.""" + from InvenTree.models import InvenTreeParameterMixin + + try: + instance = self.content_object + except InvenTree.models.InvenTreeModel.DoesNotExist: + return + + if instance and isinstance(instance, InvenTreeParameterMixin): + instance.check_parameter_delete(self) + # TODO: Reintroduce validator for model_type model_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) diff --git a/src/backend/InvenTree/part/models.py b/src/backend/InvenTree/part/models.py index ffdc6e735f..2f2b74961f 100644 --- a/src/backend/InvenTree/part/models.py +++ b/src/backend/InvenTree/part/models.py @@ -591,6 +591,16 @@ class Part( 'test_templates': self.getTestTemplateMap(), } + def check_parameter_delete(self, parameter): + """Custom delete check for Paramteter instances associated with this Part.""" + if self.locked: + raise ValidationError(_('Cannot delete parameters of a locked part')) + + def check_parameter_save(self, parameter): + """Custom save check for Parameter instances associated with this Part.""" + if self.locked: + raise ValidationError(_('Cannot modify parameters of a locked part')) + def delete(self, **kwargs): """Custom delete method for the Part model.