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
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, })
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()
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
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
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
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, })
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
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.")
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