Ejemplo n.º 1
0
    def test_specific_location_recipient(self):
        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_LOCATION,
            recipient_id=self.city_location.location_id,
        )
        self.assertTrue(isinstance(instance.recipient, SQLLocation))
        self.assertEqual(instance.recipient.location_id, self.city_location.location_id)

        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_LOCATION,
            recipient_id='id-does-not-exist',
        )
        self.assertIsNone(instance.recipient)
Ejemplo n.º 2
0
    def test_specific_group_recipient(self):
        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_USER_GROUP,
            recipient_id=self.group.get_id,
        )
        self.assertTrue(isinstance(instance.recipient, Group))
        self.assertEqual(instance.recipient.get_id, self.group.get_id)

        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_USER_GROUP,
            recipient_id='id-does-not-exist',
        )
        self.assertIsNone(instance.recipient)
Ejemplo n.º 3
0
    def test_specific_case_recipient(self):
        with create_case(self.domain, 'person') as case:
            instance = ScheduleInstance(
                domain=self.domain,
                recipient_type=ScheduleInstance.RECIPIENT_TYPE_CASE,
                recipient_id=case.case_id,
            )
            self.assertEqual(instance.recipient.case_id, case.case_id)

        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_CASE,
            recipient_id='id-does-not-exist',
        )
        self.assertIsNone(instance.recipient)
Ejemplo n.º 4
0
    def test_specific_web_user_recipient(self):
        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_WEB_USER,
            recipient_id=self.web_user.get_id,
        )
        self.assertTrue(isinstance(instance.recipient, WebUser))
        self.assertEqual(instance.recipient.get_id, self.web_user.get_id)

        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_WEB_USER,
            recipient_id=self.mobile_user.get_id,
        )
        self.assertIsNone(instance.recipient)

        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_WEB_USER,
            recipient_id='id-does-not-exist',
        )
        self.assertIsNone(instance.recipient)
Ejemplo n.º 5
0
                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(
Ejemplo n.º 6
0
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()