Пример #1
0
    def test_reminder_delete(self):
        reminder = (CaseReminderHandler
            .create(self.domain, 'test')
            .set_case_criteria_start_condition('participant', 'status', MATCH_EXACT, 'green')
            .set_case_criteria_start_date()
            .set_case_recipient()
            .set_sms_content_type('en')
            .set_daily_schedule(fire_time=time(12, 0),
                message={'en': 'Hello {case.name}, your test result was normal.'})
            .set_stop_condition(max_iteration_count=REPEAT_SCHEDULE_INDEFINITELY)
            .set_advanced_options())
        reminder.save()

        r1 = CaseReminder(domain=self.domain, handler_id=reminder.get_id)
        r2 = CaseReminder(domain=self.domain, handler_id='abc')
        r3 = CaseReminder(domain='def', handler_id='ghi')

        r1.save()
        r2.save()
        r3.save()

        self.assertEqual(len(self.get_all_reminders()), 3)
        reminder.retire()
        self.assertEqual(len(self.get_all_reminders()), 2)

        r1 = CaseReminder.get(r1.get_id)
        r2 = CaseReminder.get(r2.get_id)
        r3 = CaseReminder.get(r3.get_id)

        self.assertEqual(r1.doc_type, 'CaseReminder-Deleted')
        self.assertEqual(r2.doc_type, 'CaseReminder')
        self.assertEqual(r3.doc_type, 'CaseReminder')
Пример #2
0
    def test_reminder_delete(self):
        reminder = (CaseReminderHandler
            .create(self.domain, 'test')
            .set_case_criteria_start_condition('participant', 'status', MATCH_EXACT, 'green')
            .set_case_criteria_start_date()
            .set_case_recipient()
            .set_sms_content_type('en')
            .set_daily_schedule(fire_time=time(12, 0),
                message={'en': 'Hello {case.name}, your test result was normal.'})
            .set_stop_condition(max_iteration_count=REPEAT_SCHEDULE_INDEFINITELY)
            .set_advanced_options())
        reminder.save()

        r1 = CaseReminder(domain=self.domain, handler_id=reminder.get_id)
        r2 = CaseReminder(domain=self.domain, handler_id='abc')
        r3 = CaseReminder(domain='def', handler_id='ghi')

        r1.save()
        r2.save()
        r3.save()

        self.assertEqual(len(self.get_all_reminders()), 3)
        reminder.retire()
        self.assertEqual(len(self.get_all_reminders()), 2)

        r1 = CaseReminder.get(r1.get_id)
        r2 = CaseReminder.get(r2.get_id)
        r3 = CaseReminder.get(r3.get_id)

        self.assertEqual(r1.doc_type, 'CaseReminder-Deleted')
        self.assertEqual(r2.doc_type, 'CaseReminder')
        self.assertEqual(r3.doc_type, 'CaseReminder')
Пример #3
0
def get_reminder_domain(reminder_id):
    """
    A reminder instance's domain should never change once set, so
    we can use a very long timeout.
    """
    from corehq.apps.reminders.models import CaseReminder
    return CaseReminder.get(reminder_id).domain
Пример #4
0
def get_reminder_domain(reminder_id):
    """
    A reminder instance's domain should never change once set, so
    we can use a very long timeout.
    """
    from corehq.apps.reminders.models import CaseReminder
    return CaseReminder.get(reminder_id).domain
Пример #5
0
def _fire_reminder(reminder_id):
    utcnow = datetime.utcnow()
    reminder = CaseReminder.get(reminder_id)
    # This key prevents doc update conflicts with rule running
    key = "rule-update-definition-%s-case-%s" % (reminder.handler_id, reminder.case_id)
    with CriticalSection([key], timeout=(settings.REMINDERS_QUEUE_PROCESSING_LOCK_TIMEOUT * 60)):
        # Refresh the reminder
        reminder = CaseReminder.get(reminder_id)
        if not reminder.retired and reminder.active and utcnow >= reminder.next_fire:
            handler = reminder.handler
            if reminder_is_stale(reminder, utcnow):
                handler.set_next_fire(reminder, utcnow)
                reminder.save()
                return
            if handler.fire(reminder):
                handler.set_next_fire(reminder, utcnow)
                reminder.save()
Пример #6
0
def reminders_in_error(request, domain):
    handler_map = {}
    if request.method == "POST":
        form = RemindersInErrorForm(request.POST)
        if form.is_valid():
            kwargs = {}
            if is_bigcouch():
                # Force a write to all nodes before returning
                kwargs["w"] = bigcouch_quorum_count()
            current_timestamp = datetime.utcnow()
            for reminder_id in form.cleaned_data.get("selected_reminders"):
                reminder = CaseReminder.get(reminder_id)
                if reminder.domain != domain:
                    continue
                if reminder.handler_id in handler_map:
                    handler = handler_map[reminder.handler_id]
                else:
                    handler = reminder.handler
                    handler_map[reminder.handler_id] = handler
                reminder.error = False
                reminder.error_msg = None
                handler.set_next_fire(reminder, current_timestamp)
                reminder.save(**kwargs)

    timezone = report_utils.get_timezone(request.couch_user.user_id, domain)
    reminders = []
    for reminder in CaseReminder.view("reminders/reminders_in_error",
                                      startkey=[domain],
                                      endkey=[domain, {}],
                                      include_docs=True).all():
        if reminder.handler_id in handler_map:
            handler = handler_map[reminder.handler_id]
        else:
            handler = reminder.handler
            handler_map[reminder.handler_id] = handler
        recipient = reminder.recipient
        case = reminder.case
        reminders.append({
            "reminder_id":
            reminder._id,
            "handler_id":
            reminder.handler_id,
            "handler_name":
            handler.nickname,
            "case_id":
            case.get_id if case is not None else None,
            "case_name":
            case.name if case is not None else None,
            "next_fire":
            tz_utils.adjust_datetime_to_timezone(
                reminder.next_fire, pytz.utc.zone,
                timezone.zone).strftime("%Y-%m-%d %H:%M:%S"),
            "error_msg":
            reminder.error_msg,
            "recipient_name":
            get_recipient_name(recipient),
        })
Пример #7
0
def _fire_reminder(reminder_id):
    utcnow = datetime.utcnow()
    reminder = CaseReminder.get(reminder_id)
    # This key prevents doc update conflicts with rule running
    key = "rule-update-definition-%s-case-%s" % (reminder.handler_id, reminder.case_id)
    with CriticalSection([key],
        timeout=(settings.REMINDERS_QUEUE_PROCESSING_LOCK_TIMEOUT*60)):
        # Refresh the reminder
        reminder = CaseReminder.get(reminder_id)
        if (not reminder.retired and reminder.active
            and utcnow >= reminder.next_fire):
            handler = reminder.handler
            if reminder_is_stale(reminder, utcnow):
                handler.set_next_fire(reminder, utcnow)
                reminder.save()
                return
            if handler.fire(reminder):
                handler.set_next_fire(reminder, utcnow)
                reminder.save()
Пример #8
0
def reminders_in_error(request, domain):
    handler_map = {}
    if request.method == "POST":
        form = RemindersInErrorForm(request.POST)
        if form.is_valid():
            kwargs = {}
            if is_bigcouch():
                # Force a write to all nodes before returning
                kwargs["w"] = bigcouch_quorum_count()
            current_timestamp = datetime.utcnow()
            for reminder_id in form.cleaned_data.get("selected_reminders"):
                reminder = CaseReminder.get(reminder_id)
                if reminder.domain != domain:
                    continue
                if reminder.handler_id in handler_map:
                    handler = handler_map[reminder.handler_id]
                else:
                    handler = reminder.handler
                    handler_map[reminder.handler_id] = handler
                reminder.error = False
                reminder.error_msg = None
                handler.set_next_fire(reminder, current_timestamp)
                reminder.save(**kwargs)
    
    timezone = report_utils.get_timezone(request.couch_user.user_id, domain)
    reminders = []
    for reminder in CaseReminder.view("reminders/reminders_in_error", startkey=[domain], endkey=[domain, {}], include_docs=True).all():
        if reminder.handler_id in handler_map:
            handler = handler_map[reminder.handler_id]
        else:
            handler = reminder.handler
            handler_map[reminder.handler_id] = handler
        recipient = reminder.recipient
        case = reminder.case
        reminders.append({
            "reminder_id" : reminder._id,
            "handler_id" : reminder.handler_id,
            "handler_name" : handler.nickname,
            "case_id" : case.get_id if case is not None else None,
            "case_name" : case.name if case is not None else None,
            "next_fire" : tz_utils.adjust_datetime_to_timezone(reminder.next_fire, pytz.utc.zone, timezone.zone).strftime("%Y-%m-%d %H:%M:%S"),
            "error_msg" : reminder.error_msg,
            "recipient_name" : get_recipient_name(recipient),
        })
    context = {
        "domain" : domain,
        "reminders" : reminders,
        "timezone" : timezone,
        "timezone_now" : datetime.now(tz=timezone),
    }
    return render(request, "reminders/partial/reminders_in_error.html", context)
Пример #9
0
    def handle(self, **options):
        num_dups = 0
        make_fixes = options["fix"]
        ids = {}
        rows = CaseReminder.view("reminders/by_domain_handler_case",
                                 include_docs=False).all()

        for row in rows:
            row_key = row["key"]
            if row_key[2]:
                ids_key = "|".join(row_key)
                if ids_key in ids:
                    ids[ids_key].append(row["id"])
                else:
                    ids[ids_key] = [row["id"]]

        for k, v in ids.items():
            if len(v) > 1:
                num_dups += 1
                split_key = k.split("|")
                print("Duplicate found: ", split_key)

                handler = CaseReminderHandler.get(split_key[1])
                if handler.start_condition_type != CASE_CRITERIA:
                    print("ERROR: Duplicate with the above key is not a case "
                          "criteria reminder")
                    continue

                all_match = True
                reminders = [CaseReminder.get(i) for i in v]
                for r in reminders[1:]:
                    all_match = all_match and self.reminders_match(
                        reminders[0], r)
                if all_match:
                    if make_fixes:
                        print("Removing duplicate(s)...")
                        for r in reminders[1:]:
                            r.retire()
                        c = CommCareCase.get(split_key[2])
                        messaging_case_changed_receiver(None, c)
                else:
                    print(
                        "ERROR: Not all of the reminders with the above key match"
                    )

        print("%s Duplicate(s) were found" % num_dups)
    def handle(self, *args, **options):
        num_dups = 0
        make_fixes = options["fix"]
        ids = {}
        rows = CaseReminder.view("reminders/by_domain_handler_case",
            include_docs=False).all()

        for row in rows:
            row_key = row["key"]
            if row_key[2]:
                ids_key = "|".join(row_key)
                if ids_key in ids:
                    ids[ids_key].append(row["id"])
                else:
                    ids[ids_key] = [row["id"]]

        for k, v in ids.items():
            if len(v) > 1:
                num_dups += 1
                split_key = k.split("|")
                print "Duplicate found: ", split_key

                handler = CaseReminderHandler.get(split_key[1])
                if handler.start_condition_type != CASE_CRITERIA:
                    print ("ERROR: Duplicate with the above key is not a case "
                        "criteria reminder")
                    continue

                all_match = True
                reminders = [CaseReminder.get(i) for i in v]
                for r in reminders[1:]:
                    all_match = all_match and self.reminders_match(reminders[0], r)
                if all_match:
                    if make_fixes:
                        print "Removing duplicate(s)..."
                        for r in reminders[1:]:
                            r.retire()
                        c = CommCareCase.get(split_key[2])
                        case_changed_receiver(None, c)
                else:
                    print "ERROR: Not all of the reminders with the above key match"

        print "%s Duplicate(s) were found" % num_dups
Пример #11
0
    def test_ok(self):
        with create_test_case(self.domain,
                              'case_type_a',
                              'test-case',
                              drop_signals=False,
                              user_id=self.user.get_id) as case:

            # Test changing a start condition which is a string
            # Spawn the reminder with an "ok" start condition value
            CaseReminderHandler.now = datetime(year=2012,
                                               month=2,
                                               day=17,
                                               hour=12,
                                               minute=0)
            self.assertIsNone(self.handler1.get_reminder(case))

            update_case(self.domain,
                        case.case_id, {'start_sending1': 'ok'},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(
                reminder.next_fire, CaseReminderHandler.now +
                timedelta(days=self.handler1.start_offset))

            # Test that saving the case without changing the start condition has no effect
            old_reminder_id = reminder.get_id
            update_case(self.domain,
                        case.case_id, {'case_property1': 'abc'},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.get_id, old_reminder_id)

            # Test retiring the reminder
            old_reminder_id = reminder.get_id
            update_case(self.domain,
                        case.case_id, {'start_sending1': ''},
                        user_id=self.user.get_id)

            self.assertIsNone(self.handler1.get_reminder(case))
            self.assertEqual(
                CaseReminder.get(old_reminder_id).doc_type,
                "CaseReminder-Deleted")

            # Test changing a start condition which is a date value
            # Spawn the reminder with date start condition value
            update_case(self.domain,
                        case.case_id, {'start_sending1': '2012-02-20'},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)

            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 20) +
                timedelta(days=self.handler1.start_offset))

            # Reset the date start condition
            old_reminder_id = reminder.get_id
            update_case(self.domain,
                        case.case_id, {'start_sending1': '2012-02-22'},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 22) +
                timedelta(days=self.handler1.start_offset))
            self.assertEqual(
                CaseReminder.get(old_reminder_id).doc_type,
                "CaseReminder-Deleted")

            # Test that saving the case without changing the start condition has no effect
            old_reminder_id = reminder.get_id
            update_case(self.domain,
                        case.case_id, {'case_property1': 'abc'},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.get_id, old_reminder_id)

            # Retire the reminder
            old_reminder_id = reminder.get_id
            update_case(self.domain,
                        case.case_id, {'start_sending1': ''},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNone(reminder)
            self.assertEqual(
                CaseReminder.get(old_reminder_id).doc_type,
                "CaseReminder-Deleted")

            # Test changing a start condition which is a string representation of a datetime value
            # Spawn the reminder with datetime start condition value
            update_case(self.domain,
                        case.case_id, {'start_sending1': '2012-02-25 11:15'},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)

            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 25, 11, 15) +
                timedelta(days=self.handler1.start_offset))

            # Reset the datetime start condition
            old_reminder_id = reminder.get_id
            update_case(self.domain,
                        case.case_id, {'start_sending1': '2012-02-26 11:20'},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)

            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 26, 11, 20) +
                timedelta(days=self.handler1.start_offset))
            self.assertEqual(
                CaseReminder.get(old_reminder_id).doc_type,
                "CaseReminder-Deleted")

            # Test that saving the case without changing the start condition has no effect
            old_reminder_id = reminder.get_id
            update_case(self.domain,
                        case.case_id, {'case_property1': 'xyz'},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.get_id, old_reminder_id)

            # Retire the reminder
            old_reminder_id = reminder.get_id
            update_case(self.domain,
                        case.case_id, {'start_sending1': ''},
                        user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNone(reminder)
            self.assertEqual(
                CaseReminder.get(old_reminder_id).doc_type,
                "CaseReminder-Deleted")
Пример #12
0
    def test_ok(self):
        with create_test_case(self.domain, 'case_type_a', 'test-case', drop_signals=False,
                user_id=self.user.get_id) as case:

            # Test changing a start condition which is a string
            # Spawn the reminder with an "ok" start condition value
            CaseReminderHandler.now = datetime(year=2012, month=2, day=17, hour=12, minute=0)
            self.assertIsNone(self.handler1.get_reminder(case))

            update_case(self.domain, case.case_id, {'start_sending1': 'ok'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(
                reminder.next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler1.start_offset)
            )

            # Test that saving the case without changing the start condition has no effect
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'case_property1': 'abc'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.get_id, old_reminder_id)

            # Test retiring the reminder
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': ''}, user_id=self.user.get_id)

            self.assertIsNone(self.handler1.get_reminder(case))
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")

            # Test changing a start condition which is a date value
            # Spawn the reminder with date start condition value
            update_case(self.domain, case.case_id, {'start_sending1': '2012-02-20'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)

            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 20) + timedelta(days=self.handler1.start_offset)
            )

            # Reset the date start condition
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': '2012-02-22'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 22) + timedelta(days=self.handler1.start_offset)
            )
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")

            # Test that saving the case without changing the start condition has no effect
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'case_property1': 'abc'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.get_id, old_reminder_id)

            # Retire the reminder
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': ''}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNone(reminder)
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")

            # Test changing a start condition which is a string representation of a datetime value
            # Spawn the reminder with datetime start condition value
            update_case(self.domain, case.case_id, {'start_sending1': '2012-02-25 11:15'},
                user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)

            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 25, 11, 15) + timedelta(days=self.handler1.start_offset)
            )

            # Reset the datetime start condition
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': '2012-02-26 11:20'},
                user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)

            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 26, 11, 20) + timedelta(days=self.handler1.start_offset)
            )
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")

            # Test that saving the case without changing the start condition has no effect
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'case_property1': 'xyz'},
                user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.get_id, old_reminder_id)

            # Retire the reminder
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': ''},
                user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNone(reminder)
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")