@@ -0,0 +1,2919 @@
+from __future__ import absolute_import%0Afrom __future__ import print_function%0Afrom collections import defaultdict%0Aimport csv%0Aimport datetime%0Afrom django.core.management.base import BaseCommand%0A%0Afrom dimagi.utils.decorators.memoized import memoized%0A%0Afrom corehq.apps.locations.models import SQLLocation%0Afrom corehq.apps.hqcase.utils import bulk_update_cases%0Afrom corehq.util.log import with_progress_bar%0A%0Afrom custom.enikshay.case_utils import CASE_TYPE_PERSON%0Afrom custom.enikshay.duplicate_ids import get_cases_with_duplicate_ids%0A%0A%0Aclass Command(BaseCommand):%0A    help = %22%22%22%0A    Finds cases with duplicate IDs and marks all but one of each ID as a duplicate%0A    %22%22%22%0A    # TODO what are the headers we need?%0A    logfile_fields = %5B'name', 'dto_name', 'phi_name', 'owner_id', 'dob', 'phone_number'%5D%0A%0A    def add_arguments(self, parser):%0A        parser.add_argument('domain')%0A        parser.add_argument(%0A            '--commit',%0A            action='store_true',%0A            dest='commit',%0A            default=False,%0A        )%0A%0A    def handle(self, domain, **options):%0A        self.domain = domain%0A        commit = options%5B'commit'%5D%0A%0A        filename = '%7B%7D-%7B%7D.csv'.format(self.__module__.split('.')%5B-1%5D,%0A                                      datetime.datetime.now().strftime('%25Y-%25m-%25d_%25H.%25M.%25S'))%0A        print(%22Logging actions to %7B%7D%22.format(filename))%0A        with open(filename, 'w') as f:%0A            logfile = csv.DictWriter(f, self.logfile_fields, extrasaction='ignore')%0A            logfile.writeheader()%0A%0A            print(%22Finding duplicates%22)%0A            bad_cases = get_cases_with_duplicate_ids(self.domain, CASE_TYPE_PERSON)%0A%0A            print(%22Processing duplicate cases%22)%0A            for person_case in with_progress_bar(bad_cases):%0A                updates = self.get_updates(person_case)%0A                case_info = self.get_person_case_info(person_case)%0A                for update in updates:%0A                    logfile.writerow(update)%0A                bulk_update_cases(self.domain, updates, self.__module__)%0A%0A    @staticmethod%0A    def get_updates(person_case):%0A        pass%0A%0A    @property%0A    @memoized%0A    def districts_by_id(self):%0A        locs = SQLLocation.objects.filter(domain=self.domain, location_type__code='dto')%0A        return defaultdict(lambda: '', (%0A            (loc.location_id, loc.loc_name) for loc in locs%0A        ))%0A%0A    def get_person_case_info(self, person_case):%0A        %22%22%22Pull info that we want to log but not update%22%22%22%0A        person = person_case.dynamic_case_properties()%0A        return %7B%0A            'name': ' '.join(filter(None, %5Bperson.get('first_name'), person.get('last_name')%5D)),%0A            'dto_name': self.districts_by_id(person.get('current_address_district_choice')),%0A            'phi_name': person.get('phi'),%0A            'owner_id': person_case.owner_id,%0A            'dob': person.get('dob'),%0A            'phone_number': person.get('contact_phone_number'),%0A        %7D%0A

Add basic duplicate resolution cmd with log info