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())
Beispiel #2
0
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)
Beispiel #3
0
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()
Beispiel #5
0
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)
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
    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()
Beispiel #9
0
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)
Beispiel #10
0
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)
Beispiel #11
0
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)
Beispiel #12
0
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)
Beispiel #13
0
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
Beispiel #14
0
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,)))
Beispiel #15
0
    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
Beispiel #16
0
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 )))
Beispiel #17
0
    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
Beispiel #18
0
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']
Beispiel #19
0
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,)))
Beispiel #20
0
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 )))
Beispiel #21
0
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)
Beispiel #22
0
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")
Beispiel #23
0
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
Beispiel #24
0
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)
Beispiel #26
0
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)
Beispiel #27
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)
    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)
Beispiel #28
0
 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)
Beispiel #29
0
def send_report(notification_id):
    notification = ReportNotification.get(notification_id)
    try:
        notification.send()
    except UnsupportedScheduledReportError:
        pass
Beispiel #30
0
 def testDailyReportOtherHoursDontCount(self):
     ReportNotification(hour=12, minute=0, day=31, interval='daily').save()
     self._check('daily', datetime(2014, 10, 31, 11, 0), 0)
Beispiel #31
0
def send_report(notification_id):
    notification = ReportNotification.get(notification_id)
    try:
        notification.send()
    except UnsupportedScheduledReportError:
        pass
Beispiel #32
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)
Beispiel #33
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)
    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)
Beispiel #34
0
 def test_queue_selection_normal(self):
     self.assertEqual(
         'celery', get_report_queue(ReportNotification(domain='not-mvp')))
Beispiel #35
0
 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)
Beispiel #36
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)
    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)
Beispiel #37
0
 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)
Beispiel #38
0
 def testMonthlyReportOtherDaysDontCount(self):
     ReportNotification(hour=12, minute=None, day=31,
                        interval='monthly').save()
     self._check('monthly', datetime(2014, 10, 30, 12, 0), 0)
Beispiel #39
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)
Beispiel #40
0
 def testWeeklyReportOtherDaysDontCount(self):
     ReportNotification(hour=12, minute=0, day=4, interval='weekly').save()
     self._check('weekly', datetime(2014, 10, 30, 12, 0), 0)
Beispiel #41
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)
Beispiel #42
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!")

        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)
Beispiel #43
0
 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)
Beispiel #44
0
 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
Beispiel #45
0
 def test_queue_selection_mvp(self):
     self.assertEqual(
         'background_queue',
         get_report_queue(ReportNotification(domain='mvp-tiby')))