def setUpClass(cls, *args, **kwargs): super().setUpClass(*args, **kwargs) cls.domain = 'case-dedupe-test' cls.case_type = 'adult' cls.factory = CaseFactory(cls.domain) cls.rule = AutomaticUpdateRule.objects.create( domain=cls.domain, name='test', case_type=cls.case_type, active=True, deleted=False, filter_on_server_modified=False, server_modified_boundary=None, workflow=AutomaticUpdateRule.WORKFLOW_DEDUPLICATE, ) _, cls.action = cls.rule.add_action( CaseDeduplicationActionDefinition, match_type=CaseDeduplicationMatchTypeChoices.ALL, case_properties=["name", "age"], ) cls.action.set_properties_to_update([ CaseDeduplicationActionDefinition.PropertyDefinition( name='is_potential_duplicate', value_type=CaseDeduplicationActionDefinition.VALUE_TYPE_EXACT, value='yes', ) ]) cls.action.save()
def reset_deduplicate_rule(rule): """Deletes all case duplicates for this rule """ from corehq.apps.data_interfaces.models import ( CaseDeduplicationActionDefinition, CaseDuplicate, ) deduplicate_action = CaseDeduplicationActionDefinition.from_rule(rule) CaseDuplicate.objects.filter(action=deduplicate_action).delete()
def _get_duplicates_count(self, rule): if rule.locked_for_editing: progress_helper = MessagingRuleProgressHelper(rule.id) return _( "Processing - {progress_percent}% ({cases_processed}/{total_cases} cases) complete" ).format( progress_percent=progress_helper.get_progress_pct(), cases_processed=progress_helper.get_cases_processed(), total_cases=progress_helper.get_total_cases_to_process(), ) action = CaseDeduplicationActionDefinition.from_rule(rule) return CaseDuplicate.objects.filter(action=action).count()
def setUpClass(cls): super().setUpClass() cls.domain = 'naboo' cls.case_type = 'people' cls.factory = CaseFactory(cls.domain) cls.pillow = get_xform_pillow(skip_ucr=True) cls.rule = AutomaticUpdateRule.objects.create( domain=cls.domain, name='test', case_type=cls.case_type, active=True, deleted=False, filter_on_server_modified=False, server_modified_boundary=None, workflow=AutomaticUpdateRule.WORKFLOW_DEDUPLICATE, ) _, cls.action = cls.rule.add_action( CaseDeduplicationActionDefinition, match_type=CaseDeduplicationMatchTypeChoices.ALL, case_properties=["case_name", "age"], ) cls.action.set_properties_to_update([ CaseDeduplicationActionDefinition.PropertyDefinition( name='age', value_type=CaseDeduplicationActionDefinition.VALUE_TYPE_EXACT, value='5', ), CaseDeduplicationActionDefinition.PropertyDefinition( name='case_name', value_type=CaseDeduplicationActionDefinition.VALUE_TYPE_EXACT, value='Herman Miller', ) ]) cls.action.save() AutomaticUpdateRule.clear_caches( cls.domain, AutomaticUpdateRule.WORKFLOW_DEDUPLICATE)
def _format_rule(self, rule): ret = super()._format_rule(rule) rule_properties = (set( CaseDeduplicationActionDefinition.from_rule(rule).case_properties) - set(CaseListExplorerColumns.DEFAULT_COLUMNS)) ret['duplicates_count'] = self._get_duplicates_count(rule) ret['explore_url'] = reverse_with_params( 'project_report_dispatcher', args=(self.domain, 'duplicate_cases'), params={ "duplicate_case_rule": rule.id, "explorer_columns": json.dumps(CaseListExplorerColumns.DEFAULT_COLUMNS + list(rule_properties)), }, ) return ret
def test_update_parent(self): es = get_es_new() with trap_extra_setup(ConnectionError): initialize_index_and_mapping(es, CASE_SEARCH_INDEX_INFO) self.addCleanup(ensure_index_deleted, CASE_SEARCH_INDEX_INFO.index) duplicates, uniques = self._create_cases(num_cases=2) parent = uniques[0] child = duplicates[0] set_parent_case(self.domain, child, parent) parent_case_property_value = parent.get_case_property('name') new_parent_case_property_value = f'{parent_case_property_value}-someextratext' self.action.set_properties_to_update([ CaseDeduplicationActionDefinition.PropertyDefinition( name='parent/name', value_type=CaseDeduplicationActionDefinition.VALUE_TYPE_EXACT, value=new_parent_case_property_value, ) ]) self.action.save() for case in chain(duplicates, uniques): send_to_elasticsearch( 'case_search', transform_case_for_elasticsearch(case.to_json())) es.indices.refresh(CASE_SEARCH_INDEX_INFO.index) self.rule = AutomaticUpdateRule.objects.get(id=self.rule.id) self.rule.run_actions_when_case_matches(child) updated_parent_case = CommCareCase.objects.get_case( parent.case_id, self.domain) self.assertEqual(updated_parent_case.get_case_property('name'), new_parent_case_property_value)
def backfill_deduplicate_rule(domain, rule): from corehq.apps.data_interfaces.models import ( AutomaticUpdateRule, CaseDeduplicationActionDefinition, DomainCaseRuleRun, ) progress_helper = MessagingRuleProgressHelper(rule.pk) total_cases_count = CaseSearchES().domain(domain).case_type( rule.case_type).count() progress_helper.set_total_cases_to_be_processed(total_cases_count) now = datetime.utcnow() try: run_record = DomainCaseRuleRun.objects.create( domain=domain, started_on=now, status=DomainCaseRuleRun.STATUS_RUNNING, case_type=rule.case_type, ) action = CaseDeduplicationActionDefinition.from_rule(rule) case_iterator = AutomaticUpdateRule.iter_cases( domain, rule.case_type, include_closed=action.include_closed) iter_cases_and_run_rules( domain, case_iterator, [rule], now, run_record.id, rule.case_type, progress_helper=progress_helper, ) finally: progress_helper.set_rule_complete() AutomaticUpdateRule.objects.filter(pk=rule.pk).update( locked_for_editing=False, last_run=now, )
def dedupe_action(self): return CaseDeduplicationActionDefinition.from_rule(self.rule)