def get_matching_owner(case): if by_user_id: if case.user_id in by_user_id: return case.user_id elif get_owner_id(case) in by_user_id: return get_owner_id(case) else: return get_owner_id(case)
def _to_fields(transaction): ret = {"requisition_status": RequisitionStatus.by_action_type(transaction.action_config.action_type)} if transaction.action_config.action_type == RequisitionActions.REQUEST: ret.update( { "create": True, "owner_id": get_owner_id(product_stock_case) or user_id, "amount_requested": transaction.value, "product_id": product_stock_case.product, "requested_by": user_id, "requested_on": datetime.utcnow(), } ) elif transaction.action_config.action_type == RequisitionActions.APPROVAL: ret.update( {"amount_approved": transaction.value, "approved_by": user_id, "approved_on": datetime.utcnow()} ) elif transaction.action_config.action_type == RequisitionActions.PACK: ret.update({"amount_packed": transaction.value, "packed_by": user_id, "packed_on": datetime.utcnow()}) elif transaction.action_config.action_type == RequisitionActions.RECEIPTS: ret.update( { "amount_received": transaction.value, "received_by": user_id, "received_on": datetime.utcnow(), "close": True, } ) else: raise ValueError("the type %s isn't yet supported." % transaction.action_config.action_type) return ret
def testRecursiveUpdates(self): parent_case = self._make_case(self.other_user._id, self.other_user._id) case = self._make_case(self.other_user._id, self.other_user._id, index={'parent': ('parent-case', parent_case._id)}) subcase1 = self._make_case(self.other_user._id, self.other_user._id, index={'parent': ('parent-case', case._id)}) subcase2 = self._make_case(self.other_user._id, self.other_user._id, index={'parent': ('parent-case', case._id)}) subsub1 = self._make_case(self.other_user._id, self.other_user._id, index={'parent': ('parent-case', subcase1._id)}) subsub2 = self._make_case(self.other_user._id, self.other_user._id, index={'parent': ('parent-case', subcase1._id)}) cases = [case, subcase1, subcase2, subsub1, subsub2] for c in cases: self.assertEqual(self.other_user._id, c.owner_id) reconcile_ownership(case, self.user, recursive=True) case = CommCareCase.get(case._id) owner = get_wrapped_owner(get_owner_id(case)) self.assertTrue(isinstance(owner, Group)) self.assertTrue(self.other_user._id in owner.users) self.assertTrue(self.user._id in owner.users) self.assertTrue(owner.case_sharing) self.assertFalse(owner.reporting) for c in cases: c = CommCareCase.get(c._id) self.assertEqual(owner._id, c.owner_id) parent_case = CommCareCase.get(parent_case._id) self.assertEqual(self.other_user._id, parent_case.owner_id)
def make_supply_point_product(supply_point_case, product_uuid, owner_id=None): domain = supply_point_case.domain id = uuid.uuid4().hex user_id = get_commtrack_user_id(domain) owner_id = owner_id or get_owner_id(supply_point_case) or user_id username = const.COMMTRACK_USERNAME product_name = Product.get(product_uuid).name caseblock = CaseBlock(case_id=id, create=True, version=V2, case_name=product_name, user_id=user_id, owner_id=owner_id, case_type=const.SUPPLY_POINT_PRODUCT_CASE_TYPE, update={"product": product_uuid}, index={ const.PARENT_CASE_REF: (const.SUPPLY_POINT_CASE_TYPE, supply_point_case._id), }) casexml = ElementTree.tostring(caseblock.as_xml()) submit_case_blocks(casexml, domain, username, user_id, xmlns=const.COMMTRACK_SUPPLY_POINT_PRODUCT_XMLNS) return SupplyPointProductCase.get(id)
def make_supply_point_product(supply_point_case, product_uuid, owner_id=None): domain = supply_point_case.domain id = uuid.uuid4().hex user_id = const.get_commtrack_user_id(domain) owner_id = owner_id or get_owner_id(supply_point_case) or user_id username = const.COMMTRACK_USERNAME product_name = Product.get(product_uuid).name caseblock = CaseBlock( case_id=id, create=True, version=V2, case_name=product_name, user_id=user_id, owner_id=owner_id, case_type=const.SUPPLY_POINT_PRODUCT_CASE_TYPE, update={ "product": product_uuid }, index={ const.PARENT_CASE_REF: (const.SUPPLY_POINT_CASE_TYPE, supply_point_case._id), } ) casexml = ElementTree.tostring(caseblock.as_xml()) submit_case_blocks(casexml, domain, username, user_id, xmlns=const.COMMTRACK_SUPPLY_POINT_PRODUCT_XMLNS) sppc = SupplyPointProductCase.get(id) sppc.bind_to_location(supply_point_case.location) sppc.save() return sppc
def get_notification_recipients(next_action, requisition): # given a status and list of requisitions, get the exhaustive list of # people to notify about the requisition entering that status. users = get_owning_users(get_owner_id(requisition)) if len(users) == 1: return users return [u for u in users if should_notify_user(u, next_action.action_type)]
def _to_fields(transaction): ret = {'requisition_status': RequisitionStatus.by_action_type(transaction.action_config.action_type)} if transaction.action_config.action_type == RequisitionActions.REQUEST: ret.update({ 'create': True, 'owner_id': get_owner_id(product_stock_case) or user_id, 'amount_requested': transaction.value, 'product_id': product_stock_case.product, 'requested_by': user_id, 'requested_on': datetime.utcnow(), }) elif transaction.action_config.action_type == RequisitionActions.APPROVAL: ret.update({ 'amount_approved': transaction.value, 'approved_by': user_id, 'approved_on': datetime.utcnow(), }) elif transaction.action_config.action_type == RequisitionActions.PACK: ret.update({ 'amount_packed': transaction.value, 'packed_by': user_id, 'packed_on': datetime.utcnow(), }) elif transaction.action_config.action_type == RequisitionActions.RECEIPTS: ret.update({ 'amount_received': transaction.value, 'received_by': user_id, 'received_on': datetime.utcnow(), 'close': True, }) else: raise ValueError("the type %s isn't yet supported." % transaction.action_config.action_type) return ret
def recipient(self): handler = self.handler if handler.recipient == RECIPIENT_USER: return self.user elif handler.recipient == RECIPIENT_CASE: return CommConnectCase.get(self.case_id) elif handler.recipient == RECIPIENT_SURVEY_SAMPLE: return SurveySample.get(self.sample_id) elif handler.recipient == RECIPIENT_OWNER: return get_wrapped_owner(get_owner_id(self.case)) elif handler.recipient == RECIPIENT_PARENT_CASE: indices = self.case.indices for index in indices: # TODO: The data model allows for more than one parent. # For now, send to the first parent, but need to decide how to handle multiple ones. if index.identifier == "parent": return CommConnectCase.get(index.referenced_id) return None elif handler.recipient == RECIPIENT_SUBCASE: indices = self.case.reverse_indices recipients = [] for index in indices: if index.identifier == "parent": subcase = CommConnectCase.get(index.referenced_id) if case_matches_criteria(subcase, handler.recipient_case_match_type, handler.recipient_case_match_property, handler.recipient_case_match_value): recipients.append(subcase) return recipients else: return None
def process_survey_keyword_actions(verified_number, survey_keyword, text, msg=None): from corehq.apps.reminders.models import ( RECIPIENT_SENDER, RECIPIENT_OWNER, RECIPIENT_USER_GROUP, METHOD_SMS, METHOD_SMS_SURVEY, METHOD_STRUCTURED_SMS, REMINDER_TYPE_KEYWORD_INITIATED, ) sender = verified_number.owner if sender.doc_type == "CommCareCase": case = sender else: case = None for survey_keyword_action in survey_keyword.actions: if survey_keyword_action.recipient == RECIPIENT_SENDER: contact = sender elif survey_keyword_action.recipient == RECIPIENT_OWNER: if sender.doc_type == "CommCareCase": contact = get_wrapped_owner(get_owner_id(sender)) else: contact = None elif survey_keyword_action.recipient == RECIPIENT_USER_GROUP: try: contact = Group.get(survey_keyword_action.recipient_id) assert contact.doc_type == "Group" assert contact.domain == verified_number.domain except Exception: contact = None else: contact = None if contact is None: continue if survey_keyword_action.action == METHOD_SMS: create_immediate_reminder( contact, METHOD_SMS, reminder_type=REMINDER_TYPE_KEYWORD_INITIATED, message=survey_keyword_action.message_content, case=case, ) elif survey_keyword_action.action == METHOD_SMS_SURVEY: create_immediate_reminder( contact, METHOD_SMS_SURVEY, reminder_type=REMINDER_TYPE_KEYWORD_INITIATED, form_unique_id=survey_keyword_action.form_unique_id, case=case, ) elif survey_keyword_action.action == METHOD_STRUCTURED_SMS: handle_structured_sms( survey_keyword, survey_keyword_action, sender, verified_number, text, send_response=True, msg=msg )
def get_user_from_usercase(usercase): if usercase.type != USERCASE_TYPE: raise ValueError(f"Expected '{USERCASE_TYPE}' case, got {usercase.type}") user = get_wrapped_owner(get_owner_id(usercase)) if not isinstance(user, CommCareUser): return None return user
def get_root_element(self): from corehq.apps.users.cases import get_owner_id root = safe_element("case") root.attrib = { "case_id": self.case.case_id, "case_type": self.case.type, "owner_id": get_owner_id(self.case), "status": "closed" if self.case.closed else "open", } return root
def testUserToGroup(self): # 2. If the case has an owner that is a user create a new case sharing group, # add that user and the new user to the case sharing group make the group the owner. case = self._make_case(self.other_user._id, self.other_user._id) self.assertEqual(self.other_user._id, case.owner_id) reconcile_ownership(case, self.user) case = CommCareCase.get(case._id) self.assertNotEqual(self.other_user._id, case.owner_id) owner = get_wrapped_owner(get_owner_id(case)) self.assertTrue(isinstance(owner, Group)) self.assertTrue(self.other_user._id in owner.users) self.assertTrue(self.user._id in owner.users) self.assertTrue(owner.case_sharing) self.assertFalse(owner.reporting)
def __get_owner_result(self): """ memoized doesn't seem to work with overriding __getattr__ at the same time, so we cache the result using a private attribute. """ if self.__owner_result: return self.__owner_result owner = get_wrapped_owner(get_owner_id(self.__case)) if isinstance(owner, CouchUser): if owner.is_member_of(self.__domain): self.__owner_result = SimpleDictTemplateParam(_get_obj_template_info(owner)) elif isinstance(owner, (Group, SQLLocation)): if owner.domain == self.__domain: self.__owner_result = SimpleDictTemplateParam(_get_obj_template_info(owner)) self.__owner_result = self.__owner_result or SimpleMessagingTemplateParam(UNKNOWN_VALUE) return self.__owner_result
def _to_fields(transaction): ret = { 'requisition_status': RequisitionStatus.by_action_type( transaction.action_config.action_type) } if transaction.action_config.action_type == RequisitionActions.REQUEST: ret.update({ 'create': True, 'owner_id': get_owner_id(product_stock_case) or user_id, 'amount_requested': transaction.value, 'product_id': product_stock_case.product, 'requested_by': user_id, 'requested_on': datetime.utcnow(), }) elif transaction.action_config.action_type == RequisitionActions.APPROVAL: ret.update({ 'amount_approved': transaction.value, 'approved_by': user_id, 'approved_on': datetime.utcnow(), }) elif transaction.action_config.action_type == RequisitionActions.PACK: ret.update({ 'amount_packed': transaction.value, 'packed_by': user_id, 'packed_on': datetime.utcnow(), }) elif transaction.action_config.action_type == RequisitionActions.RECEIPTS: ret.update({ 'amount_received': transaction.value, 'received_by': user_id, 'received_on': datetime.utcnow(), 'close': True, }) else: raise ValueError("the type %s isn't yet supported." % transaction.action_config.action_type) return ret
def _is_live(case, restore_state): """ Given a case and a restore state object, return whether or not the case is "live" (direclty owned by this sync and open), or "dependent" (needed by another case) """ return not case.closed and get_owner_id(case) in restore_state.owner_ids
return 1 else: return 0 if case: subevent.case_id = case.case_id subevent.save() # Process structured sms actions first actions = sorted(survey_keyword.keywordaction_set.all(), cmp=cmp_fcn) for survey_keyword_action in actions: if survey_keyword_action.recipient == KeywordAction.RECIPIENT_SENDER: contact = sender elif survey_keyword_action.recipient == KeywordAction.RECIPIENT_OWNER: if is_commcarecase(sender): contact = get_wrapped_owner(get_owner_id(sender)) else: contact = None elif survey_keyword_action.recipient == KeywordAction.RECIPIENT_USER_GROUP: try: contact = Group.get(survey_keyword_action.recipient_id) assert contact.doc_type == "Group" assert contact.domain == verified_number.domain except Exception: contact = None else: contact = None if contact is None: continue
def get_user_from_usercase(usercase): user = get_wrapped_owner(get_owner_id(usercase)) if not isinstance(user, CommCareUser): return None return user
def might_be_relevant(case): if filter_group: return get_owner_id(case) in owner_ids else: return not users or get_matching_owner(case)
def might_be_relevant(case): return not filter_group or get_owner_id(case) in owner_ids
def process_survey_keyword_actions(verified_number, survey_keyword, text, msg): sender = verified_number.owner case = None args = split_args(text, survey_keyword) logged_event = MessagingEvent.create_from_keyword(survey_keyword, sender) # Log a messaging subevent for the incoming message subevent = logged_event.create_subevent_for_single_sms( msg.couch_recipient_doc_type, msg.couch_recipient, completed=True ) add_msg_tags(msg, MessageMetadata(messaging_subevent_id=subevent.pk)) # Close any open sessions even if it's just an sms that we're # responding with. SQLXFormsSession.close_all_open_sms_sessions(verified_number.domain, verified_number.owner_id) if is_commcarecase(sender): case = sender args = args[1:] elif isinstance(sender, CommCareUser): if keyword_uses_form_that_requires_case(survey_keyword): if len(args) > 1: external_id = args[1] case, matches = get_case_by_external_id(verified_number.domain, external_id, sender) if matches == 0: send_keyword_response(verified_number, MSG_CASE_NOT_FOUND, logged_event) logged_event.error(MessagingEvent.ERROR_CASE_EXTERNAL_ID_NOT_FOUND) return elif matches > 1: send_keyword_response(verified_number, MSG_MULTIPLE_CASES_FOUND, logged_event) logged_event.error(MessagingEvent.ERROR_MULTIPLE_CASES_WITH_EXTERNAL_ID_FOUND) return else: send_keyword_response(verified_number, MSG_MISSING_EXTERNAL_ID, logged_event) logged_event.error(MessagingEvent.ERROR_NO_EXTERNAL_ID_GIVEN) return args = args[2:] else: args = args[1:] def cmp_fcn(a1, a2): a1_ss = (a1.action == KeywordAction.ACTION_STRUCTURED_SMS) a2_ss = (a2.action == KeywordAction.ACTION_STRUCTURED_SMS) if a1_ss and a2_ss: return 0 elif a1_ss: return -1 elif a2_ss: return 1 else: return 0 if case: subevent.case_id = case.case_id subevent.save() # Process structured sms actions first actions = sorted(survey_keyword.keywordaction_set.all(), cmp=cmp_fcn) for survey_keyword_action in actions: if survey_keyword_action.recipient == KeywordAction.RECIPIENT_SENDER: contact = sender elif survey_keyword_action.recipient == KeywordAction.RECIPIENT_OWNER: if is_commcarecase(sender): contact = get_wrapped_owner(get_owner_id(sender)) else: contact = None elif survey_keyword_action.recipient == KeywordAction.RECIPIENT_USER_GROUP: try: contact = Group.get(survey_keyword_action.recipient_id) assert contact.doc_type == "Group" assert contact.domain == verified_number.domain except Exception: contact = None else: contact = None if contact is None: continue # contact can be either a user, case, group, or location if survey_keyword_action.action in (KeywordAction.ACTION_SMS, KeywordAction.ACTION_SMS_SURVEY): if isinstance(contact, Group): recipients = list(ScheduleInstance.expand_group(contact)) elif isinstance(contact, SQLLocation): recipients = list(ScheduleInstance.expand_location_ids(contact.domain, [contact.location_id])) else: recipients = [contact] recipient_is_sender = survey_keyword_action.recipient == KeywordAction.RECIPIENT_SENDER if survey_keyword_action.action == KeywordAction.ACTION_SMS: content = SMSContent(message={'*': survey_keyword_action.message_content}) content.set_context(case=case) elif survey_keyword_action.action == KeywordAction.ACTION_SMS_SURVEY: content = SMSSurveyContent( form_unique_id=survey_keyword_action.form_unique_id, expire_after=SQLXFormsSession.MAX_SESSION_LENGTH, ) content.set_context( case=case, critical_section_already_acquired=recipient_is_sender, ) else: raise ValueError("Unexpected action %s" % survey_keyword_action.action) for recipient in recipients: phone_entry = verified_number if recipient_is_sender else None content.send(recipient, logged_event, phone_entry=phone_entry) elif survey_keyword_action.action == KeywordAction.ACTION_STRUCTURED_SMS: res = handle_structured_sms(survey_keyword, survey_keyword_action, sender, verified_number, text, send_response=True, msg=msg, case=case, text_args=args, logged_event=logged_event) if not res: # If the structured sms processing wasn't successful, don't # process any of the other actions return logged_event.completed()
def export_cases(domain, cases, workbook, filter_group=None, users=None, all_groups=None, process=None): by_user_id = dict([(user.user_id, user) for user in users]) if users else {} by_group_id = dict([(g.get_id, g) for g in all_groups]) if all_groups else {} owner_ids = set(by_user_id.keys()) if filter_group: owner_ids.add(filter_group.get_id) else: # |= reassigns owner_ids to the union of the two sets owner_ids |= set(by_group_id.keys()) case_static_keys = ( "case_id", "username", "user_id", "owner_id", "owner_name", "type", "name", "opened_on", "modified_on", "closed", "closed_on", "domain", "external_id", ) case_dynamic_keys = get_case_properties(domain) case_rows = [] def render_case_attr(case, key): attr = getattr(case, key) if isinstance (attr, dict): return attr.get('#text', '') else: return attr num_cases = len(cases) def get_matching_owner(case): if by_user_id: if case.user_id in by_user_id: return case.user_id elif get_owner_id(case) in by_user_id: return get_owner_id(case) else: return get_owner_id(case) for i, case in enumerate(cases): if process: DownloadBase.set_progress(process, i, num_cases) if get_owner_id(case) in owner_ids: matching_owner = get_matching_owner(case) case_row = {'dynamic_properties': {}} for key in case_static_keys: if key == 'username': try: case_row[key] = by_user_id[matching_owner].raw_username except (TypeError, KeyError): case_row[key] = '' elif key == 'owner_name': if users and case.owner_id in by_user_id: case_row[key] = by_user_id[case.owner_id].full_name elif case.owner_id in by_group_id: case_row[key] = by_group_id[case.owner_id].name else: case_row[key] = '' else: case_row[key] = getattr(case, key) for key in case.dynamic_properties(): case_row['dynamic_properties'][key] = render_case_attr(case, key) case_rows.append(case_row) def format_dynamic_key(key): return "d.{key}".format(key=key) def tidy_up_case_row(case_row): row = dict([(key, case_row[key]) for key in case_static_keys]) for key in case_dynamic_keys: row[format_dynamic_key(key)] = case_row['dynamic_properties'].get(key, workbook.undefined) return row case_headers = list(case_static_keys) case_headers.extend([format_dynamic_key(key) for key in case_dynamic_keys]) workbook.open("Cases", case_headers) for case_row in case_rows: workbook.write_row("Cases", tidy_up_case_row(case_row)) return workbook
def _add_owner_to_template_params(case, result): owner = get_wrapped_owner(get_owner_id(case)) if owner: result['case']['owner'] = _get_obj_template_info(owner)
def case_owner(self): if self.case: return get_wrapped_owner(get_owner_id(self.case)) return None
def add_base_properties(self, element): super(V2CaseXMLGenerator, self).add_base_properties(element) from corehq.apps.users.cases import get_owner_id element.append(safe_element('owner_id', get_owner_id(self.case)))
def process_survey_keyword_actions(verified_number, survey_keyword, text, msg): sender = verified_number.owner case = None args = split_args(text, survey_keyword) logged_event = MessagingEvent.create_from_keyword(survey_keyword, sender) # Log a messaging subevent for the incoming message subevent = logged_event.create_subevent_for_single_sms( msg.couch_recipient_doc_type, msg.couch_recipient ) subevent.completed() add_msg_tags(msg, MessageMetadata(messaging_subevent_id=subevent.pk)) # Close any open sessions even if it's just an sms that we're # responding with. SQLXFormsSession.close_all_open_sms_sessions(verified_number.domain, verified_number.owner_id) if sender.doc_type == "CommCareCase": case = sender args = args[1:] elif sender.doc_type == "CommCareUser": if keyword_uses_form_that_requires_case(survey_keyword): if len(args) > 1: external_id = args[1] case, matches = get_case_by_external_id(verified_number.domain, external_id, sender) if matches == 0: send_keyword_response(verified_number, MSG_CASE_NOT_FOUND, logged_event) logged_event.error(MessagingEvent.ERROR_CASE_EXTERNAL_ID_NOT_FOUND) return elif matches > 1: send_keyword_response(verified_number, MSG_MULTIPLE_CASES_FOUND, logged_event) logged_event.error(MessagingEvent.ERROR_MULTIPLE_CASES_WITH_EXTERNAL_ID_FOUND) return else: send_keyword_response(verified_number, MSG_MISSING_EXTERNAL_ID, logged_event) logged_event.error(MessagingEvent.ERROR_NO_EXTERNAL_ID_GIVEN) return args = args[2:] else: args = args[1:] def cmp_fcn(a1, a2): a1_ss = (a1.action == METHOD_STRUCTURED_SMS) a2_ss = (a2.action == METHOD_STRUCTURED_SMS) if a1_ss and a2_ss: return 0 elif a1_ss: return -1 elif a2_ss: return 1 else: return 0 if case: subevent.case_id = case.get_id subevent.save() # Process structured sms actions first actions = sorted(survey_keyword.actions, cmp=cmp_fcn) for survey_keyword_action in actions: if survey_keyword_action.recipient == RECIPIENT_SENDER: contact = sender elif survey_keyword_action.recipient == RECIPIENT_OWNER: if sender.doc_type == "CommCareCase": contact = get_wrapped_owner(get_owner_id(sender)) else: contact = None elif survey_keyword_action.recipient == RECIPIENT_USER_GROUP: try: contact = Group.get(survey_keyword_action.recipient_id) assert contact.doc_type == "Group" assert contact.domain == verified_number.domain except Exception: contact = None else: contact = None if contact is None: continue if survey_keyword_action.action == METHOD_SMS: create_immediate_reminder(contact, METHOD_SMS, reminder_type=REMINDER_TYPE_KEYWORD_INITIATED, message=survey_keyword_action.message_content, case=case, logged_event=logged_event) elif survey_keyword_action.action == METHOD_SMS_SURVEY: create_immediate_reminder(contact, METHOD_SMS_SURVEY, reminder_type=REMINDER_TYPE_KEYWORD_INITIATED, form_unique_id=survey_keyword_action.form_unique_id, case=case, logged_event=logged_event) elif survey_keyword_action.action == METHOD_STRUCTURED_SMS: res = handle_structured_sms(survey_keyword, survey_keyword_action, sender, verified_number, text, send_response=True, msg=msg, case=case, text_args=args, logged_event=logged_event) if not res: # If the structured sms processing wasn't successful, don't # process any of the other actions return logged_event.completed()
def process_survey_keyword_actions(verified_number, survey_keyword, text, msg): sender = verified_number.owner case = None args = split_args(text, survey_keyword) # Close any open sessions even if it's just an sms that we're # responding with. XFormsSession.close_all_open_sms_sessions(verified_number.domain, verified_number.owner_id) if sender.doc_type == "CommCareCase": case = sender args = args[1:] elif sender.doc_type == "CommCareUser": if keyword_uses_form_that_requires_case(survey_keyword): if len(args) > 1: external_id = args[1] case = get_case_by_external_id(verified_number.domain, external_id) if case is None or not user_can_access_case(sender, case): send_keyword_response(verified_number, MSG_CASE_NOT_FOUND) return else: send_keyword_response(verified_number, MSG_MISSING_EXTERNAL_ID) return args = args[2:] else: args = args[1:] def cmp_fcn(a1, a2): a1_ss = (a1.action == METHOD_STRUCTURED_SMS) a2_ss = (a2.action == METHOD_STRUCTURED_SMS) if a1_ss and a2_ss: return 0 elif a1_ss: return -1 elif a2_ss: return 1 else: return 0 # Process structured sms actions first actions = sorted(survey_keyword.actions, cmp=cmp_fcn) for survey_keyword_action in actions: if survey_keyword_action.recipient == RECIPIENT_SENDER: contact = sender elif survey_keyword_action.recipient == RECIPIENT_OWNER: if sender.doc_type == "CommCareCase": contact = get_wrapped_owner(get_owner_id(sender)) else: contact = None elif survey_keyword_action.recipient == RECIPIENT_USER_GROUP: try: contact = Group.get(survey_keyword_action.recipient_id) assert contact.doc_type == "Group" assert contact.domain == verified_number.domain except Exception: contact = None else: contact = None if contact is None: continue if survey_keyword_action.action == METHOD_SMS: create_immediate_reminder(contact, METHOD_SMS, reminder_type=REMINDER_TYPE_KEYWORD_INITIATED, message=survey_keyword_action.message_content, case=case) elif survey_keyword_action.action == METHOD_SMS_SURVEY: create_immediate_reminder(contact, METHOD_SMS_SURVEY, reminder_type=REMINDER_TYPE_KEYWORD_INITIATED, form_unique_id=survey_keyword_action.form_unique_id, case=case) elif survey_keyword_action.action == METHOD_STRUCTURED_SMS: res = handle_structured_sms(survey_keyword, survey_keyword_action, sender, verified_number, text, send_response=True, msg=msg, case=case, text_args=args) if not res: # If the structured sms processing wasn't successful, don't # process any of the other actions return