Exemple #1
0
 def fire(self, reminder):
     """
     Sends the message associated with the given CaseReminder's current event.
     
     reminder    The CaseReminder which to fire.
     
     return      True on success, False on failure
     """
     # Get the proper recipient
     recipient = reminder.recipient
     
     # Retrieve the VerifiedNumber entry for the recipient
     try:
         verified_number = recipient.get_verified_number()
     except Exception:
         verified_number = None
         
     # Get the language of the recipient
     try:
         lang = recipient.get_language_code()
     except Exception:
         lang = None
     
     if reminder.method == "survey":
         # Close all currently open sessions
         sessions = XFormsSession.view("smsforms/open_sessions_by_connection",
                                      key=[reminder.domain, recipient.get_id],
                                      include_docs=True).all()
         for session in sessions:
             session.end(False)
             session.save()
         
         # Start the new session
         try:
             form_unique_id = reminder.current_event.form_unique_id
             form = Form.get_form(form_unique_id)
             app = form.get_app()
             module = form.get_module()
         except Exception as e:
             print e
             print "ERROR: Could not load survey form for handler " + reminder.handler_id + ", event " + str(reminder.current_event_sequence_num)
             return False
         session, responses = start_session(reminder.domain, recipient, app, module, form, reminder.case_id)
         
         # Send out first message
         if len(responses) > 0:
             message = format_message_list(responses)
             if verified_number is not None:
                 return send_sms_to_verified_number(verified_number, message)
             else:
                 return True
     else:
         # If it is a callback reminder and the callback has been received, skip sending the next timeout message
         if (reminder.method == "callback" or reminder.method == "callback_test") and len(reminder.current_event.callback_timeout_intervals) > 0 and (reminder.callback_try_count > 0):
             if CallLog.inbound_call_exists(recipient.doc_type, recipient._id, reminder.last_fired):
                 reminder.callback_received = True
                 return True
             elif len(reminder.current_event.callback_timeout_intervals) == reminder.callback_try_count:
                 # On the last callback timeout, instead of sending the SMS again, log the missed callback
                 event = EventLog(
                     domain          = reminder.domain,
                     date            = self.get_now(),
                     event_type      = MISSED_EXPECTED_CALLBACK
                 )
                 if verified_number is not None:
                     event.couch_recipient_doc_type = verified_number.owner_doc_type
                     event.couch_recipient = verified_number.owner_id
                 event.save()
                 return True
         reminder.last_fired = self.get_now()
         message = reminder.current_event.message.get(lang, reminder.current_event.message[self.default_lang])
         message = Message.render(message, case=reminder.case.case_properties())
         if reminder.method == "sms" or reminder.method == "callback":
             if verified_number is not None:
                 return send_sms_to_verified_number(verified_number, message)
             elif self.recipient == RECIPIENT_USER:
                 # If there is no verified number, but the recipient is a CommCareUser, still try to send it
                 try:
                     phone_number = reminder.user.phone_number
                 except Exception:
                     # If the user has no phone number, we cannot send any SMS
                     return False
                 return send_sms(reminder.domain, reminder.user_id, phone_number, message)
             else:
                 return False
         elif reminder.method == "test" or reminder.method == "callback_test":
             print(message)
             return True
Exemple #2
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)
        
        # 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 day)
        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=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, datetime(year=2012, month=1, day=1, hour=8, minute=1))
        
        ######################
        # 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)
        
        # 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)
        
        # 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, datetime(year=2012, month=1, day=2, hour=8, minute=15))
        
        # Ensure that a missed call was logged
        missed_call_datetime = json_format_datetime(CaseReminderHandler.now)
        missed_call = EventLog.view("sms/event_by_domain_date_recipient",
                        key=["test", missed_call_datetime, "CommCareUser", self.user_id],
                        include_docs=True).one()
        self.assertNotEqual(missed_call, None)
        self.assertEqual(missed_call.event_type, MISSED_EXPECTED_CALLBACK)
        
        ######################
        # 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)
        
        # 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)
        
        # 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, datetime(year=2012, month=1, day=3, hour=8, minute=15))
        self.assertEqual(reminder.active, False)