From 7507b1cbe1d308255076590525d0661f32dbf27e Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Mon, 23 Dec 2024 10:32:04 +0100 Subject: [PATCH] :bug: [#4900] Recouple SubmissionValueVars for other forms for reusable FormDefinitions when bulk updating variables --- src/openforms/forms/tasks.py | 54 +++++++++++-------- .../forms/tests/variables/test_tasks.py | 18 +++---- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/openforms/forms/tasks.py b/src/openforms/forms/tasks.py index 8f8d382c8a..bcb8684b18 100644 --- a/src/openforms/forms/tasks.py +++ b/src/openforms/forms/tasks.py @@ -62,33 +62,45 @@ def recouple_submission_variables_to_form_variables(form_id: int) -> None: When the FormVariable bulk create/update endpoint is called, all existing FormVariable related to the form are deleted and new are created. If there are existing submissions for this form, the SubmissionValueVariables don't - have a related FormVariable anymore. This task tries to recouple them. + have a related FormVariable anymore. This task tries to recouple them and does the same for + other Forms in case of reusable FormDefinitions """ from openforms.submissions.models import SubmissionValueVariable - form = Form.objects.get(id=form_id) - submission_variables_to_recouple = SubmissionValueVariable.objects.filter( - form_variable__isnull=True, submission__form=form - ) + from .models import FormDefinition # due to circular import + + def recouple(form): + submission_variables_to_recouple = SubmissionValueVariable.objects.filter( + form_variable__isnull=True, submission__form=form + ) - form_variables = { - variable.key: variable for variable in form.formvariable_set.all() - } + form_variables = { + variable.key: variable for variable in form.formvariable_set.all() + } - submission_variables_to_update = [] - for submission_variable in submission_variables_to_recouple: - if form_variable := form_variables.get(submission_variable.key): - submission_variable.form_variable = form_variable - submission_variables_to_update.append(submission_variable) + submission_variables_to_update = [] + for submission_variable in submission_variables_to_recouple: + if form_variable := form_variables.get(submission_variable.key): + submission_variable.form_variable = form_variable + submission_variables_to_update.append(submission_variable) - try: - SubmissionValueVariable.objects.bulk_update( - submission_variables_to_update, fields=["form_variable"] - ) - except IntegrityError: - # Issue #1970: If the form is saved again from the form editor while this task was running, the form variables - # retrieved don't exist anymore. Another task will be scheduled from the endpoint, so nothing more to do here. - logger.info("Form variables were updated while this task was runnning.") + try: + SubmissionValueVariable.objects.bulk_update( + submission_variables_to_update, fields=["form_variable"] + ) + except IntegrityError: + # Issue #1970: If the form is saved again from the form editor while this task was running, the form variables + # retrieved don't exist anymore. Another task will be scheduled from the endpoint, so nothing more to do here. + logger.info("Form variables were updated while this task was runnning.") + + recouple(Form.objects.get(id=form_id)) + + fds = FormDefinition.objects.filter(formstep__form=form_id, is_reusable=True) + other_forms = Form.objects.filter(formstep__form_definition__in=fds).exclude( + id=form_id + ) + for form in other_forms: + recouple(form) @app.task(ignore_result=True) diff --git a/src/openforms/forms/tests/variables/test_tasks.py b/src/openforms/forms/tests/variables/test_tasks.py index 896499e9a5..f1b038e336 100644 --- a/src/openforms/forms/tests/variables/test_tasks.py +++ b/src/openforms/forms/tests/variables/test_tasks.py @@ -337,15 +337,15 @@ def test_on_formstep_save_event_fixes_broken_form_variables_state(self): self.assertEqual(first_name_submission_var1.form_variable, first_name_var1) - # with self.subTest( - # "Existing submission values for other form are recoupled with new variables" - # ): - # submission_vars2 = SubmissionValueVariable.objects.filter( - # submission__form=other_form - # ) + with self.subTest( + "Existing submission values for other form are recoupled with new variables" + ): + submission_vars2 = SubmissionValueVariable.objects.filter( + submission__form=other_form + ) - # self.assertEqual(submission_vars1.count(), 1) + self.assertEqual(submission_vars1.count(), 1) - # [first_name_submission_var2] = submission_vars2 + [first_name_submission_var2] = submission_vars2 - # self.assertEqual(first_name_submission_var2.form_variable, first_name_var2) + self.assertEqual(first_name_submission_var2.form_variable, first_name_var2)