def handle(self, *args, **options):
     ids = self.get_reminder_definition_ids()
     for handler_doc in iter_docs(CaseReminderHandler.get_db(), ids):
         handler = CaseReminderHandler.wrap(handler_doc)
         if handler.reminder_type == REMINDER_TYPE_DEFAULT:
             self.check_for_ui_type(handler)
             self.check_for_multiple_fire_time_types(handler)
             self.check_for_datetime_criteria(handler)
             self.check_for_case_group_recipient(handler)
def fire_ivr_survey_event(reminder, handler, recipients, verified_numbers, logged_event):
    domain_obj = Domain.get_by_name(reminder.domain, strict=True)
    for recipient in recipients:
        initiate_call = True
        if reminder.callback_try_count > 0 and reminder.event_initiation_timestamp:
            initiate_call = not Call.answered_call_exists(
                recipient.doc_type,
                recipient.get_id,
                reminder.event_initiation_timestamp
            )

        if initiate_call:
            if (is_commcarecase(recipient) and
                not handler.force_surveys_to_use_triggered_case):
                case_id = recipient.case_id
            else:
                case_id = reminder.case_id
            verified_number, unverified_number = get_recipient_phone_number(
                reminder, recipient, verified_numbers)
            if verified_number:
                initiate_outbound_call.delay(
                    recipient,
                    reminder.current_event.form_unique_id,
                    handler.submit_partial_forms,
                    handler.include_case_side_effects,
                    handler.max_question_retries,
                    logged_event.pk,
                    verified_number=verified_number,
                    case_id=case_id,
                    case_for_case_submission=handler.force_surveys_to_use_triggered_case,
                    timestamp=CaseReminderHandler.get_now(),
                )
            elif domain_obj.send_to_duplicated_case_numbers and unverified_number:
                initiate_outbound_call.delay(
                    recipient,
                    reminder.current_event.form_unique_id,
                    handler.submit_partial_forms,
                    handler.include_case_side_effects,
                    handler.max_question_retries,
                    logged_event.pk,
                    unverified_number=unverified_number,
                    case_id=case_id,
                    case_for_case_submission=handler.force_surveys_to_use_triggered_case,
                    timestamp=CaseReminderHandler.get_now(),
                )
            else:
                # initiate_outbound_call will create the subevent automatically,
                # so since we're not initiating the call here, we have to create
                # the subevent explicitly in order to log the error.
                logged_subevent = logged_event.create_subevent(handler, reminder, recipient)
                logged_subevent.error(MessagingEvent.ERROR_NO_PHONE_NUMBER)
Beispiel #3
0
    def get_broadcast_ajax_response(self, upcoming=True):
        """
        upcoming - True to include only upcoming broadcasts, False to include
                   only past broadcasts.
        """
        if upcoming:
            ids = CaseReminderHandler.get_upcoming_broadcast_ids(self.domain)
        else:
            ids = CaseReminderHandler.get_past_broadcast_ids(self.domain)

        total_records = len(ids)
        ids = ids[self.display_start:self.display_start + self.display_length]
        data = self.format_broadcast_data(ids)
        return self.datatables_ajax_response(data, total_records)
 def _active_reminders(self):
     db = CaseReminderHandler.get_db()
     key = [self.domain.name]
     reminder_rules = db.view(
         'reminders/handlers_by_reminder_type',
         startkey=key,
         endkey=key+[{}],
         reduce=False
     ).all()
     active_reminders = []
     for reminder_doc in iter_docs(db, [r['id'] for r in reminder_rules]):
         if reminder_doc.get('active', True):
             active_reminders.append(CaseReminderHandler.wrap(reminder_doc))
     return active_reminders
Beispiel #5
0
def rule_progress(request, domain):
    client = get_redis_client()
    handlers = CaseReminderHandler.get_handlers(domain,
        reminder_type_filter=REMINDER_TYPE_DEFAULT)

    response = {}
    for handler in handlers:
        info = {}
        if handler.locked:
            info['complete'] = False
            current = None
            total = None

            try:
                current = client.get('reminder-rule-processing-current-%s' % handler._id)
                total = client.get('reminder-rule-processing-total-%s' % handler._id)
            except:
                continue

            info['current'] = int_or_none(current)
            info['total'] = int_or_none(total)
        else:
            info['complete'] = True

        response[handler._id] = info

    return HttpResponse(json.dumps(response))
Beispiel #6
0
    def clean(self):
        cleaned_data = self.cleaned_data
        sm = cleaned_data["share_multimedia"]
        license = cleaned_data["license"]
        app_ids = self._get_apps_to_publish()

        if sm and license not in self.dom.most_restrictive_licenses(apps_to_check=app_ids):
            license_choices = [LICENSES[l] for l in self.dom.most_restrictive_licenses(apps_to_check=app_ids)]
            msg = render_to_string('domain/partials/restrictive_license.html', {'licenses': license_choices})
            self._errors["license"] = self.error_class([msg])

            del cleaned_data["license"]

        sr = cleaned_data["share_reminders"]
        if sr:  # check that the forms referenced by the events in each reminders exist in the project
            referenced_forms = CaseReminderHandler.get_referenced_forms(domain=self.dom.name)
            if referenced_forms:
                apps = [Application.get(app_id) for app_id in app_ids]
                app_forms = [f.unique_id for forms in [app.get_forms() for app in apps] for f in forms]
                nonexistent_forms = filter(lambda f: f not in app_forms, referenced_forms)
                nonexistent_forms = [FormBase.get_form(f) for f in nonexistent_forms]
                if nonexistent_forms:
                    msg = """
                        Your reminders reference forms that are not being published.
                        Make sure the following forms are being published: %s
                    """ % str([f.default_name() for f in nonexistent_forms]).strip('[]')
                    self._errors["share_reminders"] = self.error_class([msg])

        return cleaned_data
Beispiel #7
0
def get_active_reminders_by_domain_name(domain_name):
    from corehq.apps.reminders.models import CaseReminderHandler, REMINDER_TYPE_DEFAULT, REMINDER_TYPE_KEYWORD_INITIATED

    db = CaseReminderHandler.get_db()
    key = [domain_name]
    reminder_rules = db.view(
        "reminders/handlers_by_reminder_type", startkey=key, endkey=(key + [{}]), reduce=False
    ).all()
    return [
        CaseReminderHandler.wrap(reminder_doc)
        for reminder_doc in iter_docs(db, [r["id"] for r in reminder_rules])
        if (
            reminder_doc.get("active", True)
            and reminder_doc.get("reminder_type", REMINDER_TYPE_DEFAULT) != REMINDER_TYPE_KEYWORD_INITIATED
        )
    ]
    def setUp(self):
        super(ReminderTestCase, self).setUp()
        self.domain = self.domain_obj.name
        self.case_type = "my_case_type"
        self.message = "Test reminder message."

        self.handler = (CaseReminderHandler.create(self.domain, 'test')
            .set_case_criteria_start_condition(self.case_type, 'start_sending', MATCH_EXACT, 'ok')
            .set_case_criteria_start_date(start_offset=1)
            .set_last_submitting_user_recipient()
            .set_sms_content_type('en')
            .set_schedule_manually(
                EVENT_AS_OFFSET,
                3,
                [
                    CaseReminderEvent(
                        day_num=0,
                        fire_time=time(0, 0),
                        message={'en': self.message},
                        callback_timeout_intervals=[]
                    ),
                ])
            .set_stop_condition(stop_case_property='stop_sending')
            .set_advanced_options()
        )
        self.handler.save()

        self.user = CommCareUser.create(self.domain, 'chw.bob', 'abc', phone_number='99912345')
    def setUp(self):
        super(StartConditionReminderTestCase, self).setUp()
        self.domain = self.domain_obj.name
        self.user = CommCareUser.create(self.domain, 'chw.bob5', 'abc', phone_number='99912345')

        self.handler1 = (CaseReminderHandler.create(self.domain, 'test')
            .set_case_criteria_start_condition('case_type_a', 'start_sending1',
                MATCH_REGEX, '^(ok|\d\d\d\d-\d\d-\d\d)')
            .set_case_criteria_start_date(start_date='start_sending1', start_offset=1)
            .set_last_submitting_user_recipient()
            .set_sms_content_type('en')
            .set_schedule_manually(
                EVENT_AS_OFFSET,
                3,
                [
                    CaseReminderEvent(
                        day_num=0,
                        fire_time=time(0, 0),
                        message={'en': 'Message1'},
                        callback_timeout_intervals=[]
                    ),
                ])
            .set_stop_condition(stop_case_property='stop_sending1')
            .set_advanced_options(use_today_if_start_date_is_blank=True))
        self.handler1.save()
Beispiel #10
0
def scheduled_reminders(request, domain, template="reminders/partial/scheduled_reminders.html"):
    reminders = CaseReminderHandler.get_all_reminders(domain)
    dates = []
    now = datetime.utcnow()
    today = now.date()
    if reminders:
        start_date = reminders[0].next_fire.date()
        if today < start_date:
            start_date = today
        end_date = reminders[-1].next_fire.date()
    else:
        start_date = end_date = today
    # make sure start date is a Monday and enddate is a Sunday
    start_date -= timedelta(days=start_date.weekday())
    end_date += timedelta(days=6-end_date.weekday())
    while start_date <= end_date:
        dates.append(start_date)
        start_date += timedelta(days=1)

    return render_to_response(request, template, {
        'domain': domain,
        'reminders': reminders,
        'dates': dates,
        'today': today,
        'now': now,
    })
Beispiel #11
0
def case_changed(self, domain, case_id):
    try:
        handler_ids = CaseReminderHandler.get_handler_ids(domain, reminder_type_filter=REMINDER_TYPE_DEFAULT)
        if handler_ids:
            _case_changed(case_id, handler_ids)
    except Exception as e:
        self.retry(exc=e)
Beispiel #12
0
def list_reminders(request, domain, template="reminders/partial/list_reminders.html"):
    handlers = CaseReminderHandler.get_handlers(domain=domain).all()
    print handlers
    return render_to_response(request, template, {
        'domain': domain,
        'reminder_handlers': handlers
    })
Beispiel #13
0
def add_reminder(request, domain, handler_id=None, template="reminders/partial/add_reminder.html"):

    if handler_id:
        handler = CaseReminderHandler.get(handler_id)
        if handler.doc_type != 'CaseReminderHandler' or handler.domain != domain:
            raise Http404
    else:
        handler = None
        
    if request.method == "POST":
        reminder_form = CaseReminderForm(request.POST)
        if reminder_form.is_valid():
            if not handler:
                handler = CaseReminderHandler(domain=domain)
                handler.ui_type = UI_SIMPLE_FIXED
            for key, value in reminder_form.cleaned_data.items():
                if (key != "frequency") and (key != "message"):
                    handler[key] = value
            handler.max_iteration_count = REPEAT_SCHEDULE_INDEFINITELY
            handler.schedule_length = reminder_form.cleaned_data["frequency"]
            handler.event_interpretation = EVENT_AS_OFFSET
            handler.events = [
                CaseReminderEvent(
                    day_num = 0
                   ,fire_time = time(hour=0,minute=0,second=0)
                   ,message = reminder_form.cleaned_data["message"]
                   ,callback_timeout_intervals = []
               )
            ]
            handler.save()
            print handler.events[0].message
            return HttpResponseRedirect(reverse('list_reminders', args=[domain]))
    elif handler:
        initial = {}
        for key in handler.to_json():
            if (key != "max_iteration_count") and (key != "schedule_length") and (key != "events") and (key != "event_interpretation"):
                initial[key] = handler[key]
        initial["message"] = json.dumps(handler.events[0].message)
        initial["frequency"] = handler.schedule_length
        reminder_form = CaseReminderForm(initial=initial)
    else:
        reminder_form = CaseReminderForm()

    return render_to_response(request, template, {
        'reminder_form': reminder_form,
        'domain': domain
    })
 def domain_has_active_reminders(self, domain):
     for handler in CaseReminderHandler.get_handlers(
         domain.name,
         reminder_type_filter=REMINDER_TYPE_DEFAULT
     ):
         if handler.active:
             return True
     return False
Beispiel #15
0
 def reminder_handler(self):
     try:
         handler = CaseReminderHandler.get(self.handler_id)
         assert handler.domain == self.domain
         assert handler.doc_type == "CaseReminderHandler"
         return handler
     except (ResourceNotFound, AssertionError):
         raise Http404()
Beispiel #16
0
    def page_context(self):
        page_context = super(ScheduledRemindersCalendarView, self).page_context
        timezone = Domain.get_by_name(self.domain).get_default_timezone()
        reminders = CaseReminderHandler.get_all_reminders(self.domain)
        dates = []
        now = datetime.utcnow()
        timezone_now = datetime.now(timezone)
        today = timezone_now.date()

        def adjust_next_fire_to_timezone(reminder_utc):
            return ServerTime(reminder_utc.next_fire).user_time(timezone).done()

        if reminders:
            start_date = adjust_next_fire_to_timezone(reminders[0]).date()
            if today < start_date:
                start_date = today
            end_date = adjust_next_fire_to_timezone(reminders[-1]).date()
        else:
            start_date = end_date = today
        # make sure start date is a Monday and enddate is a Sunday
        start_date -= timedelta(days=start_date.weekday())
        end_date += timedelta(days=6 - end_date.weekday())
        while start_date <= end_date:
            dates.append(start_date)
            start_date += timedelta(days=1)

        reminder_data = []
        for reminder in reminders:
            handler = reminder.handler
            recipient = reminder.recipient
            recipient_desc = get_recipient_name(recipient)
            case = reminder.case

            reminder_data.append(
                {
                    "handler_name": handler.nickname,
                    "next_fire": adjust_next_fire_to_timezone(reminder),
                    "recipient_desc": recipient_desc,
                    "recipient_type": handler.recipient,
                    "case_id": case.case_id if case is not None else None,
                    "case_name": case.name if case is not None else None,
                }
            )

        page_context.update(
            {
                "domain": self.domain,
                "reminder_data": reminder_data,
                "dates": dates,
                "today": today,
                "now": now,
                "timezone": timezone,
                "timezone_now": timezone_now,
            }
        )
        return page_context
Beispiel #17
0
def case_changed_receiver(sender, case, **kwargs):
    try:
        handler_ids = CaseReminderHandler.get_handlers(case.domain,
            ids_only=True)
        if len(handler_ids) > 0:
            case_changed.delay(case._id, handler_ids)
    except Exception:
        notify_exception(None,
            message="Error in reminders case changed receiver for case %s" %
            case._id)
Beispiel #18
0
def case_changed_receiver(sender, case, **kwargs):
    try:
        handler_ids = CaseReminderHandler.get_handler_ids(case.domain,
            reminder_type_filter=REMINDER_TYPE_DEFAULT)
        if len(handler_ids) > 0:
            case_changed.delay(case._id, handler_ids)
    except Exception:
        notify_exception(None,
            message="Error in reminders case changed receiver for case %s" %
            case._id)
Beispiel #19
0
 def reminders(self):
     all_handlers = CaseReminderHandler.get_handlers(self.domain,
         reminder_type_filter=REMINDER_TYPE_DEFAULT)
     if not self.can_use_survey:
         all_handlers = filter(
             lambda x: x.method not in [METHOD_IVR_SURVEY, METHOD_SMS_SURVEY],
             all_handlers
         )
     for handler in all_handlers:
         yield self._fmt_reminder_data(handler)
Beispiel #20
0
    def delete_broadcast(self, broadcast_id):
        try:
            broadcast = CaseReminderHandler.get(broadcast_id)
        except:
            raise Http404()

        if broadcast.doc_type != 'CaseReminderHandler' or broadcast.domain != self.domain:
            raise Http404()

        broadcast.retire()
        return HttpResponse()
Beispiel #21
0
def _case_changed(case_id, handler_ids):
    subcases = None
    case = CommCareCase.get(case_id)
    for handler in CaseReminderHandler.get_handlers_from_ids(handler_ids):
        if handler.start_condition_type == CASE_CRITERIA:
            handler.case_changed(case)
            if handler.uses_parent_case_property:
                if subcases is None:
                    subcases = get_subcases(case)
                for subcase in subcases:
                    handler.case_changed(subcase)
 def handle(self, *labels, **options):
     handlers = CaseReminderHandler.view("reminders/handlers_by_domain_case_type", include_docs=True)
     print "Migrating CaseReminderHandlers"
     for h in handlers:            
         try:
             h.start_property    = h.start
             h.start_value       = "^(ok|OK|\d\d\d\d-\d\d-\d\d)"
             h.start_date        = h.start
             h.start_match_type  = MATCH_REGEX
             h.save()
         except Exception as e:
             print "There was an error migrating handler %s." % (h._id)
Beispiel #23
0
def scheduled_reminders(request, domain, template="reminders/partial/scheduled_reminders.html"):
    reminders = CaseReminderHandler.get_all_reminders(domain)
    dates = []
    now = datetime.utcnow()
    today = now.date()
    if reminders:
        start_date = reminders[0].next_fire.date()
        if today < start_date:
            start_date = today
        end_date = reminders[-1].next_fire.date()
    else:
        start_date = end_date = today
    # make sure start date is a Monday and enddate is a Sunday
    start_date -= timedelta(days=start_date.weekday())
    end_date += timedelta(days=6-end_date.weekday())
    while start_date <= end_date:
        dates.append(start_date)
        start_date += timedelta(days=1)
    
    reminder_data = []
    for reminder in reminders:
        handler = reminder.handler
        recipient = reminder.recipient
        
        if isinstance(recipient, CouchUser):
            recipient_desc = "User '" + recipient.raw_username + "'"
        elif isinstance(recipient, CommCareCase):
            recipient_desc = "Case '" + recipient.name + "'"
        elif isinstance(recipient, Group):
            recipient_desc = "Group '" + recipient.name + "'"
        elif isinstance(recipient, SurveySample):
            recipient_desc = "Survey Sample '" + recipient.name + "'"
        else:
            recipient_desc = ""
        
        case = reminder.case
        
        reminder_data.append({
            "handler_name" : handler.nickname,
            "next_fire" : reminder.next_fire,
            "recipient_desc" : recipient_desc,
            "recipient_type" : handler.recipient,
            "case_id" : case.get_id if case is not None else None,
            "case_name" : case.name if case is not None else None,
        })
    
    return render(request, template, {
        'domain': domain,
        'reminder_data': reminder_data,
        'dates': dates,
        'today': today,
        'now': now,
    })
Beispiel #24
0
def delete_reminders_for_cases(domain, case_ids):
    handler_ids = CaseReminderHandler.get_handler_ids(
        domain, reminder_type_filter=REMINDER_TYPE_DEFAULT)
    for ids in chunked(case_ids, 50):
        keys = [[domain, handler_id, case_id]
                for handler_id in handler_ids
                for case_id in ids]
        results = CaseReminder.get_db().view(
            'reminders/by_domain_handler_case',
            keys=keys,
            include_docs=True
        )
        soft_delete_docs([row['doc'] for row in results], CaseReminder)
Beispiel #25
0
def _case_changed(case_id, handler_ids):
    subcases = None
    case = CommCareCase.get(case_id)
    for handler in CaseReminderHandler.get_handlers_from_ids(handler_ids):
        if handler.start_condition_type == CASE_CRITERIA:
            kwargs = {}
            if handler.uses_time_case_property:
                kwargs = {"schedule_changed": True, "prev_definition": handler}
            handler.case_changed(case, **kwargs)
            if handler.uses_parent_case_property:
                if subcases is None:
                    subcases = get_subcases(case)
                for subcase in subcases:
                    handler.case_changed(subcase, **kwargs)
Beispiel #26
0
 def _active_reminder_methods(self):
     db = CaseReminderHandler.get_db()
     key = [self.domain.name]
     reminder_rules = db.view(
         'reminders/handlers_by_reminder_type',
         startkey=key,
         endkey=key+[{}],
         reduce=False
     ).all()
     recipients = []
     for reminder_doc in iter_docs(db, [r['id'] for r in reminder_rules]):
         if reminder_doc['active']:
             recipients.append(reminder_doc['method'])
     return recipients
Beispiel #27
0
    def broadcast(self):
        try:
            broadcast = CaseReminderHandler.get(self.broadcast_id)
        except:
            raise Http404()

        if (
            broadcast.doc_type != 'CaseReminderHandler' or
            broadcast.domain != self.domain or
            broadcast.reminder_type != REMINDER_TYPE_ONE_TIME
        ):
            raise Http404()

        return broadcast
Beispiel #28
0
def case_changed_receiver(sender, case, **kwargs):
    try:
        subcases = None
        handlers = CaseReminderHandler.get_handlers(case.domain)
        for handler in handlers:
            if handler.start_condition_type == CASE_CRITERIA:
                handler.case_changed(case)
                if handler.uses_parent_case_property:
                    if subcases is None:
                        subcases = get_subcases(case)
                    for subcase in subcases:
                        handler.case_changed(subcase)
    except Exception:
        logging.exception("Error processing reminders case_changed_receiver for case %s" % case._id)
Beispiel #29
0
 def format_broadcast_data(self, ids):
     broadcasts = CaseReminderHandler.get_handlers_from_ids(ids)
     result = []
     for broadcast in broadcasts:
         display = self.format_broadcast_name(broadcast)
         result.append([
             display,
             self.format_recipients(broadcast),
             self.format_content(broadcast),
             broadcast._id,
             reverse(EditBroadcastView.urlname, args=[self.domain, broadcast._id]),
             reverse(CopyBroadcastView.urlname, args=[self.domain, broadcast._id]),
         ])
     return result
Beispiel #30
0
def _case_changed(domain, case_id, handler_ids):
    case = CaseAccessors(domain).get_case(case_id)
    for handler in CaseReminderHandler.get_handlers_from_ids(handler_ids):
        if handler.start_condition_type == CASE_CRITERIA:
            kwargs = {}
            if handler.uses_time_case_property:
                kwargs = {
                    'schedule_changed': True,
                    'prev_definition': handler,
                }
            handler.case_changed(case, **kwargs)
            if handler.uses_parent_case_property:
                subcases = case.get_subcases(index_identifier=DEFAULT_PARENT_IDENTIFIER)
                for subcase in subcases:
                    handler.case_changed(subcase, **kwargs)
Beispiel #31
0
 def fire_reminders():
     CaseReminderHandler.fire_reminders()
Beispiel #32
0
 def create_new_broadcast(self):
     return CaseReminderHandler(
         domain=self.domain,
         nickname='One-time Reminder',
         reminder_type=REMINDER_TYPE_ONE_TIME,
     )
Beispiel #33
0
    def testOutbound(self):
        # Send an outbound call using self.reminder1 to self.case
        # and answer it
        CaseReminderHandler.now = datetime(2014, 6, 23, 10, 0)
        self.case.name = "case1"
        self.case.save()
        CaseReminderHandler.now = datetime(2014, 6, 23, 12, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 12, 30))

        call = self.get_last_outbound_call(self.case)
        self.assertTrue(call.use_precached_first_response)

        kookoo_session_id = call.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(
            resp,
            '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })

        call = CallLog.get(call._id)
        self.assertTrue(call.answered)
        self.assertEqual(call.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "1")
        self.assertFormQuestionEquals(form, "take_meds", "2")
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "1")
        self.assertCasePropertyEquals(case, "take_meds", "2")

        CaseReminderHandler.now = datetime(2014, 6, 23, 12, 30)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 13, 0))

        last_call = self.get_last_outbound_call(self.case)
        self.assertEqual(call._id, last_call._id)

        # Move on to the second event which now uses an all-label form and
        # should not precache the first ivr response
        CaseReminderHandler.now = datetime(2014, 6, 23, 13, 0)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 13, 30))

        call = self.get_last_outbound_call(self.case)
        self.assertFalse(call.use_precached_first_response)

        kookoo_session_id = call.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s">'
            '<playtext>This is just a reminder to take your meds.'
            '</playtext><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "5",
        })

        call = CallLog.get(call._id)
        self.assertTrue(call.answered)
        self.assertEqual(call.duration, 5)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "label", "ok")

        CaseReminderHandler.now = datetime(2014, 6, 23, 13, 30)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 0))

        last_call = self.get_last_outbound_call(self.case)
        self.assertEqual(call._id, last_call._id)

        # Now test sending outbound calls to a group of users (the owners
        # of the case)

        # Allow sending to unverified numbers
        self.domain_obj = Domain.get(self.domain_obj._id)
        self.domain_obj.send_to_duplicated_case_numbers = True
        self.domain_obj.save()

        CaseReminderHandler.now = datetime(2014, 6, 24, 10, 0)
        self.case = CommCareCase.get(self.case._id)
        self.case.name = "case2"
        self.case.save()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 0))

        CaseReminderHandler.now = datetime(2014, 6, 24, 12, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 30))

        call1 = self.get_last_outbound_call(self.user1)
        self.assertTrue(call1.use_precached_first_response)
        self.assertFalse(call1.answered)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertFalse(call2.answered)

        old_call1 = call1
        old_call2 = call2

        CaseReminderHandler.now = datetime(2014, 6, 24, 12, 30)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 13, 0))

        call1 = self.get_last_outbound_call(self.user1)
        self.assertTrue(call1.use_precached_first_response)
        self.assertNotEqual(call1._id, old_call1._id)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertFalse(call2.answered)
        self.assertNotEqual(call2._id, old_call2._id)

        kookoo_session_id = call1.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(
            resp,
            '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })
        call1 = CallLog.get(call1._id)
        self.assertTrue(call1.answered)
        self.assertEqual(call1.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "2")
        self.assertFormQuestionEquals(form, "take_meds", "1")
        self.assertEqual(form.form["meta"]["userID"], self.user1._id)
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "2")
        self.assertCasePropertyEquals(case, "take_meds", "1")
        self.assertEqual(case.user_id, self.user1._id)

        old_call1 = call1
        old_call2 = call2

        CaseReminderHandler.now = datetime(2014, 6, 24, 13, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 25, 12, 0))

        call1 = self.get_last_outbound_call(self.user1)
        # No new call for user1 since it was already answered
        self.assertEqual(call1._id, old_call1._id)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertNotEqual(call2._id, old_call2._id)

        kookoo_session_id = call2.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(
            resp,
            '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })
        call2 = CallLog.get(call2._id)
        self.assertTrue(call2.answered)
        self.assertEqual(call2.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "1")
        self.assertFormQuestionEquals(form, "take_meds", "2")
        self.assertEqual(form.form["meta"]["userID"], self.user2._id)
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "1")
        self.assertCasePropertyEquals(case, "take_meds", "2")
        self.assertEqual(case.user_id, self.user2._id)
Beispiel #34
0
class KooKooTestCase(TouchformsTestCase):
    """
    Must be run manually (see corehq.apps.sms.tests.util.TouchformsTestCase)
    """
    def setUp(self):
        super(KooKooTestCase, self).setUp()
        self.ivr_backend = MobileBackend(
            _id="MOBILE_BACKEND_KOOKOO",
            outbound_module="corehq.apps.kookoo.api",
            outbound_params={
                "is_test": True,
                "api_key": "xyz"
            },
        )
        self.ivr_backend.save()

        self.user1 = self.create_mobile_worker("user1",
                                               "123",
                                               "91001",
                                               save_vn=False)
        self.user2 = self.create_mobile_worker("user2",
                                               "123",
                                               "91002",
                                               save_vn=False)
        self.create_group("group1", [self.user1, self.user2])

        self.case = CommCareCase(
            domain=self.domain,
            type="participant",
            owner_id=self.groups[0]._id,
        )
        self.case.set_case_property("contact_phone_number", "91000")
        self.case.set_case_property("contact_phone_number_is_verified", "1")
        self.case.set_case_property("contact_ivr_backend_id",
                                    "MOBILE_BACKEND_KOOKOO")
        self.case.save()

        dirname = os.path.dirname(os.path.abspath(__file__))
        self.load_app("app1.json", dirname)
        self.load_app("app2.json", dirname)

        self.reminder1 = CaseReminderHandler(
            domain=self.domain,
            active=True,
            case_type="participant",
            method=METHOD_IVR_SURVEY,
            recipient=RECIPIENT_CASE,
            sample_id=None,
            user_group_id=None,
            user_id=None,
            case_id=None,
            reminder_type=REMINDER_TYPE_DEFAULT,
            submit_partial_forms=True,
            include_case_side_effects=False,
            max_question_retries=5,
            start_condition_type=CASE_CRITERIA,
            start_property="name",
            start_value="case1",
            start_date=None,
            start_offset=0,
            start_match_type=MATCH_EXACT,
            events=[
                CaseReminderEvent(
                    day_num=0,
                    fire_time=time(12, 0),
                    fire_time_type=FIRE_TIME_DEFAULT,
                    callback_timeout_intervals=[30],
                    form_unique_id=self.apps[0].modules[0].forms[0].unique_id,
                ),
                CaseReminderEvent(
                    day_num=0,
                    fire_time=time(13, 0),
                    fire_time_type=FIRE_TIME_DEFAULT,
                    callback_timeout_intervals=[30],
                    form_unique_id=self.apps[0].modules[0].forms[1].unique_id,
                ),
            ],
            schedule_length=1,
            event_interpretation=EVENT_AS_SCHEDULE,
            max_iteration_count=7,
            until=None,
            force_surveys_to_use_triggered_case=False,
        )
        self.reminder1.save()

        self.reminder2 = CaseReminderHandler(
            domain=self.domain,
            active=True,
            case_type="participant",
            method=METHOD_IVR_SURVEY,
            recipient=RECIPIENT_OWNER,
            sample_id=None,
            user_group_id=None,
            user_id=None,
            case_id=None,
            reminder_type=REMINDER_TYPE_DEFAULT,
            submit_partial_forms=True,
            include_case_side_effects=True,
            max_question_retries=5,
            start_condition_type=CASE_CRITERIA,
            start_property="name",
            start_value="case2",
            start_date=None,
            start_offset=0,
            start_match_type=MATCH_EXACT,
            events=[
                CaseReminderEvent(
                    day_num=0,
                    fire_time=time(12, 0),
                    fire_time_type=FIRE_TIME_DEFAULT,
                    callback_timeout_intervals=[30, 30],
                    form_unique_id=self.apps[1].modules[0].forms[0].unique_id,
                ),
            ],
            schedule_length=1,
            event_interpretation=EVENT_AS_SCHEDULE,
            max_iteration_count=7,
            until=None,
            force_surveys_to_use_triggered_case=False,
        )
        self.reminder2.save()

    def kookoo_in(self, params):
        """
        params should be a dictionary containing:
        event, cid, sid, and (optionally) data
        """
        params = urllib.urlencode(params)
        url = "%s/kookoo/ivr/" % self.live_server_url
        return urllib2.urlopen("%s?%s" % (url, params)).read()

    def kookoo_finished(self, params):
        """
        params should be a dictionary containing:
        sid, status, and duration
        """
        params = urllib.urlencode(params)
        url = "%s/kookoo/ivr_finished/" % self.live_server_url
        return urllib2.urlopen(url, params).read()

    def testOutbound(self):
        # Send an outbound call using self.reminder1 to self.case
        # and answer it
        CaseReminderHandler.now = datetime(2014, 6, 23, 10, 0)
        self.case.name = "case1"
        self.case.save()
        CaseReminderHandler.now = datetime(2014, 6, 23, 12, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 12, 30))

        call = self.get_last_outbound_call(self.case)
        self.assertTrue(call.use_precached_first_response)

        kookoo_session_id = call.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(
            resp,
            '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })

        call = CallLog.get(call._id)
        self.assertTrue(call.answered)
        self.assertEqual(call.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "1")
        self.assertFormQuestionEquals(form, "take_meds", "2")
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "1")
        self.assertCasePropertyEquals(case, "take_meds", "2")

        CaseReminderHandler.now = datetime(2014, 6, 23, 12, 30)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 13, 0))

        last_call = self.get_last_outbound_call(self.case)
        self.assertEqual(call._id, last_call._id)

        # Move on to the second event which now uses an all-label form and
        # should not precache the first ivr response
        CaseReminderHandler.now = datetime(2014, 6, 23, 13, 0)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 13, 30))

        call = self.get_last_outbound_call(self.case)
        self.assertFalse(call.use_precached_first_response)

        kookoo_session_id = call.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s">'
            '<playtext>This is just a reminder to take your meds.'
            '</playtext><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "5",
        })

        call = CallLog.get(call._id)
        self.assertTrue(call.answered)
        self.assertEqual(call.duration, 5)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "label", "ok")

        CaseReminderHandler.now = datetime(2014, 6, 23, 13, 30)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 0))

        last_call = self.get_last_outbound_call(self.case)
        self.assertEqual(call._id, last_call._id)

        # Now test sending outbound calls to a group of users (the owners
        # of the case)

        # Allow sending to unverified numbers
        self.domain_obj = Domain.get(self.domain_obj._id)
        self.domain_obj.send_to_duplicated_case_numbers = True
        self.domain_obj.save()

        CaseReminderHandler.now = datetime(2014, 6, 24, 10, 0)
        self.case = CommCareCase.get(self.case._id)
        self.case.name = "case2"
        self.case.save()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 0))

        CaseReminderHandler.now = datetime(2014, 6, 24, 12, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 30))

        call1 = self.get_last_outbound_call(self.user1)
        self.assertTrue(call1.use_precached_first_response)
        self.assertFalse(call1.answered)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertFalse(call2.answered)

        old_call1 = call1
        old_call2 = call2

        CaseReminderHandler.now = datetime(2014, 6, 24, 12, 30)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 13, 0))

        call1 = self.get_last_outbound_call(self.user1)
        self.assertTrue(call1.use_precached_first_response)
        self.assertNotEqual(call1._id, old_call1._id)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertFalse(call2.answered)
        self.assertNotEqual(call2._id, old_call2._id)

        kookoo_session_id = call1.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(
            resp,
            '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })
        call1 = CallLog.get(call1._id)
        self.assertTrue(call1.answered)
        self.assertEqual(call1.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "2")
        self.assertFormQuestionEquals(form, "take_meds", "1")
        self.assertEqual(form.form["meta"]["userID"], self.user1._id)
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "2")
        self.assertCasePropertyEquals(case, "take_meds", "1")
        self.assertEqual(case.user_id, self.user1._id)

        old_call1 = call1
        old_call2 = call2

        CaseReminderHandler.now = datetime(2014, 6, 24, 13, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 25, 12, 0))

        call1 = self.get_last_outbound_call(self.user1)
        # No new call for user1 since it was already answered
        self.assertEqual(call1._id, old_call1._id)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertNotEqual(call2._id, old_call2._id)

        kookoo_session_id = call2.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(
            resp,
            '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })
        call2 = CallLog.get(call2._id)
        self.assertTrue(call2.answered)
        self.assertEqual(call2.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "1")
        self.assertFormQuestionEquals(form, "take_meds", "2")
        self.assertEqual(form.form["meta"]["userID"], self.user2._id)
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "1")
        self.assertCasePropertyEquals(case, "take_meds", "2")
        self.assertEqual(case.user_id, self.user2._id)

    def tearDown(self):
        self.ivr_backend.delete()
        super(KooKooTestCase, self).tearDown()
Beispiel #35
0
    def setUp(self):
        super(KooKooTestCase, self).setUp()
        self.ivr_backend = MobileBackend(
            _id="MOBILE_BACKEND_KOOKOO",
            outbound_module="corehq.apps.kookoo.api",
            outbound_params={
                "is_test": True,
                "api_key": "xyz"
            },
        )
        self.ivr_backend.save()

        self.user1 = self.create_mobile_worker("user1",
                                               "123",
                                               "91001",
                                               save_vn=False)
        self.user2 = self.create_mobile_worker("user2",
                                               "123",
                                               "91002",
                                               save_vn=False)
        self.create_group("group1", [self.user1, self.user2])

        self.case = CommCareCase(
            domain=self.domain,
            type="participant",
            owner_id=self.groups[0]._id,
        )
        self.case.set_case_property("contact_phone_number", "91000")
        self.case.set_case_property("contact_phone_number_is_verified", "1")
        self.case.set_case_property("contact_ivr_backend_id",
                                    "MOBILE_BACKEND_KOOKOO")
        self.case.save()

        dirname = os.path.dirname(os.path.abspath(__file__))
        self.load_app("app1.json", dirname)
        self.load_app("app2.json", dirname)

        self.reminder1 = CaseReminderHandler(
            domain=self.domain,
            active=True,
            case_type="participant",
            method=METHOD_IVR_SURVEY,
            recipient=RECIPIENT_CASE,
            sample_id=None,
            user_group_id=None,
            user_id=None,
            case_id=None,
            reminder_type=REMINDER_TYPE_DEFAULT,
            submit_partial_forms=True,
            include_case_side_effects=False,
            max_question_retries=5,
            start_condition_type=CASE_CRITERIA,
            start_property="name",
            start_value="case1",
            start_date=None,
            start_offset=0,
            start_match_type=MATCH_EXACT,
            events=[
                CaseReminderEvent(
                    day_num=0,
                    fire_time=time(12, 0),
                    fire_time_type=FIRE_TIME_DEFAULT,
                    callback_timeout_intervals=[30],
                    form_unique_id=self.apps[0].modules[0].forms[0].unique_id,
                ),
                CaseReminderEvent(
                    day_num=0,
                    fire_time=time(13, 0),
                    fire_time_type=FIRE_TIME_DEFAULT,
                    callback_timeout_intervals=[30],
                    form_unique_id=self.apps[0].modules[0].forms[1].unique_id,
                ),
            ],
            schedule_length=1,
            event_interpretation=EVENT_AS_SCHEDULE,
            max_iteration_count=7,
            until=None,
            force_surveys_to_use_triggered_case=False,
        )
        self.reminder1.save()

        self.reminder2 = CaseReminderHandler(
            domain=self.domain,
            active=True,
            case_type="participant",
            method=METHOD_IVR_SURVEY,
            recipient=RECIPIENT_OWNER,
            sample_id=None,
            user_group_id=None,
            user_id=None,
            case_id=None,
            reminder_type=REMINDER_TYPE_DEFAULT,
            submit_partial_forms=True,
            include_case_side_effects=True,
            max_question_retries=5,
            start_condition_type=CASE_CRITERIA,
            start_property="name",
            start_value="case2",
            start_date=None,
            start_offset=0,
            start_match_type=MATCH_EXACT,
            events=[
                CaseReminderEvent(
                    day_num=0,
                    fire_time=time(12, 0),
                    fire_time_type=FIRE_TIME_DEFAULT,
                    callback_timeout_intervals=[30, 30],
                    form_unique_id=self.apps[1].modules[0].forms[0].unique_id,
                ),
            ],
            schedule_length=1,
            event_interpretation=EVENT_AS_SCHEDULE,
            max_iteration_count=7,
            until=None,
            force_surveys_to_use_triggered_case=False,
        )
        self.reminder2.save()
Beispiel #36
0
 handler = CaseReminderHandler(
     domain=contact.domain,
     reminder_type=reminder_type,
     nickname="One-time Reminder",
     default_lang="xx",
     method=content_type,
     recipient=recipient,
     start_condition_type=ON_DATETIME,
     start_datetime=datetime.utcnow(),
     start_offset=0,
     events=[
         CaseReminderEvent(
             day_num=0,
             fire_time=time(0, 0),
             form_unique_id=form_unique_id
             if content_type == METHOD_SMS_SURVEY else None,
             message={'xx': message} if content_type == METHOD_SMS else {},
             callback_timeout_intervals=[],
         )
     ],
     schedule_length=1,
     event_interpretation=EVENT_AS_OFFSET,
     max_iteration_count=1,
     case_id=case_id,
     user_id=contact.get_id if recipient == RECIPIENT_USER else None,
     sample_id=contact.get_id
     if recipient == RECIPIENT_SURVEY_SAMPLE else None,
     user_group_id=contact.get_id
     if recipient == RECIPIENT_USER_GROUP else None,
     messaging_event_id=logged_event.pk if logged_event else None,
 )
Beispiel #37
0
    def test_cache(self, check_state_mock):

        # Nothing expected at first
        self.assertEqual(CaseReminderHandler.get_handler_ids(self.domain), [])

        # Create two reminder definitions of different types
        handler1 = CaseReminderHandler(
            domain=self.domain,
            reminder_type=REMINDER_TYPE_DEFAULT,
        )
        handler1.save()
        self.addCleanup(handler1.delete)

        handler2 = CaseReminderHandler(
            domain=self.domain,
            reminder_type=REMINDER_TYPE_ONE_TIME,
        )
        handler2.save()
        self.addCleanup(handler2.delete)

        self.assertEqual(
            CaseReminderHandler.get_handler_ids(
                self.domain, reminder_type_filter=REMINDER_TYPE_DEFAULT),
            [handler1._id])

        self.assertEqual(
            CaseReminderHandler.get_handler_ids(
                self.domain, reminder_type_filter=REMINDER_TYPE_ONE_TIME),
            [handler2._id])

        self.assertEqual(
            sorted(CaseReminderHandler.get_handler_ids(self.domain)),
            sorted([handler1._id, handler2._id]))

        # Add another with default type
        handler3 = CaseReminderHandler(
            domain=self.domain,
            reminder_type=REMINDER_TYPE_DEFAULT,
        )
        handler3.save()
        self.addCleanup(handler3.delete)

        self.assertEqual(
            sorted(
                CaseReminderHandler.get_handler_ids(
                    self.domain, reminder_type_filter=REMINDER_TYPE_DEFAULT)),
            sorted([handler1._id, handler3._id]))

        self.assertEqual(
            CaseReminderHandler.get_handler_ids(
                self.domain, reminder_type_filter=REMINDER_TYPE_ONE_TIME),
            [handler2._id])

        self.assertEqual(
            sorted(CaseReminderHandler.get_handler_ids(self.domain)),
            sorted([handler1._id, handler2._id, handler3._id]))

        # Retire the one-time reminder
        handler2.retire()

        self.assertEqual(
            sorted(
                CaseReminderHandler.get_handler_ids(
                    self.domain, reminder_type_filter=REMINDER_TYPE_DEFAULT)),
            sorted([handler1._id, handler3._id]))

        self.assertEqual(
            CaseReminderHandler.get_handler_ids(
                self.domain, reminder_type_filter=REMINDER_TYPE_ONE_TIME), [])

        self.assertEqual(
            sorted(CaseReminderHandler.get_handler_ids(self.domain)),
            sorted([handler1._id, handler3._id]))
    def test_host_case_owner_location(self):
        parent_location = SQLLocation.objects.create(
            domain=self.domain,
            name='parent test',
            site_code='parent',
            location_type=self.parent_location_type)
        self.addCleanup(parent_location.delete)

        child_location = SQLLocation.objects.create(
            domain=self.domain,
            name='child test',
            site_code='child',
            location_type=self.child_location_type,
            parent=parent_location)
        self.addCleanup(child_location.delete)

        with create_test_case(self.domain, 'test-extension-case',
                              'name') as extension_case:
            with create_test_case(self.domain, 'test-host-case',
                                  'name') as host_case:

                update_case(
                    self.domain,
                    host_case.case_id,
                    case_properties={'owner_id': child_location.location_id})
                set_parent_case(self.domain,
                                extension_case,
                                host_case,
                                relationship='extension')

                handler1 = CaseReminderHandler(
                    domain=self.domain, recipient='HOST_CASE_OWNER_LOCATION')
                handler2 = CaseReminderHandler(
                    domain=self.domain,
                    recipient='HOST_CASE_OWNER_LOCATION_PARENT')
                reminder = CaseReminder(domain=self.domain,
                                        case_id=extension_case.case_id)

                # Test the recipients are returned correctly
                with patch('corehq.apps.reminders.models.CaseReminder.handler',
                           new=handler1):
                    self.assertEqual(reminder.recipient, [child_location])

                with patch('corehq.apps.reminders.models.CaseReminder.handler',
                           new=handler2):
                    self.assertEqual(reminder.recipient, [parent_location])

                # Remove parent location reference
                child_location.parent = None
                child_location.save()
                with patch('corehq.apps.reminders.models.CaseReminder.handler',
                           new=handler2):
                    self.assertIsNone(reminder.recipient)

                # Test location that does not exist
                update_case(self.domain,
                            host_case.case_id,
                            case_properties={'owner_id': 'does-not-exist'})
                with patch('corehq.apps.reminders.models.CaseReminder.handler',
                           new=handler1):
                    self.assertIsNone(reminder.recipient)

                # Test on a case that is not an extension case
                reminder.case_id = host_case.case_id
                with patch('corehq.apps.reminders.models.CaseReminder.handler',
                           new=handler1):
                    self.assertIsNone(reminder.recipient)

                # Test on a blank case id
                reminder.case_id = None
                with patch('corehq.apps.reminders.models.CaseReminder.handler',
                           new=handler1):
                    self.assertIsNone(reminder.recipient)
Beispiel #39
0
 def reminder(self):
     return CaseReminderHandler.get(self.reminder_id)
Beispiel #40
0
    def save_copy(self, new_domain_name=None, user=None, ignore=None):
        from corehq.apps.app_manager.models import get_app
        from corehq.apps.reminders.models import CaseReminderHandler

        ignore = ignore if ignore is not None else []
        if new_domain_name is not None and Domain.get_by_name(new_domain_name):
            return None
        db = get_db()

        new_id = db.copy_doc(self.get_id)['id']
        if new_domain_name is None:
            new_domain_name = new_id
        new_domain = Domain.get(new_id)
        new_domain.name = new_domain_name
        new_domain.copy_history = self.get_updated_history()
        new_domain.is_snapshot = False
        new_domain.snapshot_time = None
        new_domain.organization = None  # TODO: use current user's organization (?)

        # reset stuff
        new_domain.cda.signed = False
        new_domain.cda.date = None
        new_domain.cda.type = None
        new_domain.cda.user_id = None
        new_domain.cda.user_ip = None
        new_domain.is_test = "none"
        new_domain.internal = InternalProperties()
        new_domain.creating_user = user.username if user else None

        for field in self._dirty_fields:
            if hasattr(new_domain, field):
                delattr(new_domain, field)

        new_comps = {}  # a mapping of component's id to it's copy
        for res in db.view('domain/related_to_domain', key=[self.name, True]):
            if not self.is_snapshot and res['value']['doc_type'] in (
                    'Application', 'RemoteApp'):
                app = get_app(self.name,
                              res['value']['_id']).get_latest_saved()
                if app:
                    comp = self.copy_component(app.doc_type,
                                               app._id,
                                               new_domain_name,
                                               user=user)
                else:
                    comp = self.copy_component(res['value']['doc_type'],
                                               res['value']['_id'],
                                               new_domain_name,
                                               user=user)
            elif res['value']['doc_type'] not in ignore:
                comp = self.copy_component(res['value']['doc_type'],
                                           res['value']['_id'],
                                           new_domain_name,
                                           user=user)
            else:
                comp = None
            if comp:
                new_comps[res['value']['_id']] = comp

        new_domain.save()

        if user:

            def add_dom_to_user(user):
                user.add_domain_membership(new_domain_name, is_admin=True)

            apply_update(user, add_dom_to_user)

        def update_events(handler):
            """
            Change the form_unique_id to the proper form for each event in a newly copied CaseReminderHandler
            """
            from corehq.apps.app_manager.models import FormBase
            for event in handler.events:
                if not event.form_unique_id:
                    continue
                form = FormBase.get_form(event.form_unique_id)
                form_app = form.get_app()
                m_index, f_index = form_app.get_form_location(form.unique_id)
                form_copy = new_comps[form_app._id].get_module(
                    m_index).get_form(f_index)
                event.form_unique_id = form_copy.unique_id

        def update_for_copy(handler):
            handler.active = False
            update_events(handler)

        if 'CaseReminderHandler' not in ignore:
            for handler in CaseReminderHandler.get_handlers(new_domain_name):
                apply_update(handler, update_for_copy)

        return new_domain
Beispiel #41
0
 def process_schedule_form(self):
     new_handler = CaseReminderHandler(use_today_if_start_date_is_blank=False)
     self.schedule_form.save(new_handler)