Example #1
0
    def _send_email(self,
                    recipients,
                    template_name,
                    context=None,
                    user=None,
                    include_token=False,
                    **kwargs):
        context = context or {}

        base_context = {
            'visit': self.get_mail_context(user=user,
                                           include_token=include_token),
            'environment': get_environment(),
        }
        base_context.update(context)
        context = base_context

        if isinstance(recipients, str):
            recipients = [
                recipients,
            ]
        else:
            recipients = list(recipients)

        # assert recipients
        if recipients:
            send_notification_with_template(
                recipients=recipients,
                template_name=template_name,
                context=context,
            )
Example #2
0
def notify_partner_hidden(partner_pk, tenant_name):

    with schema_context(tenant_name):
        partner = PartnerOrganization.objects.get(pk=partner_pk)
        pds = Intervention.objects.filter(
            agreement__partner__name=partner.name,
            status__in=[
                Intervention.SIGNED, Intervention.ACTIVE, Intervention.ENDED
            ])
        if pds:
            email_context = {
                'partner_name': partner.name,
                'pds': ', '.join(pd.number for pd in pds),
                'environment': get_environment(),
            }
            emails_to_pd = [
                pd.unicef_focal_points.values_list('email', flat=True)
                for pd in pds
            ]
            recipients = set(itertools.chain.from_iterable(emails_to_pd))

            send_notification_with_template(
                recipients=list(recipients),
                template_name='partners/blocked_partner',
                context=email_context)
Example #3
0
def send_intervention_past_start_notification():
    """Send an email to PD/SHPD/SSFA's focal point(s) if signed
    and start date is past with no FR added"""
    intervention_qs = Intervention.objects.filter(
        status=Intervention.SIGNED,
        start__lt=datetime.date.today(),
        frs__isnull=False,
    )
    for intervention in intervention_qs.all():
        recipients = [
            u.user.email for u in intervention.unicef_focal_points.all()
            if u.user.email
        ]
        send_notification_with_template(
            recipients=recipients,
            template_name="partners/intervention/past-start",
            context={
                "reference_number": intervention.reference_number,
                "title": intervention.title,
                "url": "{}pmp/interventions/{}/details".format(
                    settings.HOST,
                    intervention.pk,
                )
            }
        )
Example #4
0
def _notify_interventions_ending_soon(country_name):
    """Implementation core of intervention_notification_ending() (q.v.)"""
    logger.info(
        'Starting interventions almost ending notifications for country {}'.
        format(country_name))

    today = datetime.date.today()

    notify_end_dates = [
        today + datetime.timedelta(days=delta)
        for delta in _INTERVENTION_ENDING_SOON_DELTAS
    ]

    interventions = Intervention.objects.filter(status=Intervention.ACTIVE,
                                                end__in=notify_end_dates)
    interventions = interventions.prefetch_related('unicef_focal_points',
                                                   'agreement',
                                                   'agreement__partner')

    for intervention in interventions:
        email_context = get_intervention_context(intervention)
        email_context["days"] = str((intervention.end - today).days)
        send_notification_with_template(
            sender=intervention,
            recipients=email_context['unicef_focal_points'],
            template_name="partners/partnership/ending",
            context=email_context)
Example #5
0
def send_invite_email(staff):
    context = {
        'environment': get_environment(),
        'login_link': reverse('social:begin', kwargs={'backend': 'azuread-b2c-oauth2'})
    }

    send_notification_with_template(
        recipients=[staff.user.email],
        template_name='organisations/staff_member/invite',
        context=context
    )
Example #6
0
def test_send_notification_with_template(mock_mail, email_template):
    mock_mail.send.return_value = Email()
    recipients = ["*****@*****.**"]
    with patch.object(Notification, 'save'):
        utils.send_notification_with_template(recipients, email_template.name,
                                              {})
    # we called send with all the proper args
    mock_mail.send.assert_called()
    call_kwargs = mock_mail.send.call_args[1]
    assert settings.DEFAULT_FROM_EMAIL == call_kwargs['sender']
    assert recipients == call_kwargs["recipients"]
Example #7
0
def send_invite_email(staff):
    context = {
        'environment': get_environment(),
        'login_link': get_token_auth_link(staff.user)
    }

    send_notification_with_template(
        recipients=[staff.user.email],
        template_name='organisations/staff_member/invite',
        context=context
    )
def assign_to_unicef_group(instance, created, **kwargs):
    if created and instance.email:
        if instance.username.endswith('@unicef.org'):
            unicef_group, _ = Group.objects.get_or_create(name='UNICEF User')
            instance.groups.add(unicef_group)
        else:
            context = {'instance': instance, 'home_link': settings.HOST}
            send_notification_with_template(
                [instance.email, ],
                "access_grant_email",
                context,
            )
Example #9
0
    def send_user_appointed_email(self, engagement):
        context = {
            'environment': get_environment(),
            'engagement': engagement.get_mail_context(user=self.user),
            'staff_member': self.user.get_full_name(),
        }

        send_notification_with_template(
            recipients=[self.user.email],
            template_name='audit/engagement/submit_to_auditor',
            context=context,
        )
Example #10
0
def send_invite_email(staff):
    context = {
        'environment':
        get_environment(),
        'login_link':
        reverse('social:begin', kwargs={'backend': 'azuread-b2c-oauth2'})
    }

    send_notification_with_template(
        recipients=[staff.user.email],
        template_name='organisations/staff_member/invite',
        context=context)
def test_extends(email_template):
    mail_qs = Email.objects
    assert mail_qs.count() == 0
    send_notification_with_template(
        recipients=['*****@*****.**'],
        from_address='*****@*****.**',
        template_name='template1',
        context={},
    )

    assert mail_qs.count() == 1
    mail = mail_qs.first()
    assert 'Base template' in mail.html_message
    assert 'Template1' in mail.html_message
Example #12
0
def test_send_notification_with_template_recipients_str(
        mock_mail, email_template):
    mock_mail.send.return_value = Email()
    recipients = "*****@*****.**"
    with patch.object(Notification, 'save'):
        utils.send_notification_with_template(
            recipients,
            email_template.name,
            {},
        )
    # we called send with all the proper args
    mock_mail.send.assert_called()
    call_kwargs = mock_mail.send.call_args[1]
    assert [recipients] == call_kwargs["recipients"]
Example #13
0
def _notify_of_ended_interventions_with_mismatched_frs(country_name):
    """Implementation core of intervention_notification_ended_fr_outstanding() (q.v.)"""
    logger.info('Starting intervention signed but FRs Amount and actual '
                'do not match notifications for country {}'.format(country_name))

    ended_interventions = Intervention.objects.filter(status=Intervention.ENDED)
    for intervention in ended_interventions:
        if intervention.total_frs['total_actual_amt'] != intervention.total_frs['total_frs_amt']:
            email_context = get_intervention_context(intervention)
            send_notification_with_template(
                sender=intervention,
                recipients=email_context['unicef_focal_points'],
                template_name="partners/partnership/ended/frs/outstanding",
                context=email_context
            )
Example #14
0
def _notify_of_signed_interventions_with_no_frs(country_name):
    """Implementation core of intervention_notification_signed_no_frs() (q.v.)"""
    logger.info('Starting intervention signed but no FRs notifications for country {}'.format(country_name))

    signed_interventions = Intervention.objects.filter(status=Intervention.SIGNED,
                                                       start__gte=datetime.date.today(),
                                                       frs__isnull=True)

    for intervention in signed_interventions:
        email_context = get_intervention_context(intervention)
        send_notification_with_template(
            sender=intervention,
            recipients=email_context['unicef_focal_points'],
            template_name="partners/partnership/signed/frs",
            context=email_context
        )
Example #15
0
def test_send_notification_with_template_from_address(mock_mail,
                                                      email_template):
    mock_mail.send.return_value = Email()
    recipients = ["*****@*****.**"]
    from_address = "*****@*****.**"
    with patch.object(Notification, 'save'):
        utils.send_notification_with_template(
            recipients,
            email_template.name,
            {},
            from_address=from_address,
        )
    # we called send with all the proper args
    mock_mail.send.assert_called()
    call_kwargs = mock_mail.send.call_args[1]
    assert from_address == call_kwargs['sender']
    assert recipients == call_kwargs["recipients"]
Example #16
0
    def form_valid(self, form):
        login_link = get_token_auth_link(form.get_user())

        redirect_to = form.data.get('next', self.request.GET.get('next'))
        if redirect_to:
            login_link = update_url_with_kwargs(login_link, next=redirect_to)

        email_context = {
            'recipient': form.get_user().get_full_name(),
            'login_link': login_link,
        }

        send_notification_with_template(recipients=[form.get_user().email],
                                        template_name='email_auth/token/login',
                                        context=email_context)

        return self.render_to_response(
            self.get_context_data(email=form.get_user().email))
Example #17
0
def send_intervention_draft_notification():
    """Send an email to PD/SHPD/SSFA's focal point(s) if in draft status"""
    for intervention in Intervention.objects.filter(
            status=Intervention.DRAFT,
            created__lt=(datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=7)).date(),
    ):
        recipients = [
            u.user.email for u in intervention.unicef_focal_points.all()
            if u.user.email
        ]
        send_notification_with_template(
            recipients=recipients,
            template_name="partners/intervention/draft",
            context={
                "reference_number": intervention.reference_number,
                "title": intervention.title,
            }
        )
Example #18
0
def send_agreement_suspended_notification(agreement, user):
    # send notification to user performing this action
    pd_list = []
    for intervention in agreement.interventions.all():
        sections = ", ".join(
            [str(s) for s in intervention.sections.all()]
        )
        url = "{}{}".format(settings.HOST, intervention.get_object_url())
        pd_list.append((sections, intervention.reference_number, url))

    send_notification_with_template(
        recipients=[user.email],  # person that initiated this update
        template_name="partners/agreement/suspended",
        context={
            "vendor_number": agreement.reference_number,
            "vendor_name": agreement.partner.name,
            "pd_list": pd_list,  # section, pd_number, link
        }
    )
Example #19
0
def _notify_interventions_ending_soon(country_name):
    """Implementation core of intervention_notification_ending() (q.v.)"""
    logger.info('Starting interventions almost ending notifications for country {}'.format(country_name))

    today = datetime.date.today()

    notify_end_dates = [today + datetime.timedelta(days=delta) for delta in _INTERVENTION_ENDING_SOON_DELTAS]

    interventions = Intervention.objects.filter(status=Intervention.ACTIVE, end__in=notify_end_dates)
    interventions = interventions.prefetch_related('unicef_focal_points', 'agreement', 'agreement__partner')

    for intervention in interventions:
        email_context = get_intervention_context(intervention)
        email_context["days"] = str((intervention.end - today).days)
        send_notification_with_template(
            sender=intervention,
            recipients=email_context['unicef_focal_points'],
            template_name="partners/partnership/ending",
            context=email_context
        )
Example #20
0
def send_pca_required_notifications():
    """If the PD has an end date that is after the CP to date
    and the it is 30 days prior to the end of the CP,
    send a PCA required notification.
    """
    days_lead = datetime.date.today() + datetime.timedelta(
        days=settings.PCA_REQUIRED_NOTIFICATION_LEAD
    )
    pd_list = set()
    for cp in CountryProgramme.objects.filter(to_date=days_lead):
        # For PDs related directly to CP
        for pd in cp.interventions.filter(
                document_type=Intervention.PD,
                end__gt=cp.to_date
        ):
            pd_list.add(pd)

        # For PDs by way of agreement
        for agreement in cp.agreements.filter(interventions__end__gt=cp.to_date):
            for pd in agreement.interventions.filter(
                    document_type=Intervention.PD,
                    end__gt=cp.to_date
            ):
                pd_list.add(pd)

    for pd in pd_list:
        recipients = [u.user.email for u in pd.unicef_focal_points.all()]
        context = {
            "reference_number": pd.reference_number,
            "partner_name": str(pd.agreement.partner),
            "pd_link": reverse(
                "partners_api:intervention-detail",
                args=[pd.pk]
            ),
        }
        send_notification_with_template(
            recipients=recipients,
            template_name='partners/intervention/new_pca_required',
            context=context
        )
Example #21
0
def notify_partner_hidden(partner_pk, tenant_name):

    with schema_context(tenant_name):
        partner = PartnerOrganization.objects.get(pk=partner_pk)
        pds = Intervention.objects.filter(
            agreement__partner__name=partner.name,
            status__in=[Intervention.SIGNED, Intervention.ACTIVE, Intervention.ENDED]
        )
        if pds:
            email_context = {
                'partner_name': partner.name,
                'pds': ', '.join(pd.number for pd in pds),
                'environment': get_environment(),
            }
            emails_to_pd = [pd.unicef_focal_points.values_list('email', flat=True) for pd in pds]
            recipients = set(itertools.chain.from_iterable(emails_to_pd))

            send_notification_with_template(
                recipients=list(recipients),
                template_name='partners/blocked_partner',
                context=email_context
            )
Example #22
0
    def _notify_focal_points(self, template_name, context=None):
        for focal_point in get_user_model().objects.filter(groups=UNICEFAuditFocalPoint.as_group(),
                                                           profile__countries_available=connection.tenant):
            # Build the context in the same order the previous version of the code did,
            # just in case something relies on it (intentionally or not).
            ctx = {
                'focal_point': focal_point.get_full_name(),
            }
            if context:
                ctx.update(context)
            base_context = {
                'engagement': self.get_mail_context(user=focal_point),
                'environment': get_environment(),
            }
            base_context.update(ctx)
            context = base_context

            send_notification_with_template(
                recipients=[focal_point.email],
                template_name=template_name,
                context=context,
            )
Example #23
0
def send_pca_missing_notifications():
    """If the PD has en end date that is after PCA end date
    and the PD start date is in the previous CP cycle,
    and the current CP cycle has no PCA
    send a missing PCA notification.
    """
    # get PDs that have end date after PCA end date
    # this means that the CP is in previous cycle
    # (as PCA and CP end dates are always equal)
    # and PD start date in the previous CP cycle
    intervention_qs = Intervention.objects.filter(
        document_type=Intervention.PD,
        agreement__agreement_type=Agreement.PCA,
        agreement__country_programme__from_date__lt=F("start"),
        end__gt=F("agreement__end")
    )
    for pd in intervention_qs:
        # check that partner has no PCA in the current CP cycle
        cp_previous = pd.agreement.country_programme
        pca_next_qs = Agreement.objects.filter(
            partner=pd.agreement.partner,
            country_programme__from_date__gt=cp_previous.to_date
        )
        if not pca_next_qs.exists():
            recipients = [u.user.email for u in pd.unicef_focal_points.all()]
            context = {
                "reference_number": pd.reference_number,
                "partner_name": str(pd.agreement.partner),
                "pd_link": reverse(
                    "partners_api:intervention-detail",
                    args=[pd.pk]
                ),
            }
            send_notification_with_template(
                recipients=recipients,
                template_name='partners/intervention/pca_missing',
                context=context
            )
Example #24
0
    def _notify_focal_points(self, template_name, context=None):
        for focal_point in get_user_model().objects.filter(
                groups=UNICEFAuditFocalPoint.as_group(),
                profile__countries_available=connection.tenant):
            # Build the context in the same order the previous version of the code did,
            # just in case something relies on it (intentionally or not).
            ctx = {
                'focal_point': focal_point.get_full_name(),
            }
            if context:
                ctx.update(context)
            base_context = {
                'engagement': self.get_mail_context(user=focal_point),
                'environment': get_environment(),
            }
            base_context.update(ctx)
            context = base_context

            send_notification_with_template(
                recipients=[focal_point.email],
                template_name=template_name,
                context=context,
            )
Example #25
0
def notify_donor(donor_code):

    document_type_filter = [
        'Certified Financial Statement - EC',
        'Certified Financial Statement - US Government',
        'Certified Statement of Account',
        'Certified Statement of Account EU',
        'Certified Statement of Account JPO',
        'Donor Statement CERF',
        'Certified Financial Report - Final',
        'Certified Financial Report - Interim',
        'Donor Statement Innovation',
        'Donor Statement Joint Programme',
        'Donor Statement Joint Programme PUNO',
        'Donor Statement JPO Summary',
        'Donor Statement Trust Fund',
        'Donor Statement UN',
        'Donor Statement UNICEF Hosted Funds',
        'FFR Form (SF-425)',
        'JPO Expenditure Summary',
        'Statement of Account Thematic Funds',
        'Donor Statement by Activity',
        'Interim Statement by Nature of expense',
        'Funds Request Report',
        'Non-Standard Statement',
        'Emergency Consolidated - Final',
        'Emergency  Consolidated - Interim',
        'Thematic Emergency Global - Final',
        'Thematic Emergency Global - Interim',
        'Emergency - Two Pager',
        'Emergency - Final',
        'Emergency - Interim',
        'Human Interest / Photos',
        'Narrative - Final',
        'Narrative - Interim',
        'Narrative Consolidated - Final',
        'Narrative Consolidated - Interim',
        'Thematic Consolidated - Final',
        'Thematic Consolidated - Interim',
        'Thematic Global - Final',
        'Thematic Global - Interim',
        'Thematic - Final',
        'Thematic - Interim',
        'Short Summary Update',
        'Official Receipts',
        'Quarterly Monitoring Report',
    ]

    donor = Donor.objects.get(code=donor_code)
    logger.info(f'Notifing {donor.name}')
    client = SharePointClient(
        url=
        f'{config.SHAREPOINT_TENANT}/{config.SHAREPOINT_SITE_TYPE}/{config.SHAREPOINT_SITE}'
    )

    notification_periods = [
        x for x in [
            (UserRole.EVERY_MONTH,
             today().replace(day=1) - relativedelta(months=1),
             today().day == 1),
            (UserRole.EVERY_MONDAY, today() - timedelta(7),
             today().weekday() == 0),
            (UserRole.EVERY_DAY, today() - timedelta(1), True),
        ] if x[2]
    ]

    for period, modified_date, _ in notification_periods:
        filters = {
            'DRPDonorCode': donor.code,
            'DRPDonorDocument': ','.join(document_type_filter),
            'DRPModified__gte': modified_date.strftime('%Y-%m-%d')
        }
        serializer_fields = DRPSharePointSearchSerializer._declared_fields.keys(
        )
        selected = ['DRP' + to_camel(x)
                    for x in serializer_fields] + ["Title", "Author", "Path"]

        page = 1
        exit_condition = True
        reports = []

        users = UserRole.objects.filter(donor=donor,
                                        notification_period=period).values(
                                            'user__first_name', 'user__email')

        if users:
            while exit_condition:
                response, total_rows = client.search(
                    filters=filters,
                    select=selected,
                    source_id=settings.DRP_SOURCE_IDS['external'],
                    page=page)
                exit_condition = page * SHAREPOINT_PAGE_SIZE < total_rows
                page += 1
                qs = DRPSharePointSearchSerializer(response, many=True)
                reports.extend(qs.data)

            if reports:
                context = {'reports': reports, 'donor': donor.name}
                recipients = list(
                    set([
                        str(user['user__email']) for user in users
                        if user['user__email']
                    ]))
                send_notification_with_template(recipients, 'notify_donor',
                                                context)