コード例 #1
0
    def test_recalculate_schedule(self, utcnow_patch, send_patch):
        self.assertNumInstancesForSchedule(0)

        # Schedule the instance
        utcnow_patch.return_value = datetime(2017, 4, 15, 6, 0)
        refresh_timed_schedule_instances(self.schedule, (('CommCareUser', self.user1.get_id),), date(2017, 4, 15))
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertTimedScheduleInstance(instance, 1, 1, datetime(2017, 4, 15, 16, 0), True, date(2017, 4, 15))
        self.assertEqual(send_patch.call_count, 0)

        # Set start date in previous month
        refresh_timed_schedule_instances(self.schedule, (('CommCareUser', self.user1.get_id),), date(2017, 3, 14))
        old_id = instance.schedule_instance_id
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertEqual(instance.schedule_instance_id, old_id)
        self.assertTimedScheduleInstance(instance, 1, 2, datetime(2017, 4, 15, 16, 0), True, date(2017, 3, 14))
        self.assertEqual(send_patch.call_count, 0)

        # Set start date two months back
        refresh_timed_schedule_instances(self.schedule, (('CommCareUser', self.user1.get_id),), date(2017, 2, 1))
        old_id = instance.schedule_instance_id
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertEqual(instance.schedule_instance_id, old_id)
        self.assertTimedScheduleInstance(instance, 0, 3, datetime(2017, 4, 1, 16, 0), False, date(2017, 2, 1))
        self.assertEqual(send_patch.call_count, 0)
コード例 #2
0
    def test_keep_in_sync_with_recipients(self, utcnow_patch, send_patch):
        self.assertNumInstancesForSchedule(0)

        # Schedule the instance for user1
        utcnow_patch.return_value = datetime(2017, 3, 16, 6, 0)
        refresh_timed_schedule_instances(
            self.schedule, (('CommCareUser', self.user1.get_id), ),
            date(2017, 3, 16))
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertTimedScheduleInstance(instance, 0, 1,
                                         datetime(2017, 3, 16, 16, 0), True,
                                         date(2017, 3, 16), self.user1)

        # Add user2
        refresh_timed_schedule_instances(self.schedule,
                                         (('CommCareUser', self.user1.get_id),
                                          ('CommCareUser', self.user2.get_id)),
                                         date(2017, 3, 16))

        self.assertNumInstancesForSchedule(2)
        [instance1,
         instance2] = get_timed_schedule_instances_for_schedule(self.schedule)
        if instance1.recipient_id == self.user1.get_id:
            user1_instance = instance1
            user2_instance = instance2
        else:
            user1_instance = instance2
            user2_instance = instance1

        self.assertTimedScheduleInstance(user1_instance, 0, 1,
                                         datetime(2017, 3, 16, 16, 0), True,
                                         date(2017, 3, 16), self.user1)
        self.assertTimedScheduleInstance(user2_instance, 0, 1,
                                         datetime(2017, 3, 16, 16, 0), True,
                                         date(2017, 3, 16), self.user2)

        # Remove user1
        refresh_timed_schedule_instances(
            self.schedule, (('CommCareUser', self.user2.get_id), ),
            date(2017, 3, 16))
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertTimedScheduleInstance(instance, 0, 1,
                                         datetime(2017, 3, 16, 16, 0), True,
                                         date(2017, 3, 16), self.user2)

        self.assertEqual(send_patch.call_count, 0)
コード例 #3
0
    def test_schedule_start_to_finish(self, utcnow_patch, send_patch):
        self.assertNumInstancesForSchedule(0)

        # Schedule the instance using an explicit start date (a Sunday)
        # Based on the schedule (with start offset 3) we should start sending on the next Monday
        utcnow_patch.return_value = datetime(2017, 8, 2, 7, 0)
        refresh_timed_schedule_instances(
            self.schedule, (('CommCareUser', self.user1.get_id), ),
            date(2017, 8, 6))
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertTimedScheduleInstance(instance, 0, 1,
                                         datetime(2017, 8, 14, 16, 0), True,
                                         date(2017, 8, 6), self.user1)
        self.assertEqual(send_patch.call_count, 0)

        # Send first event
        utcnow_patch.return_value = datetime(2017, 8, 14, 16, 1)
        instance.handle_current_event()
        save_timed_schedule_instance(instance)
        self.assertNumInstancesForSchedule(1)
        self.assertTimedScheduleInstance(instance, 0, 2,
                                         datetime(2017, 8, 15, 16, 0), True,
                                         date(2017, 8, 6), self.user1)
        self.assertEqual(send_patch.call_count, 1)

        # Send second (and final) event
        utcnow_patch.return_value = datetime(2017, 8, 15, 16, 1)
        instance.handle_current_event()
        save_timed_schedule_instance(instance)
        self.assertNumInstancesForSchedule(1)
        self.assertTimedScheduleInstance(instance, 0, 3,
                                         datetime(2017, 8, 16, 16, 0), False,
                                         date(2017, 8, 6), self.user1)
        self.assertEqual(send_patch.call_count, 2)
コード例 #4
0
    def test_schedule_start_to_finish(self, utcnow_patch, send_patch):
        self.assertNumInstancesForSchedule(0)

        # Schedule the instance
        utcnow_patch.return_value = datetime(2017, 3, 16, 6, 0)
        refresh_timed_schedule_instances(self.schedule, (('CommCareUser', self.user1.get_id),), date(2017, 3, 16))
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertTimedScheduleInstance(instance, 0, 1, datetime(2017, 3, 16, 16, 0), True, date(2017, 3, 16),
            self.user1)
        self.assertEqual(send_patch.call_count, 0)

        # Send first event
        utcnow_patch.return_value = datetime(2017, 3, 16, 16, 1)
        instance.handle_current_event()
        save_timed_schedule_instance(instance)
        self.assertNumInstancesForSchedule(1)
        self.assertTimedScheduleInstance(instance, 0, 2, datetime(2017, 3, 17, 16, 0), True, date(2017, 3, 16),
            self.user1)
        self.assertEqual(send_patch.call_count, 1)

        # Send second (and final) event
        utcnow_patch.return_value = datetime(2017, 3, 17, 16, 1)
        instance.handle_current_event()
        save_timed_schedule_instance(instance)
        self.assertNumInstancesForSchedule(1)
        self.assertTimedScheduleInstance(instance, 0, 3, datetime(2017, 3, 18, 16, 0), False, date(2017, 3, 16),
            self.user1)
        self.assertEqual(send_patch.call_count, 2)
コード例 #5
0
def refresh_timed_schedule_instances(schedule, recipients, start_date=None):
    """
    :param schedule: the TimedSchedule
    :param start_date: the date to start the TimedSchedule
    :param recipients: a list of (recipient_type, recipient_id) tuples; the
    recipient type should be one of the values checked in ScheduleInstance.recipient
    """

    existing_instances = {
        (instance.recipient_type, instance.recipient_id): instance
        for instance in get_timed_schedule_instances_for_schedule(schedule)
    }

    recipients = convert_to_tuple_of_tuples(recipients)
    new_recipients = set(recipients)

    for recipient_type, recipient_id in new_recipients:
        if (recipient_type, recipient_id) not in existing_instances:
            instance = TimedScheduleInstance.create_for_recipient(
                schedule,
                recipient_type,
                recipient_id,
                start_date=start_date,
                move_to_next_event_not_in_the_past=True,
            )
            save_timed_schedule_instance(instance)

    for key, schedule_instance in existing_instances.iteritems():
        if key not in new_recipients:
            delete_timed_schedule_instance(schedule_instance)
        elif start_date and start_date != schedule_instance.start_date:
            schedule_instance.recalculate_schedule(schedule, new_start_date=start_date)
            save_timed_schedule_instance(schedule_instance)
コード例 #6
0
    def test_setting_first_event_for_today_when_time_has_not_yet_passed(
            self, utcnow_patch, send_patch):
        self.assertNumInstancesForSchedule(0)

        # Schedule the instance using "today's date" (Monday) as the start date.
        # Since the time has not yet passed for today's event, we schedule it for today.
        utcnow_patch.return_value = datetime(2017, 8, 7, 7, 0)
        refresh_timed_schedule_instances(
            self.schedule, (('CommCareUser', self.user1.get_id), ))
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertTimedScheduleInstance(instance, 0, 1,
                                         datetime(2017, 8, 7, 16, 0), True,
                                         date(2017, 8, 7), self.user1)
        self.assertEqual(send_patch.call_count, 0)
コード例 #7
0
    def test_setting_first_event_for_next_monday(self, utcnow_patch,
                                                 send_patch):
        self.assertNumInstancesForSchedule(0)

        # Schedule the instance using "today's date" (a Wednesday) as a start date.
        # Based on the schedule we should start sending on the next Monday
        utcnow_patch.return_value = datetime(2017, 8, 9, 7, 0)
        refresh_timed_schedule_instances(
            self.schedule, (('CommCareUser', self.user1.get_id), ))
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertTimedScheduleInstance(instance, 0, 1,
                                         datetime(2017, 8, 14, 16, 0), True,
                                         date(2017, 8, 9), self.user1)
        self.assertEqual(send_patch.call_count, 0)
コード例 #8
0
ファイル: tasks.py プロジェクト: dimagi/commcare-hq
def refresh_timed_schedule_instances(schedule_id, recipients, start_date=None):
    """
    :param schedule_id: the TimedSchedule schedule_id
    :param start_date: the date to start the TimedSchedule
    :param recipients: a list of (recipient_type, recipient_id) tuples; the
    recipient type should be one of the values checked in ScheduleInstance.recipient
    """
    with CriticalSection(['refresh-timed-schedule-instances-for-%s' % schedule_id.hex], timeout=5 * 60):
        schedule = TimedSchedule.objects.get(schedule_id=schedule_id)
        TimedScheduleInstanceRefresher(
            schedule,
            recipients,
            get_timed_schedule_instances_for_schedule(schedule),
            start_date=start_date
        ).refresh()
コード例 #9
0
def refresh_timed_schedule_instances(schedule_id, recipients, start_date=None):
    """
    :param schedule_id: the TimedSchedule schedule_id
    :param start_date: the date to start the TimedSchedule
    :param recipients: a list of (recipient_type, recipient_id) tuples; the
    recipient type should be one of the values checked in ScheduleInstance.recipient
    """
    with CriticalSection(
        ['refresh-timed-schedule-instances-for-%s' % schedule_id.hex],
            timeout=5 * 60):
        schedule = TimedSchedule.objects.get(schedule_id=schedule_id)
        TimedScheduleInstanceRefresher(
            schedule,
            recipients,
            get_timed_schedule_instances_for_schedule(schedule),
            start_date=start_date).refresh()
コード例 #10
0
    def test_setting_first_event_using_explicit_start_date(
            self, utcnow_patch, send_patch):
        self.assertNumInstancesForSchedule(0)

        # Schedule the instance using an explicit start date (a Thursday).
        # Based on the schedule we should start sending on the next Monday
        utcnow_patch.return_value = datetime(2017, 8, 2, 7, 0)
        refresh_timed_schedule_instances(
            self.schedule, (('CommCareUser', self.user1.get_id), ),
            date(2017, 8, 3))
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertTimedScheduleInstance(instance, 0, 1,
                                         datetime(2017, 8, 7, 16, 0), True,
                                         date(2017, 8, 3), self.user1)
        self.assertEqual(send_patch.call_count, 0)
コード例 #11
0
    def test_setting_first_event_for_past_schedule(self, utcnow_patch,
                                                   send_patch):
        self.assertNumInstancesForSchedule(0)

        # Schedule the instance using an explicit start date in the past.
        # Since the date is so far back, the schedule is automatically deactivated.
        utcnow_patch.return_value = datetime(2017, 8, 9, 7, 0)
        refresh_timed_schedule_instances(
            self.schedule, (('CommCareUser', self.user1.get_id), ),
            date(2017, 7, 1))
        self.assertNumInstancesForSchedule(1)
        [instance] = get_timed_schedule_instances_for_schedule(self.schedule)
        self.assertTimedScheduleInstance(instance, 0, 3,
                                         datetime(2017, 7, 5, 16, 0), False,
                                         date(2017, 7, 1), self.user1)
        self.assertEqual(send_patch.call_count, 0)
コード例 #12
0
def refresh_timed_schedule_instances(schedule_id,
                                     recipients,
                                     start_date_iso_string=None):
    """
    :param schedule_id: type str that is hex representation of the TimedSchedule schedule_id (UUID)
    :param recipients: a list of (recipient_type, recipient_id) tuples; the
    recipient type should be one of the values checked in ScheduleInstance.recipient
    :param start_date_iso_string: the date to start the TimedSchedule formatted as an iso string
    """
    schedule_uuid = uuid.UUID(schedule_id)
    start_date = iso_string_to_date(
        start_date_iso_string) if start_date_iso_string else None
    with CriticalSection(
        ['refresh-timed-schedule-instances-for-%s' % schedule_uuid.hex],
            timeout=5 * 60):
        schedule = TimedSchedule.objects.get(schedule_id=schedule_uuid)
        TimedScheduleInstanceRefresher(
            schedule,
            recipients,
            get_timed_schedule_instances_for_schedule(schedule),
            start_date=start_date).refresh()
コード例 #13
0
 def test_get_timed_schedule_instances_for_schedule(self):
     self.assertEqual(
         set(
             get_timed_schedule_instances_for_schedule(
                 TimedSchedule(schedule_id=self.schedule_id2))),
         set([self.timed_instance2, self.timed_instance3]))
コード例 #14
0
 def test_get_timed_schedule_instances_for_schedule(self):
     self.assertItemsEqual(
         get_timed_schedule_instances_for_schedule(
             TimedSchedule(schedule_id=self.schedule_id2)),
         [self.timed_instance2_p1, self.timed_instance3_p2])
コード例 #15
0
 def assertNumInstancesForSchedule(self, num):
     self.assertEqual(len(list(get_timed_schedule_instances_for_schedule(self.schedule))), num)
コード例 #16
0
 def tearDown(self):
     for instance in get_timed_schedule_instances_for_schedule(self.schedule):
         delete_timed_schedule_instance(instance)
コード例 #17
0
 def test_get_timed_schedule_instances_for_schedule(self):
     self.assertItemsEqual(
         get_timed_schedule_instances_for_schedule(TimedSchedule(schedule_id=self.schedule_id2)),
         [self.timed_instance2_p1, self.timed_instance3_p2]
     )