def _get_user_case(self, user_id=None): return CaseAccessors(TEST_DOMAIN).get_case_by_domain_hq_user_id( user_id or self.user._id, CASE_TYPE)
def setUp(self): self.accessor = CaseAccessors(self.domain.name) delete_all_cases() delete_all_xforms()
def case(self): try: return CaseAccessors(self.domain).get_case(self.case_id) except CaseNotFound: return None
def handle(self, days, *args, **options): email_to = options.get('email') # to iterate over repeat records we need time zone independent datetime # so find the difference between timezone needed and utc # For ex: IST is 5 hours 30 mins ahead of utc, so reduce that time in since # datetime to fetch repeat records from midnight IST on since datetime timezone = get_timezone_for_domain(DOMAIN) self.days = days self.till = datetime.datetime.now(tz=timezone) self.since = ( datetime.datetime(self.till.year, self.till.month, self.till.day) - datetime.timedelta(days=days) - datetime.timedelta(hours=5, minutes=30)) result_file_name = "nikshay_registration_notification_time_report_from_%s_till_%s.csv" % ( self.since.strftime('%Y-%m-%d-%H:%M:%S'), self.till.strftime('%Y-%m-%d-%H:%M:%S')) with open(result_file_name, 'w') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=[ "nikshay id", "form finished on", "form submitted on", "notification completed on", "form to submission", "submission to notification", "case id" ]) writer.writeheader() case_accessor = CaseAccessors(DOMAIN) for repeat_record in iter_repeat_records_by_domain( DOMAIN, repeater_id=REGISTRATION_REPEATER_ID, state=SUCCESS_STATE, since=self.since): episode_case_id = repeat_record.payload_id episode_case = case_accessor.get_case(episode_case_id) assert repeat_record.succeeded time_of_notification = pytz.utc.localize( repeat_record.last_checked).astimezone(timezone) # assert that # the last notification was the success one and # the time for last notification is same as that for the repeat record last_notification_attempt = repeat_record.attempts[-1] assert last_notification_attempt.succeeded assert repeat_record.last_checked == last_notification_attempt.datetime property_changed_info = get_latest_property_change_to_value( episode_case, "treatment_initiated", "yes_phi") xform = property_changed_info.transaction.form form_received_on = pytz.utc.localize( xform.received_on).astimezone(timezone) property_modified_on = parse_datetime( property_changed_info.modified_on).astimezone(timezone) writer.writerow({ 'nikshay id': episode_case.get_case_property('nikshay_id'), 'form finished on': property_modified_on.strftime('%Y-%m-%d-%H:%M:%S'), 'form submitted on': form_received_on.strftime('%Y-%m-%d-%H:%M:%S'), 'notification completed on': time_of_notification.strftime('%Y-%m-%d-%H:%M:%S'), 'form to submission': (form_received_on - property_modified_on), 'submission to notification': (time_of_notification - form_received_on), 'case id': episode_case.case_id }) if email_to: email_to = list(email_to) if not isinstance( email_to, six.string_types) else [email_to] csvfile = open(result_file_name) email = EmailMessage( subject="Nikshay Registration Notification Time Report", body= "Report for time taken for registration notifications for %s day(s)" % self.days, to=email_to, from_email=settings.DEFAULT_FROM_EMAIL) email.attach(filename=result_file_name, content=csvfile.read()) csvfile.close() email.send()
def setUp(self): super(ExplodeExtensionsDBTest, self).setUp() self.accessor = CaseAccessors(self.project.name) self._create_case_structure()
def _check_ids(self, form, cases): for case in cases: ids = CaseAccessors().get_case_xform_ids(case.case_id) self.assertEqual(1, len(ids)) self.assertEqual(form._id, ids[0])
def filter_cases(request, domain, app_id, module_id, parent_id=None): app = Application.get(app_id) module = app.get_module(module_id) auth_cookie = request.COOKIES.get('sessionid') requires_parent_cases = string_to_boolean( request.GET.get('requires_parent_cases', 'false')) xpath = EntriesHelper.get_filter_xpath(module) instances = get_instances_for_module(app, module, additional_xpaths=[xpath]) extra_instances = [{'id': inst.id, 'src': inst.src} for inst in instances] accessor = CaseAccessors(domain) # touchforms doesn't like this to be escaped xpath = HTMLParser.HTMLParser().unescape(xpath) case_type = module.case_type if xpath or should_use_sql_backend(domain): # if we need to do a custom filter, send it to touchforms for processing additional_filters = { "properties/case_type": case_type, "footprint": True } helper = BaseSessionDataHelper(domain, request.couch_user) result = helper.filter_cases(xpath, additional_filters, DjangoAuth(auth_cookie), extra_instances=extra_instances) if result.get('status', None) == 'error': code = result.get('code', 500) message = result.get( 'message', _("Something went wrong filtering your cases.")) if code == 500: notify_exception(None, message=message) return json_response(message, status_code=code) case_ids = result.get("cases", []) else: # otherwise just use our built in api with the defaults case_ids = [ res.id for res in get_filtered_cases( domain, status=CASE_STATUS_OPEN, case_type=case_type, user_id=request.couch_user._id, footprint=True, ids_only=True, ) ] cases = accessor.get_cases(case_ids) if parent_id: cases = filter(lambda c: c.parent and c.parent.case_id == parent_id, cases) # refilter these because we might have accidentally included footprint cases # in the results from touchforms. this is a little hacky but the easiest # (quick) workaround. should be revisted when we optimize the case list. cases = filter(lambda c: c.type == case_type, cases) cases = [c.to_api_json(lite=True) for c in cases if c] response = {'cases': cases} if requires_parent_cases: # Subtract already fetched cases from parent list parent_ids = set(map(lambda c: c['indices']['parent']['case_id'], cases)) - \ set(map(lambda c: c['case_id'], cases)) parents = accessor.get_cases(list(parent_ids)) parents = [c.to_api_json(lite=True) for c in parents] response.update({'parents': parents}) return json_response(response)
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') 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)
def get(self, request, domain, case_id=None, attachment_id=None): """ https://github.com/dimagi/commcare/wiki/CaseAttachmentAPI max_size The largest size (in bytes) for the attachment max_image_width The largest width in pixels for an an image attachment max_image_height The largest width in pixels for an an image attachment """ if self.request.couch_user.is_web_user() and not can_view_attachments( self.request): return HttpResponseForbidden() if not case_id or not attachment_id: raise Http404 img = self.request.GET.get('img', None) size = self.request.GET.get('size', OBJECT_ORIGINAL) max_width = int(self.request.GET.get('max_image_width', 0)) max_height = int(self.request.GET.get('max_image_height', 0)) max_filesize = int(self.request.GET.get('max_size', 0)) try: CaseAccessors(domain).get_case(case_id) except CaseNotFound: raise Http404 if img is not None: if size == "debug_all": url_base = reverse("api_case_attachment", kwargs={ "domain": self.request.domain, "case_id": case_id, "attachment_id": attachment_id, }) r = HttpResponse(content_type="text/html") r.write('<html><body>') r.write('<ul>') for fsize in IMAGE_SIZE_ORDERING: meta, stream = fetch_case_image( domain, case_id, attachment_id, filesize_limit=max_filesize, width_limit=max_width, height_limit=max_height, fixed_size=fsize) r.write('<li>') r.write('Size: %s<br>' % fsize) r.write("Limit: max_size: %s" % max_filesize) if max_width > 0: r.write(", max_width: %s" % max_width) if max_height > 0: r.write(", max_height: %s" % max_height) r.write("<br>") if meta is not None: r.write('Resolution: %d x %d<br>' % (meta['width'], meta['height'])) r.write('Filesize: %d<br>' % meta['content_length']) url_params = six.moves.urllib.parse.urlencode({ "img": '1', "size": fsize, "max_size": max_filesize, "max_image_width": max_width, "max_image_height": max_height }) r.write('<img src="%(attach_url)s?%(params)s">' % { "attach_url": url_base, "params": url_params }) else: r.write('Not available') r.write('</li>') r.write('</ul></body></html>') return r else: attachment_meta, attachment_stream = fetch_case_image( domain, case_id, attachment_id, filesize_limit=max_filesize, width_limit=max_width, height_limit=max_height, fixed_size=size) else: cached_attachment = get_cached_case_attachment( domain, case_id, attachment_id) attachment_meta, attachment_stream = cached_attachment.get() if attachment_meta is not None: mime_type = attachment_meta['content_type'] else: mime_type = "plain/text" return StreamingHttpResponse( streaming_content=FileWrapper(attachment_stream), content_type=mime_type)
def _get_case(self, case_id): return CaseAccessors(domain=self.domain_name).get_case(case_id)
def __init__(self, domain, person_id): self.domain = domain self.person_id = person_id self.case_accessor = CaseAccessors(domain) self.case_factory = CaseFactory(domain)
def find_case_ids_by_type(self, domain, case_type): accessor = CaseAccessors(domain) case_ids = accessor.get_case_ids_in_domain(case_type) print(f"Found {len(case_ids)} {case_type} cases in {domain}") return case_ids
def _reverse_indices(self): return CaseAccessors(self.domain).get_all_reverse_indices_info([self._id])
def handle(self, commit, domain, log_path, **options): commit = commit factory = CaseFactory(domain) headers = [ 'case_id', 'case_type', 'test_date_tested', 'test_result', 'test_interim_outcome', 'episode_interim_outcome', 'episode_interim_outcome_history', 'datamigration_interim_outcome', ] print("Starting {} migration on {} at {}".format( "real" if commit else "fake", domain, datetime.datetime.utcnow() )) case_ids = [ hit['_id'] for hit in ( CaseSearchES() .domain(domain) .case_type("episode") .case_property_query("episode_type", "confirmed_drtb", "must") .run().hits ) ] with open(log_path, "w") as log_file: writer = csv.writer(log_file) writer.writerow(headers) accessor = CaseAccessors(domain=domain) for episode in accessor.iter_cases(case_ids): if self.is_valid_case(domain, episode): # Get all follow up tests with a result occurrence = get_occurrence_case_from_episode(domain, episode.case_id) tests = [case for case in accessor.get_reverse_indexed_cases([occurrence.get_id]) if case.type == CASE_TYPE_TEST and case.get_case_property('rft_general') == 'follow_up_drtb' and case.get_case_property('result_recorded') == 'yes'] tests = sorted(tests, key=lambda test: test.get_case_property('date_tested')) interim_outcome = '' interim_outcome_history = '' for i in range(1, len(tests)): test_interim_outcome = None test_interim_outcome_text = None current_test = tests[i] current_test_date = datetime.datetime.strptime( current_test.get_case_property('date_tested'), "%Y-%m-%d").date() prev_test = tests[i - 1] prev_test_date = datetime.datetime.strptime( prev_test.get_case_property('date_tested'), "%Y-%m-%d").date() if (current_test_date - prev_test_date).days >= 30: if ( prev_test.get_case_property('result') == TEST_RESULT_TB_NOT_DETECTED and current_test.get_case_property('result') == TEST_RESULT_TB_NOT_DETECTED and interim_outcome != 'culture_conversion' ): test_interim_outcome = 'culture_conversion' test_interim_outcome_text = "Culture Conversion" elif ( prev_test.get_case_property('result') == TEST_RESULT_TB_DETECTED and current_test.get_case_property('result') == TEST_RESULT_TB_DETECTED and interim_outcome == 'culture_conversion' ): test_interim_outcome = 'culture_reversion' test_interim_outcome_text = "Culture Reversion" if test_interim_outcome: interim_outcome = test_interim_outcome interim_outcome_history = prev_test_date.strftime("%d/%m/%y") + ": " + \ test_interim_outcome_text + '\n' + interim_outcome_history writer.writerow([current_test.case_id, "test", current_test.get_case_property('date_tested'), current_test.get_case_property('result'), test_interim_outcome, None, None, "yes"]) print('Updating {}...'.format(current_test.case_id)) case_structure = CaseStructure( case_id=current_test.case_id, walk_related=False, attrs={ "create": False, "update": { "interim_outcome": test_interim_outcome, "datamigration_interim_outcome": "yes", }, }, ) if commit: factory.create_or_update_case(case_structure) else: writer.writerow([current_test.case_id, "test", current_test.get_case_property('date_tested'), current_test.get_case_property('result'), None, None, None, "no"]) # update episode if needed if interim_outcome: writer.writerow([episode.case_id, "episode", None, None, None, interim_outcome, interim_outcome_history, "yes"]) print('Updating {}...'.format(episode.case_id)) case_structure = CaseStructure( case_id=episode.case_id, walk_related=False, attrs={ "create": False, "update": { "interim_outcome": interim_outcome, "interim_outcome_history": interim_outcome_history, "datamigration_interim_outcome": "yes", }, }, ) if commit: factory.create_or_update_case(case_structure) else: writer.writerow([episode.case_id, "episode", None, None, None, None, None, "no"]) print("Migration finished at {}".format(datetime.datetime.utcnow()))
def _get_drug_resistance_cases(domain, occurrence_case_id): case_accessor = CaseAccessors(domain) all_cases = case_accessor.get_reverse_indexed_cases([occurrence_case_id]) cases = [ case for case in all_cases if case.type == CASE_TYPE_DRUG_RESISTANCE ]
def setUp(self): super(FundamentalCaseTests, self).setUp() self.interface = FormProcessorInterface() self.casedb = CaseAccessors()
def _get_case_ids(self): return CaseAccessors(domain=self.domain_name).get_case_ids_in_domain()
if importer_util.is_valid_id(uploaded_owner_id, domain, id_cache): owner_id = uploaded_owner_id id_cache[uploaded_owner_id] = True else: errors.add(ImportErrors.InvalidOwnerId, i + 1, 'owner_id') id_cache[uploaded_owner_id] = False continue else: # if they didn't supply an owner_id mapping, default to current # user owner_id = user_id extras = {} if parent_id: try: parent_case = CaseAccessors(domain).get_case(parent_id) if parent_case.domain == domain: extras['index'] = { parent_ref: (parent_case.type, parent_id) } except ResourceNotFound: errors.add(ImportErrors.InvalidParentId, i + 1, 'parent_id') continue elif parent_external_id: parent_case, error = importer_util.lookup_case( 'external_id', parent_external_id, domain, parent_type) if parent_case: extras['index'] = { parent_ref: (parent_type, parent_case.case_id) }
def get(self, request, domain, urlPath): try: preview = string_to_boolean(request.GET.get("preview", "false")) except ValueError: # this is typically only set at all if it's intended to be true so this # is a reasonable default for "something went wrong" preview = True app_access = ApplicationAccess.get_by_domain(domain) accessor = CaseAccessors(domain) if not preview: apps = get_cloudcare_apps(domain) if request.project.use_cloudcare_releases: if (toggles.CLOUDCARE_LATEST_BUILD.enabled(domain) or toggles.CLOUDCARE_LATEST_BUILD.enabled( request.couch_user.username)): get_cloudcare_app = get_latest_build_doc else: get_cloudcare_app = get_latest_released_app_doc apps = map( lambda app: get_cloudcare_app(domain, app['_id']), apps, ) apps = filter(None, apps) apps = map(wrap_app, apps) # convert to json apps = [get_app_json(app) for app in apps] else: # legacy functionality - use the latest build regardless of stars apps = [ get_latest_build_doc(domain, app['_id']) for app in apps ] apps = [ get_app_json(ApplicationBase.wrap(app)) for app in apps if app ] else: # big TODO: write a new apps view for Formplayer, can likely cut most out now if not toggles.USE_OLD_CLOUDCARE.enabled(domain): apps = get_cloudcare_apps(domain) else: apps = get_brief_apps_in_domain(domain) apps = [ get_app_json(app) for app in apps if app and (isinstance(app, RemoteApp) or app.application_version == V2) ] meta = get_meta(request) track_clicked_preview_on_hubspot(request.couch_user, request.COOKIES, meta) # trim out empty apps apps = filter(lambda app: app, apps) apps = filter( lambda app: app_access.user_can_access_app(request.couch_user, app ), apps) def _default_lang(): if apps: # unfortunately we have to go back to the DB to find this return Application.get(apps[0]["_id"]).default_language else: return "en" # default language to user's preference, followed by # first app's default, followed by english language = request.couch_user.language or _default_lang() def _url_context(): # given a url path, returns potentially the app, parent, and case, if # they're selected. the front end optimizes with these to avoid excess # server calls # there's an annoying dependency between this logic and backbone's # url routing that seems hard to solve well. this needs to be synced # with apps.js if anything changes # for apps anything with "view/app/" works # for cases it will be: # "view/:app/:module/:form/case/:case/" # if there are parent cases, it will be: # "view/:app/:module/:form/parent/:parent/case/:case/ # could use regex here but this is actually simpler with the potential # absence of a trailing slash split = urlPath.split('/') app_id = split[1] if len(split) >= 2 else None if len(split) >= 5 and split[4] == "parent": parent_id = split[5] case_id = split[7] if len(split) >= 7 else None else: parent_id = None case_id = split[5] if len(split) >= 6 else None app = None if app_id: if app_id in [a['_id'] for a in apps]: app = look_up_app_json(domain, app_id) else: messages.info( request, _("That app is no longer valid. Try using the " "navigation links to select an app.")) if app is None and len(apps) == 1: app = look_up_app_json(domain, apps[0]['_id']) def _get_case(domain, case_id): case = accessor.get_case(case_id) assert case.domain == domain, "case %s not in %s" % (case_id, domain) return case.to_api_json() case = _get_case(domain, case_id) if case_id else None if parent_id is None and case is not None: parent_id = case.get('indices', {}).get('parent', {}).get('case_id', None)
def handle(self, domain, log_path, **options): commit = options['commit'] factory = CaseFactory(domain) logger.info("Starting {} migration on {} at {}".format( "real" if commit else "fake", domain, datetime.datetime.utcnow() )) cases = (CaseSearchES() .domain(domain) .case_type("test") .case_property_query("test_type_value", "cbnaat", "must") .values_list('case_id', flat=True)) with open(log_path, "w") as f: for test in CaseAccessors(domain=domain).iter_cases(cases): updated_by_migration = test.get_case_property('updated_by_migration') if ((updated_by_migration == 'enikshay_2b_case_properties' or updated_by_migration == 'enikshay_2b_reason_for_test_fix') and test.get_case_property('result_recorded') == 'yes'): drug_resistance_list = '' drug_sensitive_list = '' resistance_display = None form_data = self._get_result_recorded_form(test) sample_a = self._get_path( 'update_test_result cbnaat ql_sample_a sample_a_rif_resistance_result'.split(), form_data, ) sample_b = self._get_path( 'update_test_result cbnaat ql_sample_b sample_b_rif_resistance_result'.split(), form_data, ) if sample_a == 'detected' or sample_b == 'detected': detected = 'TB Detected' drug_resistance_list = 'r' resistance_display = 'R: Res' elif sample_a == 'not_detected' or sample_b == 'not_detected': detected = 'TB Not Detected' drug_sensitive_list = 'r' else: detected = '' result_summary_display = '\n'.join(filter(None, [ detected, resistance_display, ])) case_id = test.case_id f.write(case_id + "\n") logger.info(case_id) case_structure = CaseStructure( case_id=case_id, walk_related=False, attrs={ "create": False, "update": { "updated_by_migration": "enikshay_2b_cbnaat_fix", "drug_resistance_list": drug_resistance_list, "drug_sensitive_list": drug_sensitive_list, "result_summary_display": result_summary_display, }, }, ) if commit: factory.create_or_update_case(case_structure) logger.info("Migration finished at {}".format(datetime.datetime.utcnow()))
def is_case_contact_active(domain, case_id): from corehq.form_processor.interfaces.dbaccessors import CaseAccessors from corehq.form_processor.exceptions import CaseNotFound try: case = CaseAccessors(domain).get_case(case_id)
def payload_doc(self, repeat_record): return CaseAccessors(repeat_record.domain).get_case(repeat_record.payload_id)
def callcenter_test(request): user_id = request.GET.get("user_id") date_param = request.GET.get("date") enable_caching = request.GET.get('cache') doc_id = request.GET.get('doc_id') if not user_id and not doc_id: return render(request, "hqadmin/callcenter_test.html", {"enable_caching": enable_caching}) error = None user = None user_case = None domain = None if user_id: try: user = CommCareUser.get(user_id) domain = user.project except ResourceNotFound: error = "User Not Found" elif doc_id: try: doc = CommCareUser.get_db().get(doc_id) domain = Domain.get_by_name(doc['domain']) doc_type = doc.get('doc_type', None) if doc_type == 'CommCareUser': case_type = domain.call_center_config.case_type user_case = CaseAccessors(doc['domain']).get_case_by_domain_hq_user_id(doc['_id'], case_type) elif doc_type == 'CommCareCase': if doc.get('hq_user_id'): user_case = CommCareCase.wrap(doc) else: error = 'Case ID does does not refer to a Call Center Case' except ResourceNotFound: error = "User Not Found" try: query_date = dateutil.parser.parse(date_param) except ValueError: error = "Unable to parse date, using today" query_date = date.today() def view_data(case_id, indicators): new_dict = SortedDict() key_list = sorted(indicators.keys()) for key in key_list: new_dict[key] = indicators[key] return { 'indicators': new_dict, 'case': CommCareCase.get(case_id), } if user or user_case: custom_cache = None if enable_caching else cache.caches['dummy'] override_case = CallCenterCase.from_case(user_case) cci = CallCenterIndicators( domain.name, domain.default_timezone, domain.call_center_config.case_type, user, custom_cache=custom_cache, override_date=query_date, override_cases=[override_case] if override_case else None ) data = {case_id: view_data(case_id, values) for case_id, values in cci.get_data().items()} else: data = {} context = { "error": error, "mobile_user": user, "date": json_format_date(query_date), "enable_caching": enable_caching, "data": data, "doc_id": doc_id } return render(request, "hqadmin/callcenter_test.html", context)
def case(self): if not self._case: self._case = CaseAccessors(self.domain).get_case(self.case_id) return self._case
def setUp(self): super(ExplodeLedgersTest, self).setUp() self.case_accessor = CaseAccessors(self.project.name) self.ledger_accessor = LedgerAccessors(self.project.name) self._create_ledgers()
def tearDown(self): delete_all_xforms() delete_all_cases() @run_with_all_backends def test_case_history(self): self.factory.create_or_update_case( CaseStructure(self.case.case_id, attrs={ "update": { 'prop_1': "val1", 'prop_2': "val1", 'prop_3': "val1", }, }), ) self.factory.create_or_update_case( CaseStructure(self.case.case_id, attrs={ "update": { 'prop_1': "val2", 'prop_2': "val2", 'prop_4': "val", }, }), ) case = CaseAccessors(self.domain).get_case(self.case.case_id) history = get_case_history(case) self.assertEqual(history[0]['prop_1'], "val1") self.assertEqual(history[1]['prop_2'], "val1") self.assertEqual(history[2]['prop_2'], "val2")
def test(self): migrator = ENikshay2BMigrator(self.domain, commit=True) # first check some utils person_case_ids = migrator.get_relevant_person_case_ids() person_case_sets = list( migrator.get_relevant_person_case_sets(person_case_ids)) self.assertEqual(1, len(person_case_sets)) person = person_case_sets[0] self.assertEqual('roland-deschain', person.person.case_id) self.assertItemsEqual(['roland-deschain-occurrence'], [c.case_id for c in person.occurrences]) self.assertItemsEqual(['roland-deschain-occurrence-episode'], [c.case_id for c in person.episodes]) self.assertItemsEqual(['roland-deschain-occurrence-test'], [c.case_id for c in person.tests]) self.assertItemsEqual(['roland-deschain-referral'], [c.case_id for c in person.referrals]) self.assertItemsEqual(['roland-deschain-referral-trail'], [c.case_id for c in person.trails]) self.assertItemsEqual( ['roland-deschain-occurrence-episode-drtb_hiv_referral'], [c.case_id for c in person.drtb_hiv]) # run the actual migration migrator.migrate() # check the results accessor = CaseAccessors(self.domain) new_person = accessor.get_case(person.person.case_id) self.assertDictContainsSubset( { 'area': 'phi_area', 'referred_outside_enikshay_date': 'date_referred_out', 'referred_outside_enikshay_by_id': 'referred_by_id', 'contact_phone_number': '911234567890', 'current_episode_type': "confirmed_tb", 'alcohol_history': "alcohol_history", 'alcohol_deaddiction': "alcohol_deaddiction", 'tobacco_user': "******", 'occupation': "occupation", 'phone_number_other': "phone_number_other", 'phi_name': 'PHI', 'tu_name': 'TU', 'tu_id': self.locations['TU'].location_id, 'dto_name': 'DTO', 'dto_id': self.locations['DTO'].location_id, 'dataset': 'real', 'updated_by_migration': 'enikshay_2b_case_properties', }, new_person.dynamic_case_properties()) new_occurrence = accessor.get_case(person.occurrences[0].case_id) self.assertDictContainsSubset( { 'current_episode_type': 'confirmed_tb', 'disease_classification': 'disease_classification', 'site_choice': 'site_choice', 'site_detail': 'site_detail', 'key_population_status': 'key_population_status', 'key_populations': 'key_populations', }, new_occurrence.dynamic_case_properties()) new_episode = accessor.get_case(person.episodes[0].case_id) self.assertDictContainsSubset( { 'treatment_status': 'initiated_second_line_treatment', 'date_of_diagnosis': 'date_reported', 'dosage_display': 'full_dosage', 'dosage_summary': 'full_dosage', 'rft_general': 'diagnosis_dstb', 'diagnosis_test_type': 'chest_x-ray', 'diagnosis_test_type_label': "Chest X-ray", 'is_active': 'yes', }, new_episode.dynamic_case_properties()) new_test = accessor.get_case(person.tests[0].case_id) self.assertDictContainsSubset( { 'is_direct_test_entry': 'no', 'rft_drtb_diagnosis': 'diagnostic_drtb_test_reason', 'dataset': 'real', 'rft_general': 'diagnosis_dstb', 'rft_dstb_diagnosis': 'diagnostic_test_reason', 'rft_dstb_followup': 'definitely_not_private_ntm', 'episode_case_id': 'roland-deschain-occurrence-episode', 'result_summary_display': "TB Detected\nR: Res\nCount of bacilli: 11\nthat looks infected", 'drug_resistance_list': 'r', }, new_test.dynamic_case_properties()) new_referral = accessor.get_case(person.referrals[0].case_id) self.assertDictContainsSubset( { 'referral_initiated_date': 'referral_date', 'referred_to_name': 'referred_to_location_name', 'referred_by_name': '', 'referral_rejection_reason_other_detail': 'reason_for_refusal_other_detail', 'referral_rejection_reason': 'reason_for_refusal', 'referral_closed_date': 'acceptance_refusal_date', 'accepted_by_name': 'phi', }, new_referral.dynamic_case_properties()) parent = get_first_parent_of_case(self.domain, new_referral, 'occurrence') self.assertEqual(new_occurrence.case_id, parent.case_id) new_trail = accessor.get_case(person.trails[0].case_id) parent = get_first_parent_of_case(self.domain, new_trail, 'occurrence') self.assertEqual(new_occurrence.case_id, parent.case_id) new_drtb_hiv = accessor.get_case(person.drtb_hiv[0].case_id) self.assertTrue(new_drtb_hiv.closed) secondary_owner_id = accessor.get_case_ids_in_domain( type='secondary_owner')[0] new_secondary_owner = accessor.get_case(secondary_owner_id) self.assertEqual('person_id-drtb-hiv', new_secondary_owner.name) self.assertDictContainsSubset({ 'secondary_owner_type': 'drtb-hiv', }, new_secondary_owner.dynamic_case_properties()) self.assertEqual("drtb_hiv_referral_owner", new_secondary_owner.owner_id) parent = get_first_parent_of_case(self.domain, new_secondary_owner, 'occurrence') self.assertEqual(new_occurrence.case_id, parent.case_id)
case_location = get_case_location(case) if not case_location: return [] location_repeaters = defaultdict(list) for repeater in OpenmrsRepeater.by_domain(case.domain): if repeater.location_id: location_repeaters[repeater.location_id].append(repeater) for location_id in reversed(case_location.path): if location_id in location_repeaters: return location_repeaters[location_id] return [] def get_ancestor_location_openmrs_uuid(domain, case_id): case = CaseAccessors(domain).get_case(case_id) case_location = get_case_location(case) if not case_location: return None for location in reversed(case_location.get_ancestors(include_self=True)): if location.metadata.get(LOCATION_OPENMRS_UUID): return location.metadata[LOCATION_OPENMRS_UUID] return None class CreatePersonAttributeTask(WorkflowTask): def __init__(self, requests, person_uuid, attribute_type_uuid, value): self.requests = requests self.person_uuid = person_uuid self.attribute_type_uuid = attribute_type_uuid self.value = value
def recipient(self): if self.recipient_type == self.RECIPIENT_TYPE_CASE: try: case = CaseAccessors(self.domain).get_case(self.recipient_id) except CaseNotFound: return None
def get_case(self, external_id): [case ] = CaseAccessors(self.domain).get_cases_by_external_id(external_id) return case