diff --git a/src/backend/InvenTree/common/filters.py b/src/backend/InvenTree/common/filters.py index 7bde1b7f4e..417d4dad90 100644 --- a/src/backend/InvenTree/common/filters.py +++ b/src/backend/InvenTree/common/filters.py @@ -210,7 +210,7 @@ def filter_parametric_data(queryset: QuerySet, parameters: dict[str, str]) -> Qu - parameter__lte= where: - - is the ID of the PartParameterTemplate. + - is the ID of the ParameterTemplate. - is the value to filter against. Typically these filters would be provided against via an API request. @@ -257,7 +257,7 @@ def order_by_parameter( - -parameter_ where: - - is the ID of the PartParameterTemplate. + - is the ID of the ParameterTemplate. - A leading '-' indicates descending order. """ import common.models diff --git a/src/backend/InvenTree/common/models.py b/src/backend/InvenTree/common/models.py index addfe484cb..84af7ebfd3 100644 --- a/src/backend/InvenTree/common/models.py +++ b/src/backend/InvenTree/common/models.py @@ -2531,6 +2531,24 @@ class ParameterTemplate( ) +@receiver( + post_save, sender=ParameterTemplate, dispatch_uid='post_save_parameter_template' +) +def post_save_parameter_template(sender, instance, created, **kwargs): + """Callback function when a ParameterTemplate is created or saved.""" + import common.tasks + + if InvenTree.ready.canAppAccessDatabase() and not InvenTree.ready.isImportingData(): + if not created: + # Schedule a background task to rebuild the parameters against this template + InvenTree.tasks.offload_task( + common.tasks.rebuild_parameters, + instance.pk, + force_async=True, + group='part', + ) + + class Parameter( UpdatedUserMixin, InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel ): diff --git a/src/backend/InvenTree/common/tasks.py b/src/backend/InvenTree/common/tasks.py index a718c2e201..6a86367937 100644 --- a/src/backend/InvenTree/common/tasks.py +++ b/src/backend/InvenTree/common/tasks.py @@ -172,3 +172,35 @@ def delete_old_notes_images(): if not found: logger.info('Deleting note %s - image file not linked to a note', image) os.remove(os.path.join(notes_dir, image)) + + +@tracer.start_as_current_span('rebuild_parameters') +def rebuild_parameters(template_id): + """Rebuild all parameters for a given template. + + This function is called when a base template is changed, + which may cause the base unit to be adjusted. + """ + from common.models import Parameter, ParameterTemplate + + try: + template = ParameterTemplate.objects.get(pk=template_id) + except ParameterTemplate.DoesNotExist: + return + + parameters = Parameter.objects.filter(template=template) + + n = 0 + + for parameter in parameters: + # Update the parameter if the numeric value has changed + value_old = parameter.data_numeric + parameter.calculate_numeric_value() + + if value_old != parameter.data_numeric: + parameter.full_clean() + parameter.save() + n += 1 + + if n > 0: + logger.info("Rebuilt %s parameters for template '%s'", n, template.name) diff --git a/src/backend/InvenTree/part/tasks.py b/src/backend/InvenTree/part/tasks.py index e168b6d33a..a7008f7576 100644 --- a/src/backend/InvenTree/part/tasks.py +++ b/src/backend/InvenTree/part/tasks.py @@ -355,38 +355,6 @@ def scheduled_stocktake_reports(): record_task_success('STOCKTAKE_RECENT_REPORT') -@tracer.start_as_current_span('rebuild_parameters') -def rebuild_parameters(template_id): - """Rebuild all parameters for a given template. - - This function is called when a base template is changed, - which may cause the base unit to be adjusted. - """ - from part.models import PartParameter, PartParameterTemplate - - try: - template = PartParameterTemplate.objects.get(pk=template_id) - except PartParameterTemplate.DoesNotExist: - return - - parameters = PartParameter.objects.filter(template=template) - - n = 0 - - for parameter in parameters: - # Update the parameter if the numeric value has changed - value_old = parameter.data_numeric - parameter.calculate_numeric_value() - - if value_old != parameter.data_numeric: - parameter.full_clean() - parameter.save() - n += 1 - - if n > 0: - logger.info("Rebuilt %s parameters for template '%s'", n, template.name) - - @tracer.start_as_current_span('rebuild_supplier_parts') def rebuild_supplier_parts(part_id: int): """Rebuild all SupplierPart objects for a given part.