def get_baz_caseblock(owner_id): return CaseBlock( create=True, case_id=BAZ_CASE_ID, case_type='person', case_name='BAZ, Bazza', external_id='P-GBR-012345678', owner_id=owner_id, update={ 'first_name': 'Bazza', 'last_name': 'Baz', 'passport_type': 'P', 'passport_country_code': 'GBR', 'passport_number': '012345678', 'sex': 'male', 'dob': '1990-01-01', 'covid19_last_test_date': '2021-01-01', 'covid19_last_test_status': 'negative', } )
def test_date_opened_coercion(self): delete_all_users() self.project = Domain(name='some-domain') self.project.save() user = create_restore_user(self.project.name) case_id = uuid.uuid4().hex modified_on = datetime.utcnow() case = CaseBlock( create=True, case_id=case_id, user_id=user.user_id, owner_id=user.user_id, case_type='demo', case_name='create_case', date_modified=modified_on, date_opened=modified_on, update={ 'dynamic': '123' } ) post_case_blocks([case.as_xml()], domain='some-domain') # update the date_opened to date type to check for value on restore case.date_opened = case.date_opened.date() deprecated_check_user_has_case(self, user, case.as_xml())
def _update_case_id_properties(domain, user): """Some case properties store the ID of related cases. This updates those IDs""" case_ids = CommCareCase.objects.get_case_ids_in_domain(domain) cases = CommCareCase.objects.get_cases(case_ids, domain) case_ids_by_external_id = {c.external_id: c.case_id for c in cases} case_blocks = [] for case in cases: update = {} for k, v in case.dynamic_case_properties().items(): if v in case_ids_by_external_id: update[k] = case_ids_by_external_id[v] if update: case_blocks.append( CaseBlock( case_id=case.case_id, user_id=user._id, update=update, ).as_xml() )
def setUp(self): super(CommTrackSyncTest, self).setUp() self.group = Group(domain=util.TEST_DOMAIN, name='commtrack-folks', users=[self.user._id], case_sharing=True) self.group._id = self.sp.owner_id self.group.save() self.restore_user = self.user.to_ota_restore_user() self.sp_block = CaseBlock(case_id=self.sp.case_id, ).as_xml() # get initial restore token restore_config = RestoreConfig( project=self.domain, restore_user=self.restore_user, params=RestoreParams(version=V2), ) self.sync_log_id = deprecated_synclog_id_from_restore_payload( restore_config.get_payload().as_string())
def get_addpatient_caseblock( case_type: str, default_owner: Optional[CommCareUser], patient: dict, repeater: OpenmrsRepeater, ) -> CaseBlock: case_block_kwargs = get_case_block_kwargs_from_patient(patient, repeater) if default_owner: case_block_kwargs.setdefault("owner_id", default_owner.user_id) if not case_block_kwargs.get("owner_id"): raise ConfigurationError( _(f'No users found at location "{repeater.location_id}" to own ' 'patients added from OpenMRS Atom feed.')) case_id = uuid.uuid4().hex return CaseBlock(create=True, case_id=case_id, case_type=case_type, external_id=patient['uuid'], **case_block_kwargs)
def to_xml(self): extras = {} if self.owner_id: extras['owner_id'] = self.owner_id if self.create: extras['case_name'] = self.product_stock_case.name extras['index'] = { const.PARENT_CASE_REF: (const.SUPPLY_POINT_PRODUCT_CASE_TYPE, self.product_stock_case._id), } caseblock = CaseBlock(case_id=self.id, create=self.create, version=V2, user_id=self.user_id, case_type=const.REQUISITION_CASE_TYPE, update=copy(self.custom_fields), close=self.close, **extras) return ElementTree.tostring( caseblock.as_xml(format_datetime=json_format_datetime))
def setUp(self): self.domain = create_domain(DOMAIN) self.user = CommCareUser.create(DOMAIN, USERNAME, PASSWORD, None, None) initialize_index_and_mapping(get_es_new(), CASE_SEARCH_INDEX_INFO) CaseSearchConfig.objects.get_or_create(pk=DOMAIN, enabled=True) delete_all_cases() self.case_id = uuid4().hex _, [self.case] = post_case_blocks([CaseBlock( create=True, case_id=self.case_id, case_type=CASE_TYPE, case_name=CASE_NAME, external_id=CASE_NAME, user_id=OWNER_ID, owner_id=OWNER_ID, update={'opened_by': OWNER_ID}, ).as_xml()], {'domain': DOMAIN}) CaseSearchReindexerFactory(domain=DOMAIN).build().reindex() es = get_es_new() es.indices.refresh(CASE_SEARCH_INDEX)
def test_rebuild_cases_with_new_owner(self, rebuild_case): """ If cases have a different owner to the person who submitted it rebuild it when the submitter is retired. """ case_id = uuid.uuid4().hex caseblock = CaseBlock( create=True, case_id=case_id, owner_id=self.commcare_user._id, user_id=self.commcare_user._id, ) casexml = ElementTree.tostring(caseblock.as_xml()) submit_case_blocks(casexml, self.domain, user_id=self.other_user._id) self.other_user.retire() detail = UserArchivedRebuild(user_id=self.other_user.user_id) rebuild_case.assert_called_once_with(self.domain, case_id, detail)
def get_foo_caseblock(owner_id): return CaseBlock( create=True, case_id=FOO_CASE_ID, case_type='person', case_name='FOO, Fred', external_id='PM-ZAF-F01234567', owner_id=owner_id, update={ 'first_name': 'Fred', 'last_name': 'Foo', 'passport_type': 'PM', 'passport_country_code': 'ZAF', 'passport_number': 'F01234567', 'sex': 'male', 'dob': '1990-01-01', 'covid19_last_test_date': '2021-01-01', 'covid19_last_test_status': 'negative', } )
def get_bar_caseblock(owner_id): return CaseBlock( create=True, case_id=BAR_CASE_ID, case_type='person', case_name='BAR, Barbara', external_id='PM-ZAF-B01234567', owner_id=owner_id, update={ 'first_name': 'Barbara', 'last_name': 'Bar', 'passport_type': 'PM', 'passport_country_code': 'ZAF', 'passport_number': 'B01234567', 'sex': 'female', 'dob': '1990-01-01', 'covid19_last_test_date': '2021-01-01', 'covid19_last_test_status': 'negative', } )
def _post_util(create=False, case_id=None, user_id=None, owner_id=None, case_type=None, form_extras=None, close=False, date_modified=None, **kwargs): form_extras = form_extras or {} form_extras['domain'] = REBUILD_TEST_DOMAIN uid = lambda: uuid.uuid4().hex case_id = case_id or uid() block = CaseBlock(create=create, case_id=case_id, user_id=user_id or uid(), owner_id=owner_id or uid(), case_type=case_type or 'test', date_modified=date_modified, update=kwargs, close=close) block = block.as_xml() post_case_blocks([block], form_extras) return case_id
def create_from_location(cls, domain, location): # a supply point is currently just a case with a special type id = uuid.uuid4().hex user_id = const.get_commtrack_user_id(domain) owner_id = location.group_id kwargs = {'external_id': location.external_id} if location.external_id else {} caseblock = CaseBlock( case_id=id, create=True, version=V2, case_name=location.name, user_id=user_id, owner_id=owner_id, case_type=const.SUPPLY_POINT_CASE_TYPE, update={ 'location_id': location._id, }, **kwargs ) return cls._from_caseblock(domain, caseblock)
def make_supply_point(domain, location): # a supply point is currently just a case with a special type case_id = uuid.uuid4().hex user_id = const.get_commtrack_user_id(domain) owner_id = location.location_id kwargs = { 'external_id': location.external_id } if location.external_id else {} caseblock = CaseBlock(case_id=case_id, create=True, case_name=location.name, user_id=user_id, owner_id=owner_id, case_type=const.SUPPLY_POINT_CASE_TYPE, update={ 'location_id': location.location_id, }, **kwargs) _submit_commtrack_caseblock(domain, caseblock, "make_supply_point") return SupplyInterface(domain).get_supply_point(case_id)
def create_case(cls, case_type, parent_case_id=None, parent_case_type=None, parent_identifier=None, parent_relationship=None): kwargs = {} if parent_case_id: kwargs['index'] = { parent_identifier: (parent_case_type, parent_case_id, parent_relationship) } caseblock = CaseBlock(uuid.uuid4().hex, case_type=case_type, create=True, **kwargs) return submit_case_blocks(ElementTree.tostring(caseblock.as_xml()), cls.domain)[1][0]
def get_case_block_for_indexed_case( mapping: ObservationMapping, external_data: dict, parent_case_attrs: CaseAttrs, ) -> CaseBlock: parent_case_id, parent_case_type, default_owner_id = parent_case_attrs relationship = mapping.indexed_case_mapping.relationship case_block_kwargs = { "index": { mapping.indexed_case_mapping.identifier: IndexAttrs( parent_case_type, parent_case_id, relationship, ) }, "update": {} } for value_source_config in mapping.indexed_case_mapping.case_properties: value_source = as_value_source(value_source_config) value = value_source.get_import_value(external_data) if value_source.case_property in CASE_BLOCK_ARGS: case_block_kwargs[value_source.case_property] = value else: case_block_kwargs["update"][value_source.case_property] = value case_id = uuid.uuid4().hex case_type = mapping.indexed_case_mapping.case_type case_block_kwargs.setdefault("owner_id", default_owner_id) if not case_block_kwargs["owner_id"]: raise ConfigurationError(_( f'Unable to determine mobile worker to own new "{case_type}" ' f'{relationship} case or parent case "{parent_case_id}"' )) case_block = CaseBlock( create=True, case_id=case_id, case_type=case_type, **case_block_kwargs ) return case_block
def assign_cases(caselist, owner_id, acting_user=None, update=None): """ Assign all cases in a list to an owner. Won't update if the owner is already set on the case. Doesn't touch parent cases or subcases. Returns the list of ids of cases that were reassigned. """ if not caselist: return def _assert(bool, msg): if not bool: raise CaseAssignmentError(msg) from corehq.apps.users.cases import get_wrapped_owner # "security" unique_domains = set([c.domain for c in caselist]) _assert(len(unique_domains) == 1, 'case list had cases spanning multiple domains') [domain] = unique_domains _assert(domain, 'domain for cases was empty') owner = get_wrapped_owner(owner_id) _assert(owner, 'no owner with id "%s" found' % owner_id) _assert(owner.domain == domain, 'owner was not in domain %s for cases' % domain) username = acting_user.username if acting_user else 'system' user_id = acting_user._id if acting_user else 'system' filtered_cases = set([c for c in caselist if c.owner_id != owner_id]) if filtered_cases: caseblocks = [ElementTree.tostring(CaseBlock( create=False, case_id=c._id, owner_id=owner_id, version=V2, update=update, ).as_xml(format_datetime=json_format_datetime)) for c in filtered_cases ] # todo: this should check whether the submit_case_blocks call actually succeeds submit_case_blocks(caseblocks, domain, username=username, user_id=user_id) return [c._id for c in filtered_cases]
def test_couch_blob_migration_edit(self): form_id = uuid.uuid4().hex case_id = uuid.uuid4().hex case_block = CaseBlock(create=True, case_id=case_id).as_string() xform = submit_case_blocks(case_block, domain=self.domain, form_id=form_id) # explicitly convert to old-style couch attachments to test the migration workflow form_xml = xform.get_xml() xform.delete_attachment('form.xml') xform.get_db().put_attachment(xform.to_json(), form_xml, 'form.xml') # make sure that worked updated_form_xml = XFormInstance.get(xform._id).get_xml() self.assertEqual(form_xml, updated_form_xml) # this call was previously failing updated_form = submit_case_blocks(case_block, domain=self.domain, form_id=form_id) self.assertEqual( form_xml, XFormInstance.get(updated_form.deprecated_form_id).get_xml())
def test_multiple_case_blocks_all_rebuilt(self, rebuild_case): """ Rebuild all cases in forms with multiple case blocks """ case_ids = [uuid.uuid4().hex, uuid.uuid4().hex, uuid.uuid4().hex] caseblocks = [CaseBlock( create=True, case_id=case_id, owner_id=self.commcare_user._id, user_id=self.commcare_user._id, ) for case_id in case_ids] casexmls = [ElementTree.tostring(caseblock.as_xml()) for caseblock in caseblocks] submit_case_blocks(casexmls, self.domain, user_id=self.other_user._id) self.other_user.retire() detail = UserArchivedRebuild(user_id=self.other_user.user_id) expected_call_args = [mock.call(self.domain, case_id, detail) for case_id in case_ids] self.assertEqual(rebuild_case.call_count, len(case_ids)) self.assertItemsEqual(rebuild_case.call_args_list, expected_call_args)
def case_blocks(self, case): username_of_associated_mobile_workers = case.get_case_property( 'username') try: normalized_username = normalize_username( username_of_associated_mobile_workers, case.domain) except ValidationError: self.logger.error( "ValidationError: invalid username:{} associated with " "case:{}".format(case.get_case_property('username'), case.case_id)) return None user_id_of_mobile_worker = username_to_user_id(normalized_username) if user_id_of_mobile_worker: return [ CaseBlock( create=False, case_id=case.case_id, update={'hq_user_id': user_id_of_mobile_worker}, ) ]
def test_claim_index_deleted(self): """ get_first_claim should return None if claim case is closed """ claim_id = claim_case(DOMAIN, self.restore_user, self.host_case_id, host_type=self.host_case_type, host_name=self.host_case_name) # delete the case index case_block = CaseBlock(create=False, case_id=claim_id, index={ "host": (self.host_case_type, "") }).as_xml() post_case_blocks([case_block], {'domain': DOMAIN}) first_claim = get_first_claims(DOMAIN, self.user.user_id, [self.host_case_id]) self.assertEqual(len(first_claim), 0)
def testOtherUserCloses(self): # create a case from one user case_id = "other_user_closes" self._createCaseStubs([case_id], owner_id=SHARED_ID) # sync then close case from another user self.other_sync_log = synclog_from_restore_payload( generate_restore_payload(self.other_user)) close_block = CaseBlock(create=False, case_id=case_id, user_id=USER_ID, version=V2, close=True).as_xml() self._postFakeWithSyncToken(close_block, self.other_sync_log.get_id) # original user syncs again # make sure close block appears assert_user_has_case(self, self.user, case_id, restore_id=self.sync_log.get_id)
def test_edit_an_error(self): form_id = uuid.uuid4().hex case_block = CaseBlock( create=True, case_id='', # this should cause the submission to error case_type='person', owner_id='some-owner', ) form, _ = submit_case_blocks(case_block.as_text(), domain=self.domain, form_id=form_id) self.assertTrue(form.is_error) self.assertTrue('IllegalCaseId' in form.problem) case_block.case_id = uuid.uuid4().hex form, _ = submit_case_blocks(case_block.as_text(), domain=self.domain, form_id=form_id) self.assertFalse(form.is_error) self.assertEqual(None, getattr(form, 'problem', None))
def _submit_followup_form(cls, case_id, received_on): form_id = uuid.uuid4().hex form_meta = TestFormMetadata( domain=cls.domain, xmlns=cls.followup_form.xmlns, app_id=cls.app._id, received_on=received_on, ) properties = cls._get_case_property_values() caseblock = CaseBlock( case_id=case_id, update=properties, ) form_builder = FormSubmissionBuilder( form_id=form_id, metadata=form_meta, case_blocks=[caseblock], form_properties=properties, ) submit_form_locally(form_builder.as_xml_string(), cls.domain, received_on=received_on, app_id=cls.app._id) return form_id
def test_ledger_update_with_case_update(self): from corehq.apps.commtrack.tests.util import get_single_balance_block submit_case_blocks([ CaseBlock(case_id=self.case.case_id, update={'a': "1"}).as_text(), get_single_balance_block(self.case.case_id, self.product_a._id, 100)], DOMAIN ) self._assert_ledger_state(100) case = CommCareCase.objects.get_case(self.case.case_id, DOMAIN) self.assertEqual("1", case.dynamic_case_properties()['a']) transactions = CaseTransaction.objects.get_transactions(self.case.case_id) self.assertEqual(2, len(transactions)) self.assertTrue(transactions[0].is_form_transaction) # ordering not guaranteed since they have the same date self.assertTrue(transactions[1].is_form_transaction) self.assertTrue(transactions[1].is_ledger_transaction) self._assert_transactions([ self._expected_val(100, 100), ])
class _UserCaseHelper(object): def __init__(self, domain, owner_id): self.domain = domain self.owner_id = owner_id def _submit_case_block(self, caseblock): casexml = ElementTree.tostring(caseblock.as_xml()) submit_case_blocks(casexml, self.domain.name) @staticmethod def re_open_case(case): transactions = case.get_closing_transactions() for transaction in transactions: transaction.form.archive() def create_user_case(self, case_type, commcare_user, fields): fields['hq_user_id'] = commcare_user._id caseblock = CaseBlock( create=True, case_id=uuid.uuid4().hex, owner_id=self.owner_id, user_id=self.owner_id, case_type=case_type, case_name=fields.pop('name', None), update=fields ) self._submit_case_block(caseblock) def update_user_case(self, case, case_type, fields): caseblock = CaseBlock( create=False, case_id=case.case_id, owner_id=self.owner_id, case_type=case_type, case_name=fields.pop('name', None), close=False, update=fields ) self._submit_case_block(caseblock)
def reassign_household_case(domain, household_case_id, old_owner_id, new_owner_id, supervisor_id, deprecation_time=None): if deprecation_time is None: deprecation_time = datetime.utcnow() case_ids = get_household_and_child_case_ids_by_owner(domain, household_case_id, old_owner_id) case_ids.add(household_case_id) case_blocks = [] for case_id in case_ids: updates = { 'location_reassignment_last_owner_id': old_owner_id, 'location_reassignment_datetime': deprecation_time } if supervisor_id: updates['location_reassignment_last_supervisor_id'] = supervisor_id case_block = CaseBlock(case_id, update=updates, owner_id=new_owner_id, user_id=SYSTEM_USER_ID) case_block = ElementTree.tostring(case_block.as_xml()).decode('utf-8') case_blocks.append(case_block) if case_blocks: submit_case_blocks(case_blocks, domain, user_id=SYSTEM_USER_ID)
def test_ledger_update_with_case_update(self): from corehq.apps.commtrack.tests.util import get_single_balance_block submit_case_blocks([ CaseBlock(case_id=self.case.case_id, update={'a': "1"}).as_string(), get_single_balance_block(self.case.case_id, self.product_a._id, 100)], DOMAIN ) self._assert_ledger_state(100) case = CaseAccessors(DOMAIN).get_case(self.case.case_id) self.assertEqual("1", case.dynamic_case_properties()['a']) if getattr(settings, 'TESTS_SHOULD_USE_SQL_BACKEND', False): transactions = CaseAccessorSQL.get_transactions(self.case.case_id) self.assertEqual(2, len(transactions)) self.assertTrue(transactions[0].is_form_transaction) # ordering not guaranteed since they have the same date self.assertTrue(transactions[1].is_form_transaction) self.assertTrue(transactions[1].is_ledger_transaction) self._assert_transactions([ self._expected_val(100, 100), ])
def create_scan_case(self, user_id, serial, scan_id, scan_time, scan_status=''): case_id = uuid.uuid4().hex case_block = CaseBlock(create=True, case_id=case_id, case_name='scan', case_type=UTH_CASE_TYPE, user_id=user_id, owner_id=user_id, update={ 'exam_number': scan_id, 'scanner_serial': serial, 'scan_status': scan_status, 'scan_time': scan_time }).as_xml() post_case_blocks([case_block], {'domain': UTH_DOMAIN}) return case_id
def set_schedule_case_properties(pact_case): """ Sets the required schedule case properties on the case if they are different from the current case properties. See the README for more information. """ SCHEDULE_CASE_PROPERTY_PREFIX = 'dotSchedule' DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'] current_schedule = pact_case.current_schedule if current_schedule is not None: to_change = {} for day in DAYS: case_property_name = '{}{}'.format(SCHEDULE_CASE_PROPERTY_PREFIX, day) from_case = getattr(pact_case, case_property_name, None) from_schedule = current_schedule[day] if (from_case or from_schedule) and from_case != from_schedule: to_change[case_property_name] = current_schedule[day] if to_change: case_block = CaseBlock( case_id=pact_case._id, update=to_change, ).as_xml() submit_case_blocks([ElementTree.tostring(case_block)], 'pact')
def set_up_form(cls): cls.form_id = uuid4().hex user_id = uuid4().hex cls.case_update = { 'year': '1970', 'breakfast': 'spam egg spam spam bacon spam', 'price': '2.40', 'album_release': '1972-09-08', 'breakfast_oclock': '09:00:00', 'breakfast_exactly': '1972-09-08T09:00:00.000Z', } builder = FormSubmissionBuilder( form_id=cls.form_id, form_properties={ 'name': 'spam', **cls.case_update, }, case_blocks=[ CaseBlock(case_id=uuid4().hex, create=True, case_type='sketch', case_name='spam', owner_id=user_id, update=cls.case_update) ], metadata=TestFormMetadata( domain=cls.domain, user_id=user_id, ), ) submit_form_locally(builder.as_xml_string(), cls.domain) cls.form = FormAccessors(cls.domain).get_form(cls.form_id) form_json_gen = FormRepeaterJsonPayloadGenerator(None) cls.form_json_payload_info = cls.get_payload_info(form_json_gen) form_dict_gen = FormDictPayloadGenerator(None) cls.form_dict_payload_info = cls.get_payload_info(form_dict_gen)