Example #1
0
def draft_app_warning(request):
    """ Warn orgs of impending draft freezes
      NOTE: must run exactly once a day
      Gives 7 day warning if created 7+ days before close, otherwise 3 day warning """

    drafts = DraftGrantApplication.objects.all()
    eight_days = timedelta(days=8)

    for draft in drafts:
        time_left = draft.grant_cycle.close - timezone.now()
        created_delta = draft.grant_cycle.close - draft.created
        if ((created_delta > eight_days
             and eight_days > time_left > timedelta(days=7))
                or (created_delta < eight_days
                    and timedelta(days=3) > time_left >= timedelta(days=2))):
            to_email = draft.organization.get_email()

            if not to_email:
                logger.warn(
                    'Unable to send draft reminder; org is not registered %d',
                    draft.organization.pk)
                continue

            utils.send_email(subject='Grant cycle closing soon',
                             sender=c.GRANT_EMAIL,
                             to=[to_email],
                             template='grants/email_draft_warning.html',
                             context={
                                 'org': draft.organization,
                                 'cycle': draft.grant_cycle
                             })
            logger.info(
                'Email sent to %s regarding draft application soon to expire',
                to_email)
    return HttpResponse('')
Example #2
0
def yer_reminder_email(request):
    """ Remind orgs of upcoming year end reports that are due
      NOTE: Must run exactly once a day. ONLY SUPPORTS UP TO 2-YEAR GRANTS
      Sends reminder emails at 1 month and 1 week """

    today = timezone.now().date()

    # get awards due in 7 or 30 days
    year_ago = today.replace(year=today.year - 1)
    reminder_deltas = [timedelta(days=7), timedelta(days=30)]
    award_dates = []
    for delta in reminder_deltas:
        award_dates.append(today + delta)
        award_dates.append((today + delta).replace(year=today.year - 1))

    awards = GivingProjectGrant.objects.filter(first_yer_due__in=award_dates)

    for award in awards:
        if award.yearendreport_set.count() < award.grant_length():
            app = award.projectapp.application

            to = app.organization.get_email() or app.email_address
            utils.send_email(subject='Year end report',
                             sender=c.GRANT_EMAIL,
                             to=[to],
                             template='grants/email_yer_due.html',
                             context={
                                 'award': award,
                                 'app': app,
                                 'gp': award.projectapp.giving_project,
                                 'base_url': c.APP_BASE_URL
                             })
            logger.info('YER reminder email sent to %s for award %d', to,
                        award.pk)
    return HttpResponse('success')
Example #3
0
def email_overdue(request):
    today = datetime.date.today()
    ships = models.Membership.objects.filter(
        giving_project__fundraising_deadline__gte=today)
    limit = today - datetime.timedelta(days=7)
    subject = 'Fundraising Steps'
    from_email = c.FUND_EMAIL

    for ship in ships:
        member = ship.member
        if not ship.emailed or (ship.emailed <= limit):
            count, step = ship.overdue_steps(get_next=True)
            if count > 0 and step:
                to_email = ship.member.user.username
                logger.info('%s has overdue step(s), emailing.', to_email)
                utils.send_email(subject=subject,
                                 to=[to_email],
                                 sender=from_email,
                                 template='fund/emails/overdue_steps.html',
                                 context={
                                     'login_url':
                                     c.APP_BASE_URL + '/fund/login',
                                     'ship': ship,
                                     'num': count,
                                     'step': step,
                                     'base_url': c.APP_BASE_URL
                                 })
                ship.emailed = today
                ship.save(skip=True)
    return HttpResponse('')
Example #4
0
def notify_approval(membership):
    to_email = membership.member.user.username
    utils.send_email(subject='Membership Approved',
                     sender=c.FUND_EMAIL,
                     to=[to_email],
                     template='fund/emails/account_approved.html',
                     context={
                         'login_url': c.APP_BASE_URL + '/fund/login',
                         'project': membership.giving_project
                     })
    logger.info(u'Approval email sent to %s at %s', membership, to_email)
Example #5
0
def report_reminder_email(request):
    """ Remind orgs of upcoming grantee reports that are due
      NOTE: Must run exactly once a day. ONLY SUPPORTS UP TO 2-YEAR GRANTS
      Sends reminder emails at 1 month and 1 week """

    today = timezone.now().date()
    seven_days = timedelta(days=7)
    thirty_days = timedelta(days=30)
    award_dates = [today + seven_days, today + thirty_days]

    awards = (GivingProjectGrant.objects.filter(
        Q(first_report_due__in=award_dates)
        | Q(second_report_due__in=award_dates)).annotate(
            report_count=Count('granteereport')))

    for award in awards:
        due = False
        if award.report_count == 0:
            due = award.first_report_due
        elif award.report_count == 1 and award.second_report_due:
            due = award.second_report_due

        if due:
            app = award.projectapp.application

            to = app.organization.get_email() or app.email_address
            utils.send_email(subject='Grantee report',
                             sender=c.GRANT_EMAIL,
                             to=[to],
                             template='grants/email_report_due.html',
                             context={
                                 'award': award,
                                 'app': app,
                                 'gp': award.projectapp.giving_project,
                                 'base_url': c.APP_BASE_URL,
                                 'due_date': due
                             })
            logger.info(
                'Grantee report reminder email sent to %s for award %d', to,
                award.pk)
    return HttpResponse('success')
Example #6
0
def gift_notify(request):
    """ Set gift received notifications on membership object and send an email
      Marks donors as notified """

    donors = (models.Donor.objects.select_related('membership__member').filter(
        gift_notified=False).exclude(received_this=0,
                                     received_next=0,
                                     received_afternext=0))

    memberships = {}
    for donor in donors:
        if donor.membership not in memberships:
            memberships[donor.membership] = []
        memberships[donor.membership].append(donor)

    login_url = c.APP_BASE_URL + '/fund/'
    subject = 'Gift or pledge received'
    from_email = c.FUND_EMAIL

    for ship, donor_list in memberships.iteritems():
        gift_str = ''
        for donor in donor_list:
            gift_str += u'${}  gift or pledge received from {}! '.format(
                donor.received(), donor)
        ship.notifications = gift_str
        ship.save(skip=True)

        utils.send_email(subject=subject,
                         to=[ship.member.user.username],
                         sender=from_email,
                         template='fund/emails/gift_received.html',
                         context={
                             'login_url': login_url,
                             'gift_str': ship.notifications
                         })
        logger.info('Set gift notification and sent email to %s',
                    ship.member.user.username)

    donors.update(gift_notified=True)
    return HttpResponse('')
Example #7
0
def new_accounts(request):
    """ Send GP leaders an email saying how many unapproved memberships exist

    Will continue emailing about the same membership until it's approved/deleted.
  """

    subject = 'Accounts pending approval'
    from_email = c.FUND_EMAIL

    active_gps = models.GivingProject.objects.filter(
        fundraising_deadline__gte=timezone.now().date())

    for gp in active_gps:
        memberships = models.Membership.objects.filter(giving_project=gp)
        need_approval = memberships.filter(approved=False).count()
        if need_approval > 0:
            leaders = memberships.filter(leader=True)
            to_emails = [leader.member.user.username for leader in leaders]
            if to_emails:
                utils.send_email(
                    subject=subject,
                    to=to_emails,
                    sender=from_email,
                    template='fund/emails/accounts_need_approval.html',
                    context={
                        'admin_url':
                        c.APP_BASE_URL + '/admin/fund/membership/',
                        'count': need_approval,
                        'giving_project': unicode(gp),
                        'support_email': c.SUPPORT_EMAIL
                    })
                logger.info(
                    '%d unapproved memberships in %s. Email sent to %s',
                    need_approval, unicode(gp), ', '.join(to_emails))

    return HttpResponse('')
Example #8
0
def auto_create_cycles(request):
    now = timezone.now()

    if now.hour != 8:  # UTC
        logger.error(
            'auto_create_cycles running at unexpected time %s; aborting', now)
        return HttpResponse(status=500)

    cycles = GrantCycle.objects.filter(
        Q(title__startswith='Rapid Response') | Q(title__startswith='Seed '),
        close__range=(now - timedelta(hours=2), now))

    if len(cycles) == 0:
        logger.info('auto_create_cycles found no recently closed cycles')
        return HttpResponse(status=200)

    created = []
    for cycle in cycles:
        prefix = 'Rapid Response' if cycle.get_type(
        ) == 'rapid' else 'Seed Grant'

        if GrantCycle.objects.filter(title__startswith=prefix,
                                     close__gte=now).exists():
            logger.info(
                'auto_create_cycles skipping %s cycle; next one exists',
                prefix)
            continue

        title = '{} {}.{}.{} - {}.{}.{}'.format(
            prefix,
            cycle.open.month,
            cycle.open.day,
            cycle.open.year,
            cycle.close.month,
            cycle.close.day,
            cycle.close.year,
        )
        new_cycle = GrantCycle.objects.copy(cycle, title, timezone.now(),
                                            cycle.close + timedelta(days=14))

        # add some context for use in email

        new_cycle.prev_cycle = cycle
        new_cycle.drafts_count = (DraftGrantApplication.objects.filter(
            grant_cycle_id=cycle.id).update(grant_cycle_id=new_cycle.id))

        created.append(new_cycle)

    if len(created) > 0:
        logger.info('auto_create_cycles created %d new cycles', len(created))

        utils.send_email(subject='Grant cycles created',
                         sender=c.GRANT_EMAIL,
                         to=['*****@*****.**'],
                         template='grants/emails/auto_create_cycles.html',
                         context={'cycles': created})
        return HttpResponse(status=201)
    else:
        logger.info(
            'auto_create_cycles did nothing; new cycles already existed')
        return HttpResponse()