Esempio n. 1
0
    def handle(self, *args, **options):
        domain = options["domain"]
        case_id = options["case_id"]
        case_accessor = CaseAccessors(domain=domain)
        case = case_accessor.get_case(case_id)
        if (
            not case.is_deleted
            and raw_input(
                "\n".join(["Case {} is not already deleted. Are you sure you want to delete it? (y/N)".format(case_id)])
            ).lower()
            != "y"
        ):
            sys.exit(0)
        dependent_case_ids = get_entire_case_network(domain, [case_id])

        cases_to_delete = filter(lambda case: not case.is_deleted, case_accessor.get_cases(dependent_case_ids))
        if cases_to_delete:
            with open(options["filename"], "w") as csvfile:
                writer = csv.writer(csvfile)
                headers = ["case id", "case type", "owner", "opened by", "app version"]
                writer.writerow(headers)
                print headers

                for case in cases_to_delete:
                    form = FormAccessors(domain=domain).get_form(case.xform_ids[0])
                    app_version_info = get_app_version_info(
                        domain, form.build_id, form.form_data["@version"], form.metadata
                    )
                    row = [
                        case.case_id,
                        case.type,
                        cached_owner_id_to_display(case.owner_id) or case.owner_id,
                        cached_owner_id_to_display(case.opened_by),
                        app_version_info.build_version,
                    ]
                    writer.writerow(row)
                    print row

        if (
            cases_to_delete
            and raw_input("\n".join(["Delete these {} cases? (y/N)".format(len(cases_to_delete))])).lower() == "y"
        ):
            case_accessor.soft_delete_cases([c.case_id for c in cases_to_delete])
            print "deleted {} cases".format(len(cases_to_delete))

        if cases_to_delete:
            print "details here: {}".format(options["filename"])
        else:
            print "didn't find any cases to delete"
Esempio n. 2
0
 def related_cases_columns(self):
     return [
         {
             'name': _('Status'),
             'expr': "status"
         },
         {
             'name': _('Case Type'),
             'expr': "type",
         },
         {
             'name': _('Owner'),
             'expr': lambda c: cached_owner_id_to_display(c.get('owner_id')),
         },
         {
             'name': _('Date Opened'),
             'expr': "opened_on",
             'parse_date': True,
             "is_phone_time": True,
         },
         {
             'name': _('Date Modified'),
             'expr': "modified_on",
             'parse_date': True,
             "is_phone_time": True,
         }
     ]
Esempio n. 3
0
 def related_cases_columns(self):
     return [
         {
             'name': _('Status'),
             'expr': "status"
         },
         {
             'name': _('Case Type'),
             'expr': "type",
         },
         {
             'name': _('Owner'),
             'expr': lambda c: cached_owner_id_to_display(c.get('owner_id')),
         },
         {
             'name': _('Date Opened'),
             'expr': "opened_on",
             'parse_date': True,
             "is_phone_time": True,
         },
         {
             'name': _('Date Modified'),
             'expr': "modified_on",
             'parse_date': True,
             "is_phone_time": True,
         }
     ]
Esempio n. 4
0
 def related_cases_columns(self):
     return [
         DisplayConfig(name=_('Status'), expr='status'),
         DisplayConfig(name=_('Case Type'), expr='type'),
         DisplayConfig(
             name=_('Owner'),
             expr=lambda c: cached_owner_id_to_display(c.get('owner_id'))),
         DisplayConfig(name=_('Date Opened'),
                       expr='opened_on',
                       process="date",
                       is_phone_time=True),
         DisplayConfig(name=_('Date Modified'),
                       expr='modified_on',
                       process="date",
                       is_phone_time=True),
     ]
Esempio n. 5
0
def owner_id_to_display(owner_id, doc):
    return cached_owner_id_to_display(owner_id)
Esempio n. 6
0
    def handle(self, **options):
        domain = options['domain']
        debug = options['debug']
        cleanup = options['cleanup']
        domain_query = CaseES().domain(domain)
        valid_case_ids = set(domain_query.get_ids())
        referenced_case_ids = {
            index['referenced_id']
            for hit in domain_query.source('indices.referenced_id').run().hits
            for index in hit['indices']
        }

        invalid_referenced_ids = referenced_case_ids - valid_case_ids

        if len(invalid_referenced_ids) > ES_MAX_CLAUSE_COUNT:
            print("there's a lot of invalid ids here. ES queries may not handle this well")

        cases_with_invalid_references = (
            domain_query
            .term('indices.referenced_id', invalid_referenced_ids)
            .source(['_id', 'type', 'indices', 'owner_id', 'opened_by', 'xform_ids'])
            .run().hits
        )

        with open(options['filename'], 'w', encoding='utf-8') as csvfile:
            writer = csv.writer(csvfile)
            headers = [
                'case id',
                'case type',
                'creating form id',
                'referenced id',
                'referenced_type',
                'index relationship',
                'index identifier',
                'owner id',
                'owner name',
                'opened by id',
                'opened by name',
            ]
            if debug:
                headers.append('app version')
            writer.writerow(headers)

            for case in cases_with_invalid_references:
                for index in case['indices']:
                    if index['referenced_id'] in invalid_referenced_ids:
                        form_id = case['xform_ids'][0]
                        row = [
                            case['_id'],
                            case['type'],
                            form_id,
                            index['referenced_id'],
                            index['referenced_type'],
                            index['relationship'],
                            index['identifier'],
                            case['owner_id'],
                            cached_owner_id_to_display(case['owner_id']),
                            case['opened_by'],
                            cached_owner_id_to_display(case['opened_by']),
                        ]
                        if debug:
                            form = FormAccessors(domain=domain).get_form(form_id)
                            app_version_info = get_app_version_info(
                                domain,
                                form.build_id,
                                form.form_data['@version'],
                                form.metadata,
                            )
                            row.append(app_version_info.build_version)
                        writer.writerow(row)

        if cleanup:
            missing = set()
            deleted = set()
            exists = set()
            for invalid_id in invalid_referenced_ids:
                try:
                    case = CaseAccessors(domain).get_case(invalid_id)
                except CaseNotFound:
                    missing.add(invalid_id)
                else:
                    if case.is_deleted:
                        deleted.add(case)
                    else:
                        exists.add(case)

            for case_to_resync in exists:
                # if the case actually exists resync it to fix the es search
                resave_case(domain, case_to_resync, send_post_save_signal=False)

            if exists:
                print('resynced {} cases that were actually not deleted'.format(len(exists)))

            for case in deleted:
                # delete the deleted case's entire network in one go
                call_command('delete_related_cases', domain, case.case_id)

            for case in cases_with_invalid_references:
                for index in case['indices']:
                    if index['referenced_id'] in missing:
                        # this is just an invalid reference. no recourse but to delete the case itself
                        call_command('delete_related_cases', domain, case['_id'])
Esempio n. 7
0
def owner_id_to_display(owner_id, doc):
    return cached_owner_id_to_display(owner_id)