From f50b5006cc0230163acd88eff30ed69e29dd17b8 Mon Sep 17 00:00:00 2001 From: Matt Riley Date: Wed, 10 Jan 2024 21:07:05 -0500 Subject: [PATCH 1/6] gate dedupe updates behind existing toggle --- corehq/apps/data_interfaces/models.py | 6 +++++- corehq/apps/data_interfaces/views.py | 13 ++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/corehq/apps/data_interfaces/models.py b/corehq/apps/data_interfaces/models.py index 44a3c361727b..6388d4b2edf1 100644 --- a/corehq/apps/data_interfaces/models.py +++ b/corehq/apps/data_interfaces/models.py @@ -69,6 +69,7 @@ paginate_query, paginate_query_across_partitioned_databases, create_unique_index_name, ) +from corehq import toggles from corehq.util.log import with_progress_bar from corehq.util.quickcache import quickcache from corehq.util.test_utils import unit_testing_only @@ -1178,7 +1179,10 @@ def _handle_case_duplicate_new(self, case, rule): existing_duplicate.delete() duplicate_ids = self._create_duplicates(case, rule, current_hash) - num_updates = self._update_duplicates(duplicate_ids, case, rule) + if toggles.CASE_DEDUPE.enabled(rule.domain): + num_updates = self._update_duplicates(duplicate_ids, case, rule) + else: + num_updates = 0 return CaseRuleActionResult(num_updates=num_updates) def _create_duplicates(self, case, rule, current_hash): diff --git a/corehq/apps/data_interfaces/views.py b/corehq/apps/data_interfaces/views.py index 01a7f70bc79e..7d16b3b2fb05 100644 --- a/corehq/apps/data_interfaces/views.py +++ b/corehq/apps/data_interfaces/views.py @@ -1161,6 +1161,7 @@ def page_context(self): 'all_case_properties': self.get_augmented_data_dict_props_by_case_type(self.domain), 'case_types': sorted(list(get_case_types_for_domain(self.domain))), 'criteria_form': self.case_filter_form, + 'update_actions_enabled': toggles.CASE_DEDUPE.enabled(self.domain), }) return context @@ -1250,11 +1251,17 @@ def parse_params(self, request): if prop ], "include_closed": request.POST.get("include_closed") == "on", - "properties_to_update": [ + } + if toggles.CASE_DEDUPE.enabled(self.domain): + properties_to_update = [ {"name": prop["name"], "value_type": prop["valueType"], "value": prop["value"]} for prop in json.loads(request.POST.get("properties_to_update")) - ], - } + ] + else: + properties_to_update = [] + + action_params["properties_to_update"] = properties_to_update + return rule_params, action_params def validate_rule_params(self, domain, rule_params, rule=None): From 14db22ea0a6702b8acf31c4982719ef3dd668c2d Mon Sep 17 00:00:00 2001 From: Matt Riley Date: Wed, 10 Jan 2024 21:40:42 -0500 Subject: [PATCH 2/6] Remove general dedupe toggle --- corehq/apps/data_interfaces/pillow.py | 3 --- corehq/apps/data_interfaces/tasks.py | 5 +--- .../edit_deduplication_rule.html | 2 ++ .../tests/test_case_deduplication.py | 3 ++- corehq/apps/data_interfaces/views.py | 3 --- corehq/apps/users/tasks.py | 3 +-- corehq/reports.py | 3 +-- corehq/tabs/tabclasses.py | 23 ++++++++----------- corehq/toggles/__init__.py | 2 +- 9 files changed, 17 insertions(+), 30 deletions(-) diff --git a/corehq/apps/data_interfaces/pillow.py b/corehq/apps/data_interfaces/pillow.py index dd2020743910..0b9ce428528d 100644 --- a/corehq/apps/data_interfaces/pillow.py +++ b/corehq/apps/data_interfaces/pillow.py @@ -10,7 +10,6 @@ from corehq.form_processor.models import CommCareCase from corehq.form_processor.models.forms import XFormInstance from corehq.apps.hqcase.constants import UPDATE_REASON_RESAVE -from corehq.toggles import CASE_DEDUPE from corehq.util.soft_assert import soft_assert @@ -28,8 +27,6 @@ class CaseDeduplicationProcessor(PillowProcessor): def process_change(self, change): domain = change.metadata.domain - if not CASE_DEDUPE.enabled(domain): - return if change.deleted: # TODO: If a case gets deleted, we don't remove the duplicates for this case? diff --git a/corehq/apps/data_interfaces/tasks.py b/corehq/apps/data_interfaces/tasks.py index 814feff220c1..4c9f8ca78fff 100644 --- a/corehq/apps/data_interfaces/tasks.py +++ b/corehq/apps/data_interfaces/tasks.py @@ -27,7 +27,7 @@ from corehq.apps.case_importer.do_import import SubmitCaseBlockHandler, RowAndCase from corehq.motech.repeaters.models import SQLRepeatRecord from corehq.sql_db.util import get_db_aliases_for_partitioned_query -from corehq.toggles import CASE_DEDUPE, DISABLE_CASE_UPDATE_RULE_SCHEDULED_TASK +from corehq.toggles import DISABLE_CASE_UPDATE_RULE_SCHEDULED_TASK from corehq.util.celery_utils import no_result_task from corehq.util.decorators import serial_task from corehq.util.log import send_HTML_email @@ -66,9 +66,6 @@ def _progress_tracker(current, total): @no_result_task(queue='case_rule_queue', acks_late=True, soft_time_limit=15 * settings.CELERY_TASK_SOFT_TIME_LIMIT) def reset_and_backfill_deduplicate_rule_task(domain, rule_id): - if not CASE_DEDUPE.enabled(domain): - return - try: rule = AutomaticUpdateRule.objects.get( id=rule_id, diff --git a/corehq/apps/data_interfaces/templates/data_interfaces/edit_deduplication_rule.html b/corehq/apps/data_interfaces/templates/data_interfaces/edit_deduplication_rule.html index 4d30a3e683fe..868bda0fe858 100644 --- a/corehq/apps/data_interfaces/templates/data_interfaces/edit_deduplication_rule.html +++ b/corehq/apps/data_interfaces/templates/data_interfaces/edit_deduplication_rule.html @@ -87,6 +87,7 @@ {% crispy criteria_form %} + {% if update_actions_enabled %}
{% trans "Actions" %}
@@ -101,6 +102,7 @@
+ {% endif %} {% if not readonly %}
diff --git a/corehq/apps/data_interfaces/tests/test_case_deduplication.py b/corehq/apps/data_interfaces/tests/test_case_deduplication.py index 9897e1b660f0..1954e6b5822f 100644 --- a/corehq/apps/data_interfaces/tests/test_case_deduplication.py +++ b/corehq/apps/data_interfaces/tests/test_case_deduplication.py @@ -443,6 +443,7 @@ def test_find_duplicates_blank_case_properties(self): find_duplicate_case_ids(self.domain, cases[0], ["name", "dob"], match_type="ANY")) +@flag_enabled('CASE_DEDUPE') class CaseDeduplicationActionTest(TestCase): def setUp(self): super().setUp() @@ -692,7 +693,6 @@ def test_rule_deletion(self): self.rule.soft_delete() self.assertEqual(CaseDuplicateNew.objects.filter(action=self.action).count(), 0) - @flag_enabled('CASE_DEDUPE') def test_case_deletion(self): """Test that deleting cases also deletes Duplicate Relationships """ @@ -882,6 +882,7 @@ def _configure_properties_to_update(self, rule, prop_map): action.save() +@flag_enabled('CASE_DEDUPE') @es_test(requires=[case_search_adapter, user_adapter]) class TestDeduplicationRuleRuns(TestCase): def setUp(self): diff --git a/corehq/apps/data_interfaces/views.py b/corehq/apps/data_interfaces/views.py index 7d16b3b2fb05..ac67ef2f79a2 100644 --- a/corehq/apps/data_interfaces/views.py +++ b/corehq/apps/data_interfaces/views.py @@ -991,7 +991,6 @@ def read_only_mode(self): return True -@method_decorator(toggles.CASE_DEDUPE.required_decorator(), name='dispatch') class DeduplicationRuleListView(DataInterfaceSection, CRUDPaginatedViewMixin): template_name = 'data_interfaces/list_deduplication_rules.html' urlname = 'deduplication_rules' @@ -1148,7 +1147,6 @@ def _get_duplicates_count(self, rule): return CaseDuplicateNew.objects.filter(action=action).count() -@method_decorator(toggles.CASE_DEDUPE.required_decorator(), name='dispatch') class DeduplicationRuleCreateView(DataInterfaceSection): template_name = "data_interfaces/edit_deduplication_rule.html" urlname = 'add_deduplication_rule' @@ -1314,7 +1312,6 @@ def _create_rule(self, domain, name, case_type): ) -@method_decorator(toggles.CASE_DEDUPE.required_decorator(), name='dispatch') class DeduplicationRuleEditView(DeduplicationRuleCreateView): urlname = 'edit_deduplication_rule' page_title = gettext_lazy("Edit Deduplication Rule") diff --git a/corehq/apps/users/tasks.py b/corehq/apps/users/tasks.py index a0280d892565..bdbe66465e87 100644 --- a/corehq/apps/users/tasks.py +++ b/corehq/apps/users/tasks.py @@ -107,8 +107,7 @@ def tag_cases_as_deleted_and_remove_indices(domain, case_ids, deletion_id, delet _remove_indices_from_deleted_cases_task.delay(domain, case_ids) delete_phone_numbers_for_owners.delay(case_ids) delete_schedule_instances_for_cases.delay(domain, case_ids) - if toggles.CASE_DEDUPE.enabled(domain): - delete_duplicates_for_cases.delay(case_ids) + delete_duplicates_for_cases.delay(case_ids) @task(serializer='pickle', rate_limit=2, queue='background_queue', ignore_result=True, acks_late=True) diff --git a/corehq/reports.py b/corehq/reports.py index ce8c40e50840..105b6f60fa0a 100644 --- a/corehq/reports.py +++ b/corehq/reports.py @@ -108,8 +108,7 @@ def REPORTS(project): if toggles.CASE_LIST_EXPLORER.enabled(project.name) or domain_can_access_case_list_explorer: inspect_reports.append(CaseListExplorer) - if toggles.CASE_DEDUPE.enabled(project.name): - inspect_reports.append(DuplicateCasesExplorer) + inspect_reports.append(DuplicateCasesExplorer) deployments_reports = ( deployments.ApplicationStatusReport, diff --git a/corehq/tabs/tabclasses.py b/corehq/tabs/tabclasses.py index fa41f7b9683e..40575ebb4fbd 100644 --- a/corehq/tabs/tabclasses.py +++ b/corehq/tabs/tabclasses.py @@ -574,11 +574,6 @@ def can_view_ecd_preview(self): return (EXPLORE_CASE_DATA_PREVIEW.enabled_for_request(self._request) and is_eligible_for_ecd_preview(self._request)) - @property - @memoized - def can_deduplicate_cases(self): - return toggles.CASE_DEDUPE.enabled_for_request(self._request) - @property def _can_view_geospatial(self): return toggles.GEOSPATIAL.enabled(self.domain) @@ -943,15 +938,15 @@ def _get_edit_section(self): else: edit_section = [(gettext_lazy('Edit Data'), [automatic_update_rule_list_view])] - if self.can_deduplicate_cases: - from corehq.apps.data_interfaces.views import ( - DeduplicationRuleListView, - ) - deduplication_list_view = { - 'title': _(DeduplicationRuleListView.page_title), - 'url': reverse(DeduplicationRuleListView.urlname, args=[self.domain]), - } - edit_section[0][1].append(deduplication_list_view) + from corehq.apps.data_interfaces.views import ( + DeduplicationRuleListView, + ) + deduplication_list_view = { + 'title': _(DeduplicationRuleListView.page_title), + 'url': reverse(DeduplicationRuleListView.urlname, args=[self.domain]), + } + edit_section[0][1].append(deduplication_list_view) + return edit_section def _get_explore_data_views(self): diff --git a/corehq/toggles/__init__.py b/corehq/toggles/__init__.py index 3265cbd56ffe..d477fa7b3823 100644 --- a/corehq/toggles/__init__.py +++ b/corehq/toggles/__init__.py @@ -1464,7 +1464,7 @@ def _commtrackify(domain_name, toggle_is_enabled): CASE_DEDUPE = StaticToggle( 'case_dedupe', - 'Case deduplication feature', + 'Allow Case deduplication update actions', TAG_SOLUTIONS_LIMITED, [NAMESPACE_DOMAIN], help_link='https://confluence.dimagi.com/display/saas/Surfacing+Case+Duplicates+in+CommCare', From fe4d2819bef029dda24c311fcdd9e6f0d4c69c63 Mon Sep 17 00:00:00 2001 From: Matt Riley Date: Thu, 11 Jan 2024 21:12:10 -0500 Subject: [PATCH 3/6] update dedupe list description --- .../templates/data_interfaces/list_deduplication_rules.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/corehq/apps/data_interfaces/templates/data_interfaces/list_deduplication_rules.html b/corehq/apps/data_interfaces/templates/data_interfaces/list_deduplication_rules.html index 90ff3fe8ae63..3410caf33f8a 100644 --- a/corehq/apps/data_interfaces/templates/data_interfaces/list_deduplication_rules.html +++ b/corehq/apps/data_interfaces/templates/data_interfaces/list_deduplication_rules.html @@ -13,7 +13,7 @@

{% blocktrans %} - Create rules for finding and updating duplicate cases. + Create rules for finding duplicate cases. Rules are run on each form submission. When rules are created or edited the rule will be locked for further changes and a backfill process will be run. {% endblocktrans %} From e986e6c45d2c94d26ecc3266dd791338081ef837 Mon Sep 17 00:00:00 2001 From: Matt Riley Date: Thu, 18 Jan 2024 12:20:05 -0500 Subject: [PATCH 4/6] require pro plan or above to access dedupe features --- corehq/apps/data_interfaces/views.py | 3 +++ corehq/reports.py | 3 ++- corehq/tabs/tabclasses.py | 22 ++++++++++++++-------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/corehq/apps/data_interfaces/views.py b/corehq/apps/data_interfaces/views.py index ac67ef2f79a2..057027d30433 100644 --- a/corehq/apps/data_interfaces/views.py +++ b/corehq/apps/data_interfaces/views.py @@ -991,6 +991,7 @@ def read_only_mode(self): return True +@method_decorator(requires_privilege_with_fallback(privileges.CASE_DEDUPE), name='dispatch') class DeduplicationRuleListView(DataInterfaceSection, CRUDPaginatedViewMixin): template_name = 'data_interfaces/list_deduplication_rules.html' urlname = 'deduplication_rules' @@ -1147,6 +1148,7 @@ def _get_duplicates_count(self, rule): return CaseDuplicateNew.objects.filter(action=action).count() +@method_decorator(requires_privilege_with_fallback(privileges.CASE_DEDUPE), name='dispatch') class DeduplicationRuleCreateView(DataInterfaceSection): template_name = "data_interfaces/edit_deduplication_rule.html" urlname = 'add_deduplication_rule' @@ -1312,6 +1314,7 @@ def _create_rule(self, domain, name, case_type): ) +@method_decorator(requires_privilege_with_fallback(privileges.CASE_DEDUPE), name='dispatch') class DeduplicationRuleEditView(DeduplicationRuleCreateView): urlname = 'edit_deduplication_rule' page_title = gettext_lazy("Edit Deduplication Rule") diff --git a/corehq/reports.py b/corehq/reports.py index 105b6f60fa0a..e36e60a384ae 100644 --- a/corehq/reports.py +++ b/corehq/reports.py @@ -108,7 +108,8 @@ def REPORTS(project): if toggles.CASE_LIST_EXPLORER.enabled(project.name) or domain_can_access_case_list_explorer: inspect_reports.append(CaseListExplorer) - inspect_reports.append(DuplicateCasesExplorer) + if domain_has_privilege(project.name, privileges.CASE_DEDUPE): + inspect_reports.append(DuplicateCasesExplorer) deployments_reports = ( deployments.ApplicationStatusReport, diff --git a/corehq/tabs/tabclasses.py b/corehq/tabs/tabclasses.py index c9a67d3713bf..6472627f4258 100644 --- a/corehq/tabs/tabclasses.py +++ b/corehq/tabs/tabclasses.py @@ -482,6 +482,11 @@ def can_edit_commcare_data(self): def can_use_data_cleanup(self): return domain_has_privilege(self.domain, privileges.DATA_CLEANUP) + @property + @memoized + def can_use_dedupe(self): + return domain_has_privilege(self.domain, privileges.CASE_DEDUPE) + @property @memoized def can_export_data(self): @@ -938,14 +943,15 @@ def _get_edit_section(self): else: edit_section = [(gettext_lazy('Edit Data'), [automatic_update_rule_list_view])] - from corehq.apps.data_interfaces.views import ( - DeduplicationRuleListView, - ) - deduplication_list_view = { - 'title': _(DeduplicationRuleListView.page_title), - 'url': reverse(DeduplicationRuleListView.urlname, args=[self.domain]), - } - edit_section[0][1].append(deduplication_list_view) + if self.can_use_dedupe: + from corehq.apps.data_interfaces.views import ( + DeduplicationRuleListView, + ) + deduplication_list_view = { + 'title': _(DeduplicationRuleListView.page_title), + 'url': reverse(DeduplicationRuleListView.urlname, args=[self.domain]), + } + edit_section[0][1].append(deduplication_list_view) return edit_section From faef8777676e52ea1a4dc50a57addbc819aeb7eb Mon Sep 17 00:00:00 2001 From: Matt Riley Date: Thu, 18 Jan 2024 21:08:27 -0500 Subject: [PATCH 5/6] add a frozen toggle to support the previous CASE_DEDUPE toggle --- .../0037_add_dedupe_update_toggle.py | 27 +++++++++++++++++++ corehq/apps/data_interfaces/models.py | 2 +- .../tests/test_case_deduplication.py | 8 +++--- corehq/apps/data_interfaces/views.py | 2 +- corehq/toggles/__init__.py | 12 +++++++-- migrations.lock | 1 + 6 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 corehq/apps/data_interfaces/migrations/0037_add_dedupe_update_toggle.py diff --git a/corehq/apps/data_interfaces/migrations/0037_add_dedupe_update_toggle.py b/corehq/apps/data_interfaces/migrations/0037_add_dedupe_update_toggle.py new file mode 100644 index 000000000000..5966a82b31da --- /dev/null +++ b/corehq/apps/data_interfaces/migrations/0037_add_dedupe_update_toggle.py @@ -0,0 +1,27 @@ +from django.db import migrations +from corehq.util.django_migrations import skip_on_fresh_install + +from corehq.toggles import CASE_DEDUPE, CASE_DEDUPE_UPDATES, NAMESPACE_DOMAIN +from corehq.toggles.models import Toggle + + +@skip_on_fresh_install +def add_dedupe_update_toggle(apps, schema_editor): + for domain in CASE_DEDUPE.get_enabled_domains(): + CASE_DEDUPE_UPDATES.set(domain, enabled=True, namespace=NAMESPACE_DOMAIN) + + +def reverse(apps, schema_editor): + toggle = Toggle.cached_get(CASE_DEDUPE_UPDATES.slug) + toggle.delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('data_interfaces', '0036_backfill_dedupe_match_values'), + ] + + operations = [ + migrations.RunPython(add_dedupe_update_toggle, reverse_code=reverse), + ] diff --git a/corehq/apps/data_interfaces/models.py b/corehq/apps/data_interfaces/models.py index c48ef601dff7..5dd1c9e02df1 100644 --- a/corehq/apps/data_interfaces/models.py +++ b/corehq/apps/data_interfaces/models.py @@ -1169,7 +1169,7 @@ def _handle_case_duplicate_new(self, case, rule): existing_duplicate.delete() duplicate_ids = self._create_duplicates(case, rule, current_hash) - if toggles.CASE_DEDUPE.enabled(rule.domain): + if toggles.CASE_DEDUPE_UPDATES.enabled(rule.domain): num_updates = self._update_duplicates(duplicate_ids, case, rule) else: num_updates = 0 diff --git a/corehq/apps/data_interfaces/tests/test_case_deduplication.py b/corehq/apps/data_interfaces/tests/test_case_deduplication.py index 1954e6b5822f..e34b210b9777 100644 --- a/corehq/apps/data_interfaces/tests/test_case_deduplication.py +++ b/corehq/apps/data_interfaces/tests/test_case_deduplication.py @@ -443,7 +443,7 @@ def test_find_duplicates_blank_case_properties(self): find_duplicate_case_ids(self.domain, cases[0], ["name", "dob"], match_type="ANY")) -@flag_enabled('CASE_DEDUPE') +@flag_enabled('CASE_DEDUPE_UPDATES') class CaseDeduplicationActionTest(TestCase): def setUp(self): super().setUp() @@ -756,7 +756,7 @@ def test_update_parent(self): @override_settings(RUN_UNKNOWN_USER_PILLOW=False) @override_settings(RUN_FORM_META_PILLOW=False) -@flag_enabled('CASE_DEDUPE') +@flag_enabled('CASE_DEDUPE_UPDATES') class DeduplicationPillowTest(TestCase): @classmethod @@ -882,7 +882,7 @@ def _configure_properties_to_update(self, rule, prop_map): action.save() -@flag_enabled('CASE_DEDUPE') +@flag_enabled('CASE_DEDUPE_UPDATES') @es_test(requires=[case_search_adapter, user_adapter]) class TestDeduplicationRuleRuns(TestCase): def setUp(self): @@ -1175,7 +1175,7 @@ def test_rule_with_user_as_owner(self): self.assertEqual(refreshed_fake_cases[1].get_case_property('age'), '14') -@flag_enabled('CASE_DEDUPE') +@flag_enabled('CASE_DEDUPE_UPDATES') @es_test(requires=[case_search_adapter], setup_class=True) class DeduplicationBackfillTest(TestCase): @classmethod diff --git a/corehq/apps/data_interfaces/views.py b/corehq/apps/data_interfaces/views.py index 057027d30433..df395bc92f17 100644 --- a/corehq/apps/data_interfaces/views.py +++ b/corehq/apps/data_interfaces/views.py @@ -1252,7 +1252,7 @@ def parse_params(self, request): ], "include_closed": request.POST.get("include_closed") == "on", } - if toggles.CASE_DEDUPE.enabled(self.domain): + if toggles.CASE_DEDUPE_UPDATES.enabled(self.domain): properties_to_update = [ {"name": prop["name"], "value_type": prop["valueType"], "value": prop["value"]} for prop in json.loads(request.POST.get("properties_to_update")) diff --git a/corehq/toggles/__init__.py b/corehq/toggles/__init__.py index c4ab03804060..6f48ab5e4f67 100644 --- a/corehq/toggles/__init__.py +++ b/corehq/toggles/__init__.py @@ -1469,8 +1469,8 @@ def _commtrackify(domain_name, toggle_is_enabled): [NAMESPACE_DOMAIN], ) -CASE_DEDUPE = StaticToggle( - 'case_dedupe', +CASE_DEDUPE_UPDATES = StaticToggle( + 'case_dedupe_updates', 'Allow Case deduplication update actions', TAG_SOLUTIONS_LIMITED, [NAMESPACE_DOMAIN], @@ -2692,6 +2692,14 @@ def domain_has_privilege_from_toggle(privilege_slug, domain): help_link='https://confluence.dimagi.com/display/commcarepublic/Data+Dictionary' ) +CASE_DEDUPE = FrozenPrivilegeToggle( + privileges.CASE_DEDUPE, + 'case_dedupe', + label='Case deduplication feature', + tag=TAG_SOLUTIONS_LIMITED, + namespaces=[NAMESPACE_DOMAIN], + help_link='https://confluence.dimagi.com/display/saas/Surfacing+Case+Duplicates+in+CommCare', +) CUSTOM_DOMAIN_BANNER_ALERTS = StaticToggle( slug='custom_domain_banners', diff --git a/migrations.lock b/migrations.lock index f35326746721..3e0c3026a75c 100644 --- a/migrations.lock +++ b/migrations.lock @@ -340,6 +340,7 @@ data_interfaces 0034_case_name_actions 0035_add_case_duplicate_new 0036_backfill_dedupe_match_values + 0037_add_dedupe_update_toggle dhis2 0001_initial 0002_auto_20170322_1323 From 1d531e28922497b44f506e677b00bf4a6fb0254e Mon Sep 17 00:00:00 2001 From: Matt Riley Date: Wed, 24 Jan 2024 14:04:23 -0500 Subject: [PATCH 6/6] Correctly gate dedupe actions behind the proper toggle --- corehq/apps/data_interfaces/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/corehq/apps/data_interfaces/views.py b/corehq/apps/data_interfaces/views.py index df395bc92f17..1bf8f1ed2bd7 100644 --- a/corehq/apps/data_interfaces/views.py +++ b/corehq/apps/data_interfaces/views.py @@ -1161,7 +1161,7 @@ def page_context(self): 'all_case_properties': self.get_augmented_data_dict_props_by_case_type(self.domain), 'case_types': sorted(list(get_case_types_for_domain(self.domain))), 'criteria_form': self.case_filter_form, - 'update_actions_enabled': toggles.CASE_DEDUPE.enabled(self.domain), + 'update_actions_enabled': toggles.CASE_DEDUPE_UPDATES.enabled(self.domain), }) return context