예제 #1
0
    def testSQLSyncToCouch(self):
        self.deleteAllLogs()
        self.assertEqual(self.getCouchCount(), 0)
        self.assertEqual(self.getSQLCount(), 0)

        # Test Create
        sql_obj = ExpectedCallback()
        self.setRandomSQLObjectValues(sql_obj)
        sql_obj.save()

        sleep(1)
        self.assertEqual(self.getCouchCount(), 1)
        self.assertEqual(self.getSQLCount(), 1)

        couch_obj = ExpectedCallbackEventLog.get(sql_obj.couch_id)
        self.checkFieldValues(couch_obj, sql_obj, ExpectedCallback._migration_get_fields())
        self.assertTrue(ExpectedCallbackEventLog.get_db().get_rev(couch_obj._id).startswith('2-'))

        # Test Update
        self.setRandomSQLObjectValues(sql_obj)
        sql_obj.save()

        sleep(1)
        self.assertEqual(self.getCouchCount(), 1)
        self.assertEqual(self.getSQLCount(), 1)
        couch_obj = ExpectedCallbackEventLog.get(sql_obj.couch_id)
        self.checkFieldValues(couch_obj, sql_obj, ExpectedCallback._migration_get_fields())
        self.assertTrue(ExpectedCallbackEventLog.get_db().get_rev(couch_obj._id).startswith('3-'))
예제 #2
0
def fire_sms_callback_event(reminder, handler, recipients, verified_numbers,
                            logged_event):
    current_event = reminder.current_event

    for recipient in recipients:
        send_message = False
        if reminder.callback_try_count > 0:
            if reminder.event_initiation_timestamp:
                event = ExpectedCallbackEventLog.view(
                    "sms/expected_callback_event",
                    key=[
                        reminder.domain,
                        json_format_datetime(
                            reminder.event_initiation_timestamp),
                        recipient.get_id
                    ],
                    include_docs=True,
                    limit=1).one()
                if not event:
                    continue
                if event.status == CALLBACK_RECEIVED:
                    continue
                if CallLog.inbound_entry_exists(
                        recipient.doc_type, recipient.get_id,
                        reminder.event_initiation_timestamp):
                    event.status = CALLBACK_RECEIVED
                    event.save()
                    continue
            else:
                continue

            if (reminder.callback_try_count >= len(
                    current_event.callback_timeout_intervals)):
                # On the last callback timeout, instead of sending the SMS
                # again, log the missed callback
                if event:
                    event.status = CALLBACK_MISSED
                    event.save()
            else:
                send_message = True
        else:
            # It's the first time sending the sms, so create an expected
            # callback event
            send_message = True
            event = ExpectedCallbackEventLog(
                domain=reminder.domain,
                date=reminder.event_initiation_timestamp,
                couch_recipient_doc_type=recipient.doc_type,
                couch_recipient=recipient.get_id,
                status=CALLBACK_PENDING,
            )
            event.save()

        if send_message:
            fire_sms_event(reminder,
                           handler, [recipient],
                           verified_numbers,
                           logged_event,
                           workflow=WORKFLOW_CALLBACK)
예제 #3
0
def fire_sms_callback_event(reminder, handler, recipients, verified_numbers):
    current_event = reminder.current_event
    if handler.recipient in [RECIPIENT_CASE, RECIPIENT_USER]:
        # If there are no recipients, just move to the next reminder event
        if len(recipients) == 0:
            return True

        # If the callback has been received, skip sending the next timeout message
        if reminder.callback_try_count > 0:
            # Lookup the expected callback event
            if reminder.event_initiation_timestamp is None:
                event = None
            else:
                event = ExpectedCallbackEventLog.view(
                    "sms/expected_callback_event",
                    key=[
                        reminder.domain,
                        json_format_datetime(
                            reminder.event_initiation_timestamp),
                        recipients[0].get_id
                    ],
                    include_docs=True,
                    limit=1).one()

            # NOTE: If last_fired is None, it means that the reminder fired for the first time on a timeout interval
            if reminder.last_fired is not None and CallLog.inbound_entry_exists(
                    recipients[0].doc_type, recipients[0].get_id,
                    reminder.last_fired):
                reminder.skip_remaining_timeouts = True
                if event is not None:
                    event.status = CALLBACK_RECEIVED
                    event.save()
                return True
            elif reminder.callback_try_count >= len(
                    current_event.callback_timeout_intervals):
                # On the last callback timeout, instead of sending the SMS again, log the missed callback
                if event is not None:
                    event.status = CALLBACK_MISSED
                    event.save()
                return True
        else:
            # It's the first time sending the sms, so create an expected callback event
            event = ExpectedCallbackEventLog(
                domain=reminder.domain,
                date=reminder.event_initiation_timestamp,
                couch_recipient_doc_type=recipients[0].doc_type,
                couch_recipient=recipients[0].get_id,
                status=CALLBACK_PENDING,
            )
            event.save()

        return fire_sms_event(reminder,
                              handler,
                              recipients,
                              verified_numbers,
                              workflow=WORKFLOW_CALLBACK)
    else:
        # TODO: Implement sms callback for RECIPIENT_OWNER and RECIPIENT_SURVEY_SAMPLE
        return False
예제 #4
0
def fire_sms_callback_event(reminder, handler, recipients, verified_numbers):
    current_event = reminder.current_event

    for recipient in recipients:
        send_message = False
        if reminder.callback_try_count > 0:
            if reminder.event_initiation_timestamp:
                event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                    key=[reminder.domain,
                         json_format_datetime(reminder.event_initiation_timestamp),
                         recipient.get_id],
                    include_docs=True,
                    limit=1).one()
                if not event:
                    continue
                if event.status == CALLBACK_RECEIVED:
                    continue
                if CallLog.inbound_entry_exists(recipient.doc_type,
                    recipient.get_id, reminder.event_initiation_timestamp):
                    event.status = CALLBACK_RECEIVED
                    event.save()
                    continue
            else:
                continue

            if (reminder.callback_try_count >=
                len(current_event.callback_timeout_intervals)):
                # On the last callback timeout, instead of sending the SMS
                # again, log the missed callback
                if event:
                    event.status = CALLBACK_MISSED
                    event.save()
            else:
                send_message = True
        else:
            # It's the first time sending the sms, so create an expected
            # callback event
            send_message = True
            event = ExpectedCallbackEventLog(
                domain=reminder.domain,
                date=reminder.event_initiation_timestamp,
                couch_recipient_doc_type=recipient.doc_type,
                couch_recipient=recipient.get_id,
                status=CALLBACK_PENDING,
            )
            event.save()

        if send_message:
            fire_sms_event(reminder, handler, [recipient], verified_numbers,
                workflow=WORKFLOW_CALLBACK)

    return True
예제 #5
0
def fire_sms_callback_event(reminder, handler, recipients, verified_numbers):
    current_event = reminder.current_event
    if handler.recipient in [RECIPIENT_CASE, RECIPIENT_USER]:
        # If there are no recipients, just move to the next reminder event
        if len(recipients) == 0:
            return True
        
        # If the callback has been received, skip sending the next timeout message
        if reminder.callback_try_count > 0:
            # Lookup the expected callback event
            if reminder.event_initiation_timestamp is None:
                event = None
            else:
                event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                                      key=[reminder.domain, json_format_datetime(reminder.event_initiation_timestamp), recipients[0].get_id],
                                                      include_docs=True,
                                                      limit=1).one()
            
            # NOTE: If last_fired is None, it means that the reminder fired for the first time on a timeout interval
            if reminder.last_fired is not None and CallLog.inbound_entry_exists(recipients[0].doc_type, recipients[0].get_id, reminder.last_fired):
                reminder.skip_remaining_timeouts = True
                if event is not None:
                    event.status = CALLBACK_RECEIVED
                    event.save()
                return True
            elif reminder.callback_try_count >= len(current_event.callback_timeout_intervals):
                # On the last callback timeout, instead of sending the SMS again, log the missed callback
                if event is not None:
                    event.status = CALLBACK_MISSED
                    event.save()
                return True
        else:
            # It's the first time sending the sms, so create an expected callback event
            event = ExpectedCallbackEventLog(
                domain                   = reminder.domain,
                date                     = reminder.event_initiation_timestamp,
                couch_recipient_doc_type = recipients[0].doc_type,
                couch_recipient          = recipients[0].get_id,
                status                   = CALLBACK_PENDING,
            )
            event.save()
        
        return fire_sms_event(reminder, handler, recipients, verified_numbers, workflow=WORKFLOW_CALLBACK)
    else:
        # TODO: Implement sms callback for RECIPIENT_OWNER and RECIPIENT_SURVEY_SAMPLE
        return False
예제 #6
0
 def getCouchCount(self):
     result = ExpectedCallbackEventLog.view(
         'sms/expected_callback_event',
         startkey=[self.domain],
         endkey=[self.domain, {}],
         include_docs=False,
     ).all()
     return len(result)
예제 #7
0
    def rows(self):
        startdate = json_format_datetime(self.datespan.startdate_utc)
        enddate = json_format_datetime(self.datespan.enddate_utc)
        data = ExpectedCallbackEventLog.by_domain(self.domain, startdate,
                                                  enddate)
        result = []

        status_descriptions = {
            CALLBACK_PENDING: _("Pending"),
            CALLBACK_RECEIVED: _("Received"),
            CALLBACK_MISSED: _("Missed"),
        }

        # Store the results of lookups for faster loading
        username_map = {}

        for event in data:
            recipient_id = event.couch_recipient
            if recipient_id in [None, ""]:
                username = "******"
            elif recipient_id in username_map:
                username = username_map.get(recipient_id)
            else:
                username = "******"
                try:
                    if event.couch_recipient_doc_type == "CommCareCase":
                        username = CommCareCase.get(recipient_id).name
                    else:
                        username = CouchUser.get_by_user_id(
                            recipient_id).username
                except Exception:
                    pass

                username_map[recipient_id] = username

            timestamp = tz_utils.adjust_datetime_to_timezone(
                event.date, pytz.utc.zone, self.timezone.zone)

            row = [
                self._fmt_timestamp(timestamp),
                self._fmt(username),
                self._fmt(status_descriptions.get(event.status, "-")),
            ]

            result.append(row)

        return result
예제 #8
0
파일: ivr.py 프로젝트: jmaina/commcare-hq
 def rows(self):
     startdate = json_format_datetime(self.datespan.startdate_utc)
     enddate = json_format_datetime(self.datespan.enddate_utc)
     data = ExpectedCallbackEventLog.by_domain(self.domain, startdate, enddate)
     result = []
     
     status_descriptions = {
         CALLBACK_PENDING : _("Pending"),
         CALLBACK_RECEIVED : _("Received"),
         CALLBACK_MISSED : _("Missed"),
     }
     
     # Store the results of lookups for faster loading
     username_map = {} 
     
     for event in data:
         recipient_id = event.couch_recipient
         if recipient_id in [None, ""]:
             username = "******"
         elif recipient_id in username_map:
             username = username_map.get(recipient_id)
         else:
             username = "******"
             try:
                 if event.couch_recipient_doc_type == "CommCareCase":
                     username = CommCareCase.get(recipient_id).name
                 else:
                     username = CouchUser.get_by_user_id(recipient_id).username
             except Exception:
                 pass
            
             username_map[recipient_id] = username
         
         timestamp = tz_utils.adjust_datetime_to_timezone(event.date, pytz.utc.zone, self.timezone.zone)
         
         row = [
             self._fmt_timestamp(timestamp),
             self._fmt(username),
             self._fmt(status_descriptions.get(event.status, "-")),
         ]
         
         result.append(row)
     
     return result
예제 #9
0
    def deleteAllLogs(self):
        for smslog in SMSLog.view(
            'sms/by_domain',
            startkey=[self.domain, 'SMSLog'],
            endkey=[self.domain, 'SMSLog', {}],
            include_docs=True,
            reduce=False,
        ).all():
            smslog.delete()

        for callog in CallLog.view(
            'sms/by_domain',
            startkey=[self.domain, 'CallLog'],
            endkey=[self.domain, 'CallLog', {}],
            include_docs=True,
            reduce=False,
        ).all():
            callog.delete()

        for obj in LastReadMessage.view(
            'sms/last_read_message',
            startkey=['by_anyone', self.domain],
            endkey=['by_anyone', self.domain, {}],
            include_docs=True,
        ).all():
            obj.delete()

        for obj in ExpectedCallbackEventLog.view(
            'sms/expected_callback_event',
            startkey=[self.domain],
            endkey=[self.domain, {}],
            include_docs=True,
        ).all():
            obj.delete()

        SMS.objects.filter(domain=self.domain).delete()
        Call.objects.filter(domain=self.domain).delete()
        MessagingSubEvent.objects.filter(parent__domain=self.domain).delete()
        MessagingEvent.objects.filter(domain=self.domain).delete()
        SQLLastReadMessage.objects.filter(domain=self.domain).delete()
        ExpectedCallback.objects.filter(domain=self.domain).delete()
    def delete_models(self, delete_interval):
        print 'Deleting SMSLogs...'
        count = iter_bulk_delete_with_doc_type_verification(SMSLog.get_db(), self.get_sms_couch_ids(), 'SMSLog',
            wait_time=delete_interval, max_fetch_attempts=5)
        print 'Deleted %s documents' % count

        print 'Deleting CallLogs...'
        count = iter_bulk_delete_with_doc_type_verification(CallLog.get_db(), self.get_call_couch_ids(), 'CallLog',
            wait_time=delete_interval, max_fetch_attempts=5)
        print 'Deleted %s documents' % count

        print 'Deleting ExpectedCallbackEventLogs...'
        count = iter_bulk_delete_with_doc_type_verification(ExpectedCallbackEventLog.get_db(),
            self.get_callback_couch_ids(), 'ExpectedCallbackEventLog', wait_time=delete_interval,
            max_fetch_attempts=5)
        print 'Deleted %s documents' % count

        print 'Deleting LastReadMessages...'
        count = iter_bulk_delete_with_doc_type_verification(LastReadMessage.get_db(),
            self.get_lastreadmessage_couch_ids(), 'LastReadMessage', wait_time=delete_interval,
            max_fetch_attempts=5)
        print 'Deleted %s documents' % count
예제 #11
0
    def delete_models(self, delete_interval):
        print('Deleting SMSLogs...')
        count = iter_bulk_delete_with_doc_type_verification(SMSLog.get_db(), self.get_sms_couch_ids(), 'SMSLog',
            wait_time=delete_interval, max_fetch_attempts=5)
        print('Deleted %s documents' % count)

        print('Deleting CallLogs...')
        count = iter_bulk_delete_with_doc_type_verification(CallLog.get_db(), self.get_call_couch_ids(), 'CallLog',
            wait_time=delete_interval, max_fetch_attempts=5)
        print('Deleted %s documents' % count)

        print('Deleting ExpectedCallbackEventLogs...')
        count = iter_bulk_delete_with_doc_type_verification(ExpectedCallbackEventLog.get_db(),
            self.get_callback_couch_ids(), 'ExpectedCallbackEventLog', wait_time=delete_interval,
            max_fetch_attempts=5)
        print('Deleted %s documents' % count)

        print('Deleting LastReadMessages...')
        count = iter_bulk_delete_with_doc_type_verification(LastReadMessage.get_db(),
            self.get_lastreadmessage_couch_ids(), 'LastReadMessage', wait_time=delete_interval,
            max_fetch_attempts=5)
        print('Deleted %s documents' % count)
예제 #12
0
 def get_callback_couch_ids(self):
     result = ExpectedCallbackEventLog.view(
         'sms/expected_callback_event',
         include_docs=False,
     ).all()
     return [row['id'] for row in result]
예제 #13
0
    def test_ok(self):
        self.assertEqual(self.handler.get_reminder(self.case), None)

        # Spawn CaseReminder
        CaseReminderHandler.now = datetime(year=2011, month=12, day=31, hour=23, minute=0)
        self.case.set_case_property('start_sending', 'ok')
        self.case.save()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=1, hour=7, minute=0))
        self.assertEqual(reminder.start_date, date(year=2012, month=1, day=1))
        self.assertEqual(reminder.schedule_iteration_num, 1)
        self.assertEqual(reminder.current_event_sequence_num, 0)
        self.assertEqual(reminder.last_fired, None)
        
        ######################
        # Day1, 10:00 reminder
        CaseReminderHandler.now = datetime(year=2012, month=1, day=1, hour=7, minute=0)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=1, hour=8, minute=0))
        self.assertEqual(reminder.schedule_iteration_num, 1)
        self.assertEqual(reminder.current_event_sequence_num, 1)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        
        # Day1, 11:00 reminder
        CaseReminderHandler.now = datetime(year=2012, month=1, day=1, hour=8, minute=1)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=1, hour=8, minute=15))
        self.assertEqual(reminder.schedule_iteration_num, 1)
        self.assertEqual(reminder.current_event_sequence_num, 1)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        
        event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                              key=["test", json_format_datetime(datetime(year=2012, month=1, day=1, hour=8, minute=1)), self.user_id],
                                              include_docs=True).one()
        self.assertNotEqual(event, None)
        self.assertEqual(event.status, CALLBACK_PENDING)
        
        # Create a callback
        c = CallLog(
            couch_recipient_doc_type    = "CommCareUser",
            couch_recipient             = self.user_id,
            phone_number                = "14445551234",
            direction                   = "I",
            date                        = datetime(year=2012, month=1, day=1, hour=8, minute=5)
        )
        c.save()

        # Day1, 11:15 timeout (should move on to next event)
        CaseReminderHandler.now = datetime(year=2012, month=1, day=1, hour=8, minute=15)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=1, hour=8, minute=45))
        self.assertEqual(reminder.schedule_iteration_num, 1)
        self.assertEqual(reminder.current_event_sequence_num, 1)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

        # Day1, 11:45 timeout (should move on to next event)
        CaseReminderHandler.now = datetime(year=2012, month=1, day=1, hour=8, minute=45)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=7, minute=0))
        self.assertEqual(reminder.schedule_iteration_num, 2)
        self.assertEqual(reminder.current_event_sequence_num, 0)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

        event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                              key=["test", json_format_datetime(datetime(year=2012, month=1, day=1, hour=8, minute=1)), self.user_id],
                                              include_docs=True).one()
        self.assertNotEqual(event, None)
        self.assertEqual(event.status, CALLBACK_RECEIVED)

        ######################
        # Day2, 10:00 reminder
        CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=7, minute=0)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=8, minute=0))
        self.assertEqual(reminder.schedule_iteration_num, 2)
        self.assertEqual(reminder.current_event_sequence_num, 1)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        
        # Day2, 11:00 reminder
        CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=8, minute=1)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=8, minute=15))
        self.assertEqual(reminder.schedule_iteration_num, 2)
        self.assertEqual(reminder.current_event_sequence_num, 1)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        
        event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                              key=["test", json_format_datetime(datetime(year=2012, month=1, day=2, hour=8, minute=1)), self.user_id],
                                              include_docs=True).one()
        self.assertNotEqual(event, None)
        self.assertEqual(event.status, CALLBACK_PENDING)
        
        # Day2, 11:15 timeout (should move on to next timeout)
        CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=8, minute=15)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=8, minute=45))
        self.assertEqual(reminder.schedule_iteration_num, 2)
        self.assertEqual(reminder.current_event_sequence_num, 1)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        
        event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                              key=["test", json_format_datetime(datetime(year=2012, month=1, day=2, hour=8, minute=1)), self.user_id],
                                              include_docs=True).one()
        self.assertNotEqual(event, None)
        self.assertEqual(event.status, CALLBACK_PENDING)
        
        # Day2, 11:45 timeout (should move on to next day)
        CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=8, minute=45)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=3, hour=7, minute=0))
        self.assertEqual(reminder.schedule_iteration_num, 3)
        self.assertEqual(reminder.current_event_sequence_num, 0)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        
        event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                              key=["test", json_format_datetime(datetime(year=2012, month=1, day=2, hour=8, minute=1)), self.user_id],
                                              include_docs=True).one()
        self.assertNotEqual(event, None)
        self.assertEqual(event.status, CALLBACK_MISSED)
        
        ######################
        # Day3, 10:00 reminder
        CaseReminderHandler.now = datetime(year=2012, month=1, day=3, hour=7, minute=0)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=3, hour=8, minute=0))
        self.assertEqual(reminder.schedule_iteration_num, 3)
        self.assertEqual(reminder.current_event_sequence_num, 1)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        
        # Day3, 11:00 reminder
        CaseReminderHandler.now = datetime(year=2012, month=1, day=3, hour=8, minute=1)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=3, hour=8, minute=15))
        self.assertEqual(reminder.schedule_iteration_num, 3)
        self.assertEqual(reminder.current_event_sequence_num, 1)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        
        event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                              key=["test", json_format_datetime(datetime(year=2012, month=1, day=3, hour=8, minute=1)), self.user_id],
                                              include_docs=True).one()
        self.assertNotEqual(event, None)
        self.assertEqual(event.status, CALLBACK_PENDING)
        
        # Day3, 11:15 timeout (should move on to next timeout)
        CaseReminderHandler.now = datetime(year=2012, month=1, day=3, hour=8, minute=15)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=3, hour=8, minute=45))
        self.assertEqual(reminder.schedule_iteration_num, 3)
        self.assertEqual(reminder.current_event_sequence_num, 1)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        
        event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                              key=["test", json_format_datetime(datetime(year=2012, month=1, day=3, hour=8, minute=1)), self.user_id],
                                              include_docs=True).one()
        self.assertNotEqual(event, None)
        self.assertEqual(event.status, CALLBACK_PENDING)
        
        # Create a callback (with phone_number missing country code)
        c = CallLog(
            couch_recipient_doc_type    = "CommCareUser",
            couch_recipient             = self.user_id,
            phone_number                = "4445551234",
            direction                   = "I",
            date                        = datetime(year=2012, month=1, day=3, hour=8, minute=22)
        )
        c.save()
        
        # Day3, 11:45 timeout (should deactivate the reminder)
        CaseReminderHandler.now = datetime(year=2012, month=1, day=3, hour=8, minute=45)
        CaseReminderHandler.fire_reminders()
        reminder = self.handler.get_reminder(self.case)
        self.assertNotEqual(reminder, None)
        self.assertEqual(reminder.schedule_iteration_num, 4)
        self.assertEqual(reminder.current_event_sequence_num, 0)
        self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
        self.assertEqual(reminder.active, False)
        
        event = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                              key=["test", json_format_datetime(datetime(year=2012, month=1, day=3, hour=8, minute=1)), self.user_id],
                                              include_docs=True).one()
        self.assertNotEqual(event, None)
        self.assertEqual(event.status, CALLBACK_RECEIVED)
 def get_callback_couch_ids(self):
     result = ExpectedCallbackEventLog.view(
         'sms/expected_callback_event',
         include_docs=False,
     ).all()
     return [row['id'] for row in result]
예제 #15
0
    def rows(self):
        group_id = None
        if self.request.couch_user.is_commcare_user():
            group_ids = self.request.couch_user.get_group_ids()
            if len(group_ids) > 0:
                group_id = group_ids[0]
        
        cases = CommCareCase.view("hqcase/types_by_domain",
                                  key=[self.domain, "participant"],
                                  reduce=False,
                                  include_docs=True).all()
        
        data = {}
        
        for case in cases:
            if case.closed:
                continue

            # If a site coordinator is viewing the report, only show participants from that site (group)
            if group_id is None or group_id == case.owner_id:
                data[case._id] = {
                    "name" : case.name,
                    "time_zone" : case.get_case_property("time_zone"),
                    "dates" : [None for x in range(14)],
                }
        
        dates = self.get_past_two_weeks()
        date_strings = [date.strftime("%Y-%m-%d") for date in dates]
        
        start_date = dates[0] - timedelta(days=1)
        end_date = dates[-1] + timedelta(days=2)
        
        start_utc_timestamp = json_format_datetime(start_date)
        end_utc_timestamp = json_format_datetime(end_date)
        
        expected_callback_events = ExpectedCallbackEventLog.view("sms/expected_callback_event",
                                                                 startkey=[self.domain, start_utc_timestamp],
                                                                 endkey=[self.domain, end_utc_timestamp],
                                                                 include_docs=True).all()
        
        for event in expected_callback_events:
            if event.couch_recipient in data:
                event_date = tz_utils.adjust_datetime_to_timezone(event.date, pytz.utc.zone, data[event.couch_recipient]["time_zone"]).date()
                event_date = event_date.strftime("%Y-%m-%d")
                if event_date in date_strings:
                    data[event.couch_recipient]["dates"][date_strings.index(event_date)] = event.status
        
        result = []
        for case_id, data_dict in data.items():
            row = [
                self._fmt(data_dict["name"]),
                None,
                None,
                None,
            ]
            
            total_no_response = 0
            total_indicated = 0
            total_pending = 0
            
            for date_status in data_dict["dates"]:
                if date_status == CALLBACK_PENDING:
                    total_indicated += 1
                    total_pending += 1
                    row.append(self._fmt(_("pending")))
                elif date_status == CALLBACK_RECEIVED:
                    total_indicated += 1
                    row.append(self._fmt(_("OK")))
                elif date_status == CALLBACK_MISSED:
                    total_indicated += 1
                    total_no_response += 1
                    row.append(self._fmt_highlight(_("No Response")))
                else:
                    row.append(self._fmt(_("not indicated")))
            
            if total_no_response > 0:
                row[1] = self._fmt_highlight(total_no_response)
            else:
                row[1] = self._fmt(total_no_response)
            row[2] = self._fmt(total_indicated)
            row[3] = self._fmt(total_pending)
            
            result.append(row)
        
        return result