def test_get_scheduled_report_response(self): domain = 'test-scheduled-reports' user = WebUser.create( domain=domain, username='******', password='******', ) report_config = ReportConfig.wrap({ "date_range": "last30", "days": 30, "domain": domain, "report_slug": "worker_activity", "report_type": "project_report", "owner_id": user._id, }) report_config.save() report = ReportNotification( hour=12, minute=None, day=30, interval='monthly', config_ids=[report_config._id] ) report.save() response = get_scheduled_report_response( couch_user=user, domain=domain, scheduled_report_id=report._id )[0] self.assertEqual(200, response.status_code) self.assertTrue(user.username in response.serialize())
def touch_saved_reports_views(user, domain): """ Hit the saved reports views so stale=update_after doesn't cause the user to see old or deleted data after a change when they next load the reports homepage. """ ReportConfig.by_domain_and_owner(domain, user._id, limit=1, stale=False) ReportNotification.by_domain_and_owner(domain, user._id, limit=1, stale=False)
def get_scheduled_report_response(couch_user, domain, scheduled_report_id, email=True): from dimagi.utils.web import get_url_base from django.http import HttpRequest request = HttpRequest() request.couch_user = couch_user request.user = couch_user.get_django_user() request.domain = domain request.couch_user.current_domain = domain notification = ReportNotification.get(scheduled_report_id) report_outputs = [] for config in notification.configs: report_outputs.append({ 'title': config.full_name, 'url': config.url, 'content': config.get_report_content() }) return render(request, "reports/report_email.html", { "reports": report_outputs, "domain": notification.domain, "couch_user": notification.owner._id, "DNS_name": get_url_base(), "owner_name": couch_user.full_name or couch_user.get_email(), "email": email })
def setUp(self): for report in ReportNotification.view( 'reportconfig/all_notifications', include_docs=True, reduce=False, ).all(): report.delete()
def saved_reports(request, domain, template="reports/reports_home.html"): user = request.couch_user if not (request.couch_user.can_view_reports() or request.couch_user.get_viewable_reports()): raise Http404 configs = ReportConfig.by_domain_and_owner(domain, user._id) def _is_valid(rn): # the _id check is for weird bugs we've seen in the wild that look like # oddities in couch. return hasattr(rn, "_id") and rn._id and (not hasattr(rn, "report_slug") or rn.report_slug != "admin_domains") scheduled_reports = [rn for rn in ReportNotification.by_domain_and_owner(domain, user._id) if _is_valid(rn)] scheduled_reports = sorted(scheduled_reports, key=lambda rn: rn.configs[0].name) context = dict( couch_user=request.couch_user, domain=domain, configs=configs, scheduled_reports=scheduled_reports, report=dict( title=_("My Saved Reports"), show=user.can_view_reports() or user.get_viewable_reports(), slug=None, is_async=True, section_name=ProjectReport.section_name, ), ) if request.couch_user: util.set_report_announcements_for_user(request, user) return render(request, template, context)
def daily_reports(): # this should get called every hour by celery reps = ReportNotification.view("reportconfig/daily_notifications", key=datetime.utcnow().hour, include_docs=True).all() for rep in reps: send_report.delay(rep._id)
def saved_reports(request, domain, template="reports/reports_home.html"): user = request.couch_user if not (request.couch_user.can_view_reports() or request.couch_user.get_viewable_reports()): raise Http404 configs = ReportConfig.by_domain_and_owner(domain, user._id).all() scheduled_reports = [s for s in ReportNotification.by_domain_and_owner(domain, user._id).all() if not hasattr(s, 'report_slug') or s.report_slug != 'admin_domains'] context = dict( couch_user=request.couch_user, domain=domain, configs=configs, scheduled_reports=scheduled_reports, report=dict( title="Select a Report to View", show=user.can_view_reports() or user.get_viewable_reports(), slug=None, is_async=True, section_name=ProjectReport.section_name, ), ) if request.couch_user: util.set_report_announcements_for_user(request, user) return render(request, template, context)
def balance_email_reports(self): EWSMigrationProblem.objects.filter(domain=self.domain).delete() reports = set() reports_count = 0 for web_user in WebUser.by_domain(self.domain): notifications = ReportNotification.by_domain_and_owner(self.domain, web_user.get_id) for notification in notifications: config_id = notification.config_ids[0] if notification.config_ids else None if not config_id: continue config = ReportConfig.get(config_id) location_id = config.filters.get('location_id') if not location_id: # report is not migrated from ews continue reports_count += 1 report_slug = config.report_slug code = SQLLocation.objects.get(location_id=location_id).site_code report_tuple = ( web_user.username, notification.day, notification.hour, code, report_slug, notification.interval ) external_id = '{}-{}-{}-{}-{}-{}'.format(*report_tuple) if not notification.send_to_owner and not notification.recipient_emails: migration_problem, _ = EWSMigrationProblem.objects.get_or_create( domain=self.domain, object_id=web_user.username, object_type='email_report_send_to_owner', external_id=external_id ) migration_problem.description = 'send_to_owner not set to true' migration_problem.save() reports.add(report_tuple) total_count = 0 for report in self.endpoint.get_daily_reports(limit=1000)[1]: if self._check_report(report, reports, 1, 'daily'): total_count += 1 for report in self.endpoint.get_weekly_reports(limit=1000)[1]: if self._check_report(report, reports, report.day_of_week, 'weekly'): total_count += 1 for report in self.endpoint.get_monthly_reports(limit=1000)[1]: if self._check_report(report, reports, report.day_of_month, 'monthly'): total_count += 1 if total_count != reports_count: migration_problem, _ = EWSMigrationProblem.objects.get_or_create( domain=self.domain, object_id=None, object_type='email_report', external_id='email-report-count' ) migration_problem.description = '{} / {}'.format(reports_count, total_count) migration_problem.save()
def monthly_reports(): now = datetime.utcnow() reps = ReportNotification.view("reportconfig/all_notifications", key=["monthly", now.hour, now.day], reduce=False, include_docs=True).all() for rep in reps: send_report.delay(rep._id)
def weekly_reports(): # this should get called every hour by celery now = datetime.utcnow() reps = ReportNotification.view("reportconfig/weekly_notifications", key=[now.weekday(), now.hour], include_docs=True).all() for rep in reps: send_report.delay(rep._id)
def set_send_to_owner_field_task(domain): for web_user in WebUser.by_domain(domain): notifications = ReportNotification.by_domain_and_owner(domain, web_user.get_id) for notification in notifications: if not notification.send_to_owner and not notification.recipient_emails: notification.send_to_owner = True notification.save() balance_migration_task.delay(domain)
def daily_reports(): # this should get called every hour by celery reps = ReportNotification.view("reportconfig/all_notifications", startkey=["daily", datetime.utcnow().hour], endkey=["daily", datetime.utcnow().hour, {}], reduce=False, include_docs=True).all() for rep in reps: send_report.delay(rep._id)
def send_report(notification_id): notification = ReportNotification.get(notification_id) owner = WebUser.get(notification.owner_id) language = owner.get_language_code() try: with localize(language): notification.send() except UnsupportedScheduledReportError: pass
def delete_scheduled_report(request, domain, scheduled_report_id): user_id = request.couch_user._id rep = ReportNotification.get(scheduled_report_id) if user_id != rep.owner._id: return HttpResponseBadRequest() rep.delete() messages.success(request, "Scheduled report deleted!") return HttpResponseRedirect(reverse("reports_home", args=(domain,)))
def _report_notfication_sync(self, report, interval, day): if not report.users or report.report not in self.REPORT_MAP: return user_id = report.users[0] recipients = report.users[1:] location_code = report.view_args.split()[1][1:-2] user = WebUser.get_by_username(user_id) if not user: return try: location = SQLLocation.active_objects.get(site_code=location_code, domain=self.domain) except SQLLocation.DoesNotExist: return notifications = ReportNotification.by_domain_and_owner(self.domain, user.get_id) for n in notifications: if len(n.config_ids) == 1: # Migrated reports have only one config config = ReportConfig.get(n.config_ids[0]) location_id = config.filters.get('location_id') slug = self.REPORT_MAP[report.report] report_slug = config.report_slug if (n.day, location_id, report_slug, n.interval) == (day, location.location_id, slug, interval): if not n.send_to_owner and not n.recipient_emails: n.send_to_owner = True n.save() return saved_config = ReportConfig( report_type='custom_project_report', name=report.report, owner_id=user.get_id, report_slug=self.REPORT_MAP[report.report], domain=self.domain, filters={'filter_by_program': 'all', 'location_id': location.location_id} ) saved_config.save() saved_notification = ReportNotification( hour=report.hours, day=day, interval=interval, owner_id=user.get_id, domain=self.domain, recipient_emails=recipients, config_ids=[saved_config.get_id], send_to_owner=True ) saved_notification.save() return saved_notification
def drop_scheduled_report(request, domain, couch_user_id, report_id): rep = ReportNotification.get(report_id) try: rep.user_ids.remove(couch_user_id) except ValueError: pass # odd, the user wasn't there in the first place if len(rep.user_ids) == 0: rep.delete() else: rep.save() messages.success(request, "Scheduled report dropped!") return HttpResponseRedirect(reverse("user_account", args=(domain, couch_user_id )))
def _report_notfication_sync(self, report, interval, day): if not report.users: return user_id = report.users[0] recipients = report.users[1:] location_code = report.view_args.split()[1][1:-2] user = WebUser.get_by_username(user_id) if not user: return try: location = SQLLocation.objects.get(site_code=location_code, domain=self.domain) except SQLLocation.DoesNotExist: return notifications = ReportNotification.by_domain_and_owner(self.domain, user.get_id) reports = [] for n in notifications: for config_id in n.config_ids: config = ReportConfig.get(config_id) reports.append((config.filters.get('location_id'), config.report_slug, interval)) if report.report not in self.REPORT_MAP or (location.location_id, self.REPORT_MAP[report.report], interval) in reports: return saved_config = ReportConfig( report_type='custom_project_report', name=report.report, owner_id=user.get_id, report_slug=self.REPORT_MAP[report.report], domain=self.domain, filters={'filter_by_program': 'all', 'location_id': location.location_id} ) saved_config.save() saved_notification = ReportNotification( hour=report.hours, day=day, interval=interval, owner_id=user.get_id, domain=self.domain, recipient_emails=recipients, config_ids=[saved_config.get_id] ) saved_notification.save() return saved_notification
def get_scheduled_report_ids(period, as_of=None): as_of = as_of or datetime.utcnow() assert period in ('daily', 'weekly', 'monthly'), period def _keys(period, as_of): minute = guess_reporting_minute(as_of) if minute == 0: # for legacy purposes, on the hour also include reports that didn't have a minute set minutes = (None, minute) else: minutes = (minute,) if period == 'daily': for minute in minutes: yield { 'startkey': [period, as_of.hour, minute], 'endkey': [period, as_of.hour, minute, {}], } elif period == 'weekly': for minute in minutes: yield { 'key': [period, as_of.hour, minute, as_of.weekday()], } else: # monthly for minute in minutes: yield { 'key': [period, as_of.hour, minute, as_of.day] } if as_of.day == monthrange(as_of.year, as_of.month)[1]: for day in range(as_of.day + 1, 32): for minute in minutes: yield { 'key': [period, as_of.hour, minute, day] } try: keys = _keys(period, as_of) except ValueError: _soft_assert(False, "Celery was probably down for a while. Lots of reports are getting dropped!") raise StopIteration for key in keys: for result in ReportNotification.view( "reportconfig/all_notifications", reduce=False, include_docs=False, **key ).all(): yield result['id']
def delete_scheduled_report(request, domain, scheduled_report_id): user_id = request.couch_user._id try: rep = ReportNotification.get(scheduled_report_id) except ResourceNotFound: # was probably already deleted by a fast-clicker. pass else: if user_id != rep.owner._id: return HttpResponseBadRequest() rep.delete() messages.success(request, "Scheduled report deleted!") return HttpResponseRedirect(reverse("reports_home", args=(domain,)))
def test_scheduled_report(request, domain, couch_user_id, report_id): rep = ReportNotification.get(report_id) try: user = WebUser.get_by_user_id(couch_user_id, domain) except CouchUser.AccountTypeError: user = CommCareUser.get_by_user_id(couch_user_id, domain) try: send_report(rep, user) except SMTPRecipientsRefused: messages.error(request, "You have no email address configured") else: messages.success(request, "Test message sent to %s" % user.get_email()) return HttpResponseRedirect(reverse("user_account", args=(domain, couch_user_id )))
def get_scheduled_report_response(couch_user, domain, scheduled_report_id, email=True): from django.http import HttpRequest request = HttpRequest() request.couch_user = couch_user request.user = couch_user.get_django_user() request.domain = domain request.couch_user.current_domain = domain notification = ReportNotification.get(scheduled_report_id) return _render_report_configs(request, notification.configs, notification.domain, notification.owner_id, couch_user, email)
def send_test_scheduled_report(request, domain, scheduled_report_id): from corehq.apps.reports.tasks import send_report from corehq.apps.users.models import CouchUser, CommCareUser, WebUser user_id = request.couch_user._id notification = ReportNotification.get(scheduled_report_id) try: user = WebUser.get_by_user_id(user_id, domain) except CouchUser.AccountTypeError: user = CommCareUser.get_by_user_id(user_id, domain) try: send_report.delay(notification._id) except Exception, e: import logging logging.exception(e) messages.error(request, "An error occured, message unable to send")
def get_scheduled_reports(period, as_of=None): as_of = as_of or datetime.utcnow() assert period in ('daily', 'weekly', 'monthly') def _keys(period, as_of): minute = guess_reporting_minute(as_of) if minute == 0: # for legacy purposes, on the hour also include reports that didn't have a minute set minutes = (None, minute) else: minutes = (minute,) if period == 'daily': for minute in minutes: yield { 'startkey': [period, as_of.hour, minute], 'endkey': [period, as_of.hour, minute, {}], } elif period == 'weekly': for minute in minutes: yield { 'key': [period, as_of.hour, minute, as_of.weekday()], } else: # monthly for minute in minutes: yield { 'key': [period, as_of.hour, minute, as_of.day] } if as_of.day == monthrange(as_of.year, as_of.month)[1]: for day in range(as_of.day + 1, 32): for minute in minutes: yield { 'key': [period, as_of.hour, minute, day] } for keys in _keys(period, as_of): for report in ReportNotification.view("reportconfig/all_notifications", reduce=False, include_docs=True, **keys ).all(): yield report
def get_scheduled_report_response(couch_user, domain, scheduled_report_id, email=True, attach_excel=False): """ This function somewhat confusingly returns a tuple of: (response, excel_files) If attach_excel is false, excel_files will always be an empty list. """ # todo: clean up this API? from django.http import HttpRequest request = HttpRequest() request.couch_user = couch_user request.user = couch_user.get_django_user() request.domain = domain request.couch_user.current_domain = domain notification = ReportNotification.get(scheduled_report_id) return _render_report_configs(request, notification.configs, notification.domain, notification.owner_id, couch_user, email, attach_excel=attach_excel)
def handle(self, *args, **options): db = ReportNotification.get_db() results = db.view('reportconfig/user_notifications', reduce=False, include_docs=False, ).all() migrate = { "first": first_migrate, "second": second_migrate, }[WHICH_MIGRATION] notifications_to_save = [] for notification in iter_docs(db, [r['id'] for r in results]): if migrate(notification): notifications_to_save.append(notification) if len(notifications_to_save) > 100: db.bulk_save(notifications_to_save) notifications_to_save = [] db.bulk_save(notifications_to_save)
def saved_reports(request, domain, template="reports/reports_home.html"): user = request.couch_user if not (request.couch_user.can_view_reports() or request.couch_user.get_viewable_reports()): raise Http404 configs = ReportConfig.by_domain_and_owner(domain, user._id) def _is_valid(rn): # the _id check is for weird bugs we've seen in the wild that look like # oddities in couch. return hasattr(rn, "_id") and rn._id and (not hasattr(rn, 'report_slug') or rn.report_slug != 'admin_domains') scheduled_reports = [rn for rn in ReportNotification.by_domain_and_owner(domain, user._id) if _is_valid(rn)] scheduled_reports = sorted(scheduled_reports, key=lambda rn: rn.configs[0].name) for report in scheduled_reports: time_difference = get_timezone_difference(domain) (report.hour, day_change) = recalculate_hour(report.hour, int(time_difference[:3]), int(time_difference[3:])) report.minute = 0 if day_change: report.day = calculate_day(report.interval, report.day, day_change) context = dict( couch_user=request.couch_user, domain=domain, configs=configs, scheduled_reports=scheduled_reports, report=dict( title=_("My Saved Reports"), show=user.can_view_reports() or user.get_viewable_reports(), slug=None, is_async=True, section_name=ProjectReport.section_name, ), ) if request.couch_user: util.set_report_announcements_for_user(request, user) return render(request, template, context)
def edit_scheduled_report(request, domain, scheduled_report_id=None, template="reports/edit_scheduled_report.html"): from corehq.apps.users.models import WebUser from corehq.apps.reports.forms import ScheduledReportForm context = { 'form': None, 'domain': domain, 'report': { 'show': request.couch_user.can_view_reports() or request.couch_user.get_viewable_reports(), 'slug': None, 'default_url': reverse('reports_home', args=(domain, )), 'is_async': False, 'section_name': ProjectReport.section_name, } } user_id = request.couch_user._id configs = ReportConfig.by_domain_and_owner(domain, user_id) config_choices = [(c._id, c.full_name) for c in configs if c.report and c.report.emailable] if not config_choices: return render(request, template, context) web_users = WebUser.view('users/web_users_by_domain', reduce=False, key=domain, include_docs=True).all() web_user_emails = [u.get_email() for u in web_users] if scheduled_report_id: instance = ReportNotification.get(scheduled_report_id) time_difference = get_timezone_difference(domain) (instance.hour, day_change) = recalculate_hour(instance.hour, int(time_difference[:3]), int(time_difference[3:])) instance.minute = 0 if day_change: instance.day = calculate_day(instance.interval, instance.day, day_change) if instance.owner_id != user_id or instance.domain != domain: raise HttpResponseBadRequest() else: instance = ReportNotification(owner_id=user_id, domain=domain, config_ids=[], hour=8, minute=0, send_to_owner=True, recipient_emails=[]) is_new = instance.new_document initial = instance.to_json() initial['recipient_emails'] = ', '.join(initial['recipient_emails']) kwargs = {'initial': initial} args = (request.POST, ) if request.method == "POST" else () form = ScheduledReportForm(*args, **kwargs) form.fields['config_ids'].choices = config_choices form.fields['recipient_emails'].choices = web_user_emails form.fields['hour'].help_text = "This scheduled report's timezone is %s (%s GMT)" % \ (Domain._get_by_name(domain)['default_timezone'], get_timezone_difference(domain)[:3] + ':' + get_timezone_difference(domain)[3:]) if request.method == "POST" and form.is_valid(): for k, v in form.cleaned_data.items(): setattr(instance, k, v) time_difference = get_timezone_difference(domain) (instance.hour, day_change) = calculate_hour(instance.hour, int(time_difference[:3]), int(time_difference[3:])) instance.minute = int(time_difference[3:]) if day_change: instance.day = calculate_day(instance.interval, instance.day, day_change) instance.save() if is_new: messages.success(request, "Scheduled report added!") else: messages.success(request, "Scheduled report updated!") touch_saved_reports_views(request.couch_user, domain) return HttpResponseRedirect(reverse('reports_home', args=(domain, ))) context['form'] = form context['day_value'] = getattr(instance, "day", 1) context['weekly_day_options'] = ReportNotification.day_choices() context['monthly_day_options'] = [(i, i) for i in range(1, 32)] if is_new: context['form_action'] = "Create a new" context['report']['title'] = "New Scheduled Report" else: context['form_action'] = "Edit" context['report']['title'] = "Edit Scheduled Report" return render(request, template, context)
def testDailyReportWithMinuteHalfHour(self): ReportNotification(hour=12, minute=30, interval='daily').save() self._check('daily', datetime(2014, 10, 31, 12, 0), 0) self._check('daily', datetime(2014, 10, 31, 12, 30), 1)
def send_report(notification_id): notification = ReportNotification.get(notification_id) try: notification.send() except UnsupportedScheduledReportError: pass
def testDailyReportOtherHoursDontCount(self): ReportNotification(hour=12, minute=0, day=31, interval='daily').save() self._check('daily', datetime(2014, 10, 31, 11, 0), 0)
def testMonthlyReportOnTheEndOfTheMonthWithMinuteHalfHour(self): ReportNotification(hour=12, minute=30, day=30, interval='monthly').save() ReportNotification(hour=12, minute=30, day=31, interval='monthly').save() self._check('monthly', datetime(2014, 11, 30, 12, 30), 2)
def edit_scheduled_report(request, domain, scheduled_report_id=None, template="reports/edit_scheduled_report.html"): from corehq.apps.users.models import WebUser from corehq.apps.reports.forms import ScheduledReportForm context = { 'form': None, 'domain': domain, 'report': { 'show': request.couch_user.can_view_reports() or request.couch_user.get_viewable_reports(), 'slug': None, 'default_url': reverse('reports_home', args=(domain,)), 'is_async': False, 'section_name': ProjectReport.section_name, } } user_id = request.couch_user._id configs = ReportConfig.by_domain_and_owner(domain, user_id) config_choices = [(c._id, c.full_name) for c in configs if c.report and c.report.emailable] if not config_choices: return render(request, template, context) web_users = WebUser.view('users/web_users_by_domain', reduce=False, key=domain, include_docs=True).all() web_user_emails = [u.get_email() for u in web_users] if scheduled_report_id: instance = ReportNotification.get(scheduled_report_id) time_difference = get_timezone_difference(domain) (instance.hour, day_change) = recalculate_hour(instance.hour, int(time_difference[:3]), int(time_difference[3:])) instance.minute = 0 if day_change: instance.day = calculate_day(instance.interval, instance.day, day_change) if instance.owner_id != user_id or instance.domain != domain: raise HttpResponseBadRequest() else: instance = ReportNotification(owner_id=user_id, domain=domain, config_ids=[], hour=8, minute=0, send_to_owner=True, recipient_emails=[]) is_new = instance.new_document initial = instance.to_json() initial['recipient_emails'] = ', '.join(initial['recipient_emails']) kwargs = {'initial': initial} args = (request.POST,) if request.method == "POST" else () form = ScheduledReportForm(*args, **kwargs) form.fields['config_ids'].choices = config_choices form.fields['recipient_emails'].choices = web_user_emails form.fields['hour'].help_text = "This scheduled report's timezone is %s (%s GMT)" % \ (Domain._get_by_name(domain)['default_timezone'], get_timezone_difference(domain)[:3] + ':' + get_timezone_difference(domain)[3:]) if request.method == "POST" and form.is_valid(): for k, v in form.cleaned_data.items(): setattr(instance, k, v) time_difference = get_timezone_difference(domain) (instance.hour, day_change) = calculate_hour(instance.hour, int(time_difference[:3]), int(time_difference[3:])) instance.minute = int(time_difference[3:]) if day_change: instance.day = calculate_day(instance.interval, instance.day, day_change) instance.save() if is_new: messages.success(request, "Scheduled report added!") else: messages.success(request, "Scheduled report updated!") touch_saved_reports_views(request.couch_user, domain) return HttpResponseRedirect(reverse('reports_home', args=(domain,))) context['form'] = form context['day_value'] = getattr(instance, "day", 1) context['weekly_day_options'] = ReportNotification.day_choices() context['monthly_day_options'] = [(i, i) for i in range(1, 32)] if is_new: context['form_action'] = "Create a new" context['report']['title'] = "New Scheduled Report" else: context['form_action'] = "Edit" context['report']['title'] = "Edit Scheduled Report" return render(request, template, context)
def test_queue_selection_normal(self): self.assertEqual( 'celery', get_report_queue(ReportNotification(domain='not-mvp')))
def testMonthlyReportOnTheEndOfTheMonthDaysAfter31DontCount(self): ReportNotification(hour=12, minute=None, day=31, interval='monthly').save() ReportNotification(hour=12, minute=None, day=32, interval='monthly').save() self._check('monthly', datetime(2014, 10, 31, 12, 0), 1)
def edit_scheduled_report(request, domain, scheduled_report_id=None, template="reports/edit_scheduled_report.html"): from corehq.apps.users.models import WebUser from corehq.apps.reports.forms import ScheduledReportForm context = { "form": None, "domain": domain, "report": { "show": request.couch_user.can_view_reports() or request.couch_user.get_viewable_reports(), "slug": None, "default_url": reverse("reports_home", args=(domain,)), "is_async": False, "section_name": ProjectReport.section_name, }, } user_id = request.couch_user._id configs = ReportConfig.by_domain_and_owner(domain, user_id) config_choices = [(c._id, c.full_name) for c in configs if c.report and c.report.emailable] if not config_choices: return render(request, template, context) web_users = WebUser.view("users/web_users_by_domain", reduce=False, key=domain, include_docs=True).all() web_user_emails = [u.get_email() for u in web_users] if scheduled_report_id: instance = ReportNotification.get(scheduled_report_id) if instance.owner_id != user_id or instance.domain != domain: raise HttpResponseBadRequest() else: instance = ReportNotification( owner_id=user_id, domain=domain, config_ids=[], hour=8, send_to_owner=True, recipient_emails=[] ) is_new = instance.new_document initial = instance.to_json() initial["recipient_emails"] = ", ".join(initial["recipient_emails"]) kwargs = {"initial": initial} args = (request.POST,) if request.method == "POST" else () form = ScheduledReportForm(*args, **kwargs) form.fields["config_ids"].choices = config_choices form.fields["recipient_emails"].choices = web_user_emails if request.method == "POST" and form.is_valid(): for k, v in form.cleaned_data.items(): setattr(instance, k, v) instance.save() if is_new: messages.success(request, "Scheduled report added!") else: messages.success(request, "Scheduled report updated!") touch_saved_reports_views(request.couch_user, domain) return HttpResponseRedirect(reverse("reports_home", args=(domain,))) context["form"] = form context["day_value"] = getattr(instance, "day", 1) context["weekly_day_options"] = ReportNotification.day_choices() context["monthly_day_options"] = [(i, i) for i in range(1, 32)] if is_new: context["form_action"] = "Create a new" context["report"]["title"] = "New Scheduled Report" else: context["form_action"] = "Edit" context["report"]["title"] = "Edit Scheduled Report" return render(request, template, context)
def testMonthlyReportWithMinute(self): ReportNotification(hour=12, minute=0, day=31, interval='monthly').save() self._check('monthly', datetime(2014, 10, 31, 12, 0), 1) self._check('monthly', datetime(2014, 10, 31, 12, 30), 0)
def testMonthlyReportOtherDaysDontCount(self): ReportNotification(hour=12, minute=None, day=31, interval='monthly').save() self._check('monthly', datetime(2014, 10, 30, 12, 0), 0)
def testMonthlyReportOnTheEndOfTheMonthEmptyMinute(self): ReportNotification(hour=12, minute=None, day=30, interval='monthly').save() ReportNotification(hour=12, minute=None, day=31, interval='monthly').save() self._check('monthly', datetime(2014, 11, 30, 12, 0), 2)
def testWeeklyReportOtherDaysDontCount(self): ReportNotification(hour=12, minute=0, day=4, interval='weekly').save() self._check('weekly', datetime(2014, 10, 30, 12, 0), 0)
def edit_scheduled_report(request, domain, scheduled_report_id=None, template="reports/edit_scheduled_report.html"): from corehq.apps.users.models import WebUser from corehq.apps.reports.forms import ScheduledReportForm context = { 'form': None, 'domain': domain, 'report': { 'show': request.couch_user.can_view_reports() or request.couch_user.get_viewable_reports(), 'slug': None, 'default_url': reverse('reports_home', args=(domain, )), 'is_async': False, 'section_name': ProjectReport.section_name, } } user_id = request.couch_user._id configs = ReportConfig.by_domain_and_owner(domain, user_id).all() config_choices = [(c._id, c.full_name) for c in configs if c.report and c.report.emailable] if not config_choices: return render(request, template, context) web_users = WebUser.view('users/web_users_by_domain', reduce=False, key=domain, include_docs=True).all() web_user_emails = [u.get_email() for u in web_users] if scheduled_report_id: instance = ReportNotification.get(scheduled_report_id) if instance.owner_id != user_id or instance.domain != domain: raise HttpResponseBadRequest() else: instance = ReportNotification(owner_id=user_id, domain=domain, config_ids=[], day_of_week=-1, hours=8, send_to_owner=True, recipient_emails=[]) is_new = instance.new_document initial = instance.to_json() initial['recipient_emails'] = ', '.join(initial['recipient_emails']) kwargs = {'initial': initial} args = (request.POST, ) if request.method == "POST" else () form = ScheduledReportForm(*args, **kwargs) form.fields['config_ids'].choices = config_choices form.fields['recipient_emails'].choices = web_user_emails if request.method == "POST" and form.is_valid(): for k, v in form.cleaned_data.items(): setattr(instance, k, v) instance.save() if is_new: messages.success(request, "Scheduled report added!") else: messages.success(request, "Scheduled report updated!") touch_saved_reports_views(request.couch_user, domain) return HttpResponseRedirect(reverse('reports_home', args=(domain, ))) context['form'] = form if is_new: context['form_action'] = "Create a new" context['report']['title'] = "New Scheduled Report" else: context['form_action'] = "Edit" context['report']['title'] = "Edit Scheduled Report" return render(request, template, context)
def edit_scheduled_report(request, domain, scheduled_report_id=None, template="reports/edit_scheduled_report.html"): from corehq.apps.users.models import WebUser from corehq.apps.reports.forms import ScheduledReportForm context = { 'form': None, 'domain': domain, 'report': { 'show': request.couch_user.can_view_reports() or request.couch_user.get_viewable_reports(), 'slug': None, 'default_url': reverse('reports_home', args=(domain,)), 'is_async': False, 'section_name': ProjectReport.section_name, } } user_id = request.couch_user._id configs = ReportConfig.by_domain_and_owner(domain, user_id).all() config_choices = [(c._id, c.full_name) for c in configs if c.report and c.report.emailable] if not config_choices: return render(request, template, context) web_users = WebUser.view('users/web_users_by_domain', reduce=False, key=domain, include_docs=True).all() web_user_emails = [u.get_email() for u in web_users] if scheduled_report_id: instance = ReportNotification.get(scheduled_report_id) if instance.owner_id != user_id or instance.domain != domain: raise HttpResponseBadRequest() else: instance = ReportNotification(owner_id=user_id, domain=domain, config_ids=[], day_of_week=-1, hours=8, send_to_owner=True, recipient_emails=[]) is_new = instance.new_document initial = instance.to_json() initial['recipient_emails'] = ', '.join(initial['recipient_emails']) kwargs = {'initial': initial} args = (request.POST,) if request.method == "POST" else () form = ScheduledReportForm(*args, **kwargs) form.fields['config_ids'].choices = config_choices form.fields['recipient_emails'].choices = web_user_emails if request.method == "POST" and form.is_valid(): for k, v in form.cleaned_data.items(): setattr(instance, k, v) instance.save() if is_new: messages.success(request, "Scheduled report added!") else: messages.success(request, "Scheduled report updated!") return HttpResponseRedirect(reverse('reports_home', args=(domain,))) context['form'] = form if is_new: context['form_action'] = "Create a new" context['report']['title'] = "New Scheduled Report" else: context['form_action'] = "Edit" context['report']['title'] = "Edit Scheduled Report" return render(request, template, context)
def testMonthlyReportBeforeTheEndOfTheMonth(self): ReportNotification(hour=12, minute=None, day=30, interval='monthly').save() ReportNotification(hour=12, minute=None, day=31, interval='monthly').save() self._check('monthly', datetime(2014, 10, 30, 12, 0), 1)
def testMonthlyReportEmptyMinute(self): ReportNotification(hour=12, minute=None, day=31, interval='monthly').save() self._check('monthly', datetime(2014, 10, 31, 12, 0), 1) self._check('monthly', datetime(2014, 10, 31, 12, 30), 0) # half hour shouldn't count
def test_queue_selection_mvp(self): self.assertEqual( 'background_queue', get_report_queue(ReportNotification(domain='mvp-tiby')))