コード例 #1
0
    def migration_already_done(self, domain_obj):
        if project_is_on_new_reminders(domain_obj):
            log("'%s' already uses new reminders, nothing to do" %
                domain_obj.name)
            return True

        return False
コード例 #2
0
 def response_inbound_sms(domain, new_plan_version):
     """
     All Reminder rules utilizing "survey" will be deactivated.
     """
     if project_is_on_new_reminders(domain):
         num_survey = (
             len(_get_active_immediate_broadcasts(domain,
                                                  survey_only=True)) +
             len(_get_active_scheduled_broadcasts(domain, survey_only=True))
             + len(_get_active_scheduling_rules(domain, survey_only=True)))
     else:
         surveys = [
             x for x in _active_reminder_methods(domain)
             if x in [METHOD_IVR_SURVEY, METHOD_SMS_SURVEY]
         ]
         num_survey = len(surveys)
     if num_survey > 0:
         return _fmt_alert(
             ungettext(
                 "You have %(num_active)d active Reminder Rule or Broadcast which uses a Survey. "
                 "Selecting this plan will deactivate it.",
                 "You have %(num_active)d active Reminder Rules and Broadcasts which use a Survey. "
                 "Selecting this plan will deactivate them.", num_survey) %
             {
                 'num_active': num_survey,
             })
コード例 #3
0
ファイル: util.py プロジェクト: udaracamarasinghe/commcare-hq
 def wrapped(request, *args, **kwargs):
     if (hasattr(request, 'couch_user')
             and toggles.NEW_REMINDERS_MIGRATOR.enabled(
                 request.couch_user.username)):
         return fn(request, *args, **kwargs)
     if not hasattr(request, 'project'):
         request.project = Domain.get_by_name(request.domain)
     if not project_is_on_new_reminders(request.project):
         return fn(request, *args, **kwargs)
     raise Http404()
コード例 #4
0
    def add_reminder_status_info(self, result):
        if project_is_on_new_reminders(self.domain_object):
            events_pending = get_count_of_active_schedule_instances_due(
                self.domain, datetime.utcnow())
        else:
            events_pending = len(
                CaseReminderHandler.get_all_reminders(
                    domain=self.domain,
                    due_before=datetime.utcnow(),
                    ids_only=True))

        result['events_pending'] = events_pending
コード例 #5
0
 def response_outbound_sms(domain, new_plan_version):
     """
     Reminder rules will be deactivated.
     """
     try:
         if project_is_on_new_reminders(domain):
             _deactivate_schedules(domain)
         else:
             for reminder in _active_reminders(domain):
                 reminder.active = False
                 reminder.save()
     except Exception:
         log_accounting_error(
             "Failed to downgrade outbound sms for domain %s." %
             domain.name)
         return False
     return True
コード例 #6
0
    def page_context(self):
        from corehq.apps.reports.standard.sms import (
            ScheduleInstanceReport,
            MessageLogReport,
            MessagingEventsReport,
        )

        if project_is_on_new_reminders(self.domain_object):
            scheduled_events_url = reverse(
                ScheduleInstanceReport.dispatcher.name(),
                args=[],
                kwargs={
                    'domain': self.domain,
                    'report_slug': ScheduleInstanceReport.slug
                })
        else:
            scheduled_events_url = reverse(
                ScheduledRemindersCalendarView.urlname, args=[self.domain])

        context = {
            'scheduled_events_url':
            scheduled_events_url,
            'message_log_url':
            reverse(MessageLogReport.dispatcher.name(),
                    args=[],
                    kwargs={
                        'domain': self.domain,
                        'report_slug': MessageLogReport.slug
                    }),
            'messaging_history_url':
            reverse(MessagingEventsReport.dispatcher.name(),
                    args=[],
                    kwargs={
                        'domain': self.domain,
                        'report_slug': MessagingEventsReport.slug
                    }),
        }

        context[
            'messaging_history_errors_url'] = self.get_messaging_history_errors_url(
                context['messaging_history_url'])

        return context
コード例 #7
0
 def response_outbound_sms(domain, new_plan_version):
     """
     Reminder rules will be deactivated.
     """
     if project_is_on_new_reminders(domain):
         num_active = (len(_get_active_immediate_broadcasts(domain)) +
                       len(_get_active_scheduled_broadcasts(domain)) +
                       len(_get_active_scheduling_rules(domain)))
     else:
         num_active = len(_active_reminder_methods(domain))
     if num_active > 0:
         return _fmt_alert(
             ungettext(
                 "You have %(num_active)d active Reminder Rule or Broadcast. Selecting "
                 "this plan will deactivate it.",
                 "You have %(num_active)d active Reminder Rules and Broadcasts. Selecting "
                 "this plan will deactivate them.", num_active) % {
                     'num_active': num_active,
                 })
コード例 #8
0
 def response_inbound_sms(domain, new_plan_version):
     """
     All Reminder rules utilizing "survey" will be deactivated.
     """
     try:
         if project_is_on_new_reminders(domain):
             _deactivate_schedules(domain, survey_only=True)
         else:
             surveys = [
                 x for x in _active_reminders(domain)
                 if x.method in [METHOD_IVR_SURVEY, METHOD_SMS_SURVEY]
             ]
             for survey in surveys:
                 survey.active = False
                 survey.save()
     except Exception:
         log_accounting_error(
             "Failed to downgrade inbound sms for domain %s." % domain.name)
         return False
     return True
コード例 #9
0
    def handle(self, domain, filename, **options):
        domain_obj = Domain.get_by_name(domain)
        if domain_obj is None:
            raise CommandError("Project space '%s' not found" % domain)

        if not project_is_on_new_reminders(domain_obj):
            raise CommandError(
                "Project space '%s' does not have new reminders enabled" %
                domain)

        json_rules = []
        with open_for_json_read(filename) as f:
            for line in f:
                json_rules.append(json.loads(line))

        print("Importing %s rules..." % len(json_rules))

        rules = []
        with transaction.atomic():
            for entry in json_rules:
                json_rule = SimpleSchedulingRule(entry['rule'])

                schedule_type = entry['schedule']['schedule_type']
                if schedule_type == SIMPLE_SMS_DAILY_SCHEDULE_WITH_TIME:
                    json_schedule = SimpleSMSDailyScheduleWithTime(
                        entry['schedule'])
                    schedule = TimedSchedule.create_simple_daily_schedule(
                        domain,
                        TimedEvent(time=json_schedule.time),
                        SMSContent(message=json_schedule.message),
                        total_iterations=json_schedule.total_iterations,
                        start_offset=json_schedule.start_offset,
                        start_day_of_week=json_schedule.start_day_of_week,
                        extra_options=json_schedule.extra_options.to_json(),
                        repeat_every=json_schedule.repeat_every,
                    )
                elif schedule_type == SIMPLE_SMS_ALERT_SCHEDULE:
                    json_schedule = SimpleSMSAlertSchedule(entry['schedule'])
                    schedule = AlertSchedule.create_simple_alert(
                        domain,
                        SMSContent(message=json_schedule.message),
                        extra_options=json_schedule.extra_options.to_json(),
                    )
                else:
                    raise CommandError("Unexpected schedule_type: %s" %
                                       schedule_type)

                rule = AutomaticUpdateRule.objects.create(
                    domain=domain,
                    name=json_rule.name,
                    case_type=json_rule.case_type,
                    active=True,
                    filter_on_server_modified=False,
                    workflow=AutomaticUpdateRule.WORKFLOW_SCHEDULING,
                )

                for criterion in json_rule.criteria:
                    rule.add_criteria(
                        MatchPropertyDefinition,
                        property_name=criterion.property_name,
                        property_value=criterion.property_value,
                        match_type=criterion.match_type,
                    )

                rule.add_action(
                    CreateScheduleInstanceActionDefinition,
                    alert_schedule_id=schedule.schedule_id if isinstance(
                        schedule, AlertSchedule) else None,
                    timed_schedule_id=schedule.schedule_id if isinstance(
                        schedule, TimedSchedule) else None,
                    recipients=json_rule.recipients,
                    reset_case_property_name=json_rule.
                    reset_case_property_name,
                    start_date_case_property=json_rule.
                    start_date_case_property,
                    specific_start_date=json_rule.specific_start_date,
                    scheduler_module_info=json_rule.scheduler_module_info.
                    to_json(),
                )

                rules.append(rule)

        print("Import complete. Starting instance refresh tasks...")

        for rule in rules:
            initiate_messaging_rule_run(rule.domain, rule.pk)

        print("Done.")
コード例 #10
0
    def save_copy(self, new_domain_name=None, new_hr_name=None, user=None,
                  copy_by_id=None, share_reminders=True,
                  share_user_roles=True):
        from corehq.apps.app_manager.dbaccessors import get_app
        from corehq.apps.data_interfaces.models import AutomaticUpdateRule
        from corehq.apps.reminders.models import CaseReminderHandler
        from corehq.apps.fixtures.models import FixtureDataItem
        from corehq.apps.app_manager.dbaccessors import get_brief_apps_in_domain
        from corehq.apps.domain.dbaccessors import get_doc_ids_in_domain_by_class
        from corehq.apps.fixtures.models import FixtureDataType
        from corehq.apps.users.models import UserRole

        db = Domain.get_db()
        new_id = db.copy_doc(self.get_id)['id']
        if new_domain_name is None:
            new_domain_name = new_id

        uses_new_reminders = project_is_on_new_reminders(self)

        with CriticalSection(['request_domain_name_{}'.format(new_domain_name)]):
            new_domain_name = Domain.generate_name(new_domain_name)
            new_domain = Domain.get(new_id)
            new_domain.name = new_domain_name
            new_domain.hr_name = new_hr_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
            new_domain.date_created = datetime.utcnow()
            new_domain.use_sql_backend = True
            new_domain.granted_messaging_access = False

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

            # Saving the domain should happen before we import any apps since
            # importing apps can update the domain object (for example, if user
            # as a case needs to be enabled)
            try:
                new_domain.save()
            except PreconditionFailed:
                # This is a hack to resolve http://manage.dimagi.com/default.asp?241492
                # Following solution in
                # https://github.com/dimagi/commcare-hq/commit/d59b1e403060ade599cc4a03db0aabc4da62b668
                time.sleep(0.5)
                new_domain.save()

            new_app_components = {}  # a mapping of component's id to its copy

            def copy_data_items(old_type_id, new_type_id):
                for item in FixtureDataItem.by_data_type(self.name, old_type_id):
                    comp = self.copy_component(
                        item.doc_type, item._id, new_domain_name, user=user)
                    comp.data_type_id = new_type_id
                    comp.save()

            def get_latest_app_id(doc_id):
                app = get_app(self.name, doc_id).get_latest_saved()
                if app:
                    return app._id, app.doc_type

            for app in get_brief_apps_in_domain(self.name):
                doc_id, doc_type = app.get_id, app.doc_type
                original_doc_id = doc_id
                if copy_by_id and doc_id not in copy_by_id:
                    continue
                if not self.is_snapshot:
                    doc_id, doc_type = get_latest_app_id(doc_id) or (doc_id, doc_type)
                component = self.copy_component(doc_type, doc_id, new_domain_name, user=user)
                if component:
                    new_app_components[original_doc_id] = component

            for doc_id in get_doc_ids_in_domain_by_class(self.name, FixtureDataType):
                if copy_by_id and doc_id not in copy_by_id:
                    continue
                component = self.copy_component(
                    'FixtureDataType', doc_id, new_domain_name, user=user)
                copy_data_items(doc_id, component._id)

            def convert_form_unique_id_function(form_unique_id):
                from corehq.apps.app_manager.models import FormBase
                form = FormBase.get_form(form_unique_id)
                form_app = form.get_app()
                m_index, f_index = form_app.get_form_location(form.unique_id)
                form_copy = new_app_components[form_app._id].get_module(m_index).get_form(f_index)
                return form_copy.unique_id

            if share_reminders:
                if uses_new_reminders:
                    for rule in AutomaticUpdateRule.by_domain(
                        self.name,
                        AutomaticUpdateRule.WORKFLOW_SCHEDULING,
                        active_only=False,
                    ):
                        rule.copy_conditional_alert(
                            new_domain_name,
                            convert_form_unique_id_function=convert_form_unique_id_function,
                        )
                else:
                    for doc_id in get_doc_ids_in_domain_by_class(self.name, CaseReminderHandler):
                        self.copy_component(
                            'CaseReminderHandler', doc_id, new_domain_name, user=user)
            if share_user_roles:
                for doc_id in get_doc_ids_in_domain_by_class(self.name, UserRole):
                    self.copy_component('UserRole', doc_id, new_domain_name, user=user)

        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)

        if not uses_new_reminders:
            # When uses_new_reminders is True, all of this is already taken care of
            # in the copy process
            def update_events(handler):
                """
                Change the form_unique_id to the proper form for each event in a newly copied CaseReminderHandler
                """
                for event in handler.events:
                    if not event.form_unique_id:
                        continue
                    event.form_unique_id = convert_form_unique_id_function(event.form_unique_id)

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

            if share_reminders:
                for handler in CaseReminderHandler.get_handlers(new_domain_name):
                    apply_update(handler, update_for_copy)

        return new_domain