Beispiel #1
0
    def post(self, request, **kwargs):
        body_unicode = request.body.decode("utf-8")
        body = json.loads(body_unicode)

        username = body["username"]
        pathway_id = body["pathway_id"]
        program_uuid = kwargs["uuid"]

        # verify that the user or an admin is making the request
        if username != request.user.get_username() and not request.user.is_staff:
            return JsonResponse({"error": "Permission denied"}, status=403)

        credential = UserCredential.objects.filter(
            username=username, status=UserCredential.AWARDED, program_credentials__program_uuid=program_uuid
        )
        program = get_object_or_404(Program, uuid=program_uuid, site=request.site)
        pathway = get_object_or_404(
            Pathway,
            id=pathway_id,
            programs__uuid=program_uuid,
            pathway_type=PathwayType.CREDIT.value,
        )
        certificate = get_object_or_404(ProgramCertificate, program_uuid=program_uuid, site=request.site)
        user = get_object_or_404(User, username=username)
        public_record, _ = ProgramCertRecord.objects.get_or_create(user=user, program=program)

        # Make sure we haven't already sent an email with a 'sent' status
        if UserCreditPathway.objects.filter(user=user, pathway=pathway, status=UserCreditPathwayStatus.SENT).exists():
            return JsonResponse({"error": "Pathway email already sent"}, status=400)

        record_path = reverse("records:public_programs", kwargs={"uuid": public_record.uuid.hex})
        record_link = request.build_absolute_uri(record_path)
        csv_link = urllib.parse.urljoin(record_link, "csv")

        msg = ProgramCreditRequest(request.site, user.email).personalize(
            recipient=Recipient(username=None, email_address=pathway.email),
            language=certificate.language,
            user_context={
                "pathway_name": pathway.name,
                "program_name": program.title,
                "record_link": record_link,
                "user_full_name": request.user.get_full_name() or request.user.username,
                "program_completed": credential.exists(),
                "previously_sent": False,
                "csv_link": csv_link,
            },
        )
        ace.send(msg)

        # Create a record of this email so that we can't send multiple times
        # If the status was previously changed, we want to reset it to SENT
        UserCreditPathway.objects.update_or_create(
            user=user,
            pathway=pathway,
            defaults={"status": UserCreditPathwayStatus.SENT},
        )

        return http.HttpResponse(status=200)
Beispiel #2
0
def send_program_certificate_created_message(username, program_certificate):
    """
    If the learner has earned a Program Certificate then we go ahead and send them an automated email congratulating
    them for their achievement. Emails to learners in credit eligible Programs will contain additional information.
    """
    user = User.objects.get(username=username)
    program_uuid = program_certificate.program_uuid
    program_details = program_certificate.program_details

    email_configuration = ProgramCompletionEmailConfiguration.get_email_config_for_program(
        program_uuid, program_details.type_slug)
    # If a config doesn't exist or isn't enabled, we don't want to send emails for this program.
    if not getattr(email_configuration, "enabled", None):
        log.info(
            f"Not sending program completion email to learner [{user.id}] "
            f"in program [{program_uuid}] because it's not enabled")
        return

    # Don't send out emails for retired programs
    if program_details.status == ProgramStatus.RETIRED.value:
        return

    try:
        msg = ProgramCertificateIssuedMessage(
            program_certificate.site, user.email
        ).personalize(
            recipient=Recipient(username=user.username,
                                email_address=user.email),
            language=program_certificate.language,
            user_context={
                "program_title":
                program_details.title,
                "program_type":
                program_details.type,
                "custom_email_html_template_extra":
                email_configuration.html_template,
                # remove any leading spaces of the plaintext content so that the email doesn't look horrendous
                "custom_email_plaintext_template_extra":
                textwrap.dedent(email_configuration.plaintext_template),
                "logo_url":
                getattr(settings, "LOGO_URL_PNG", ""),
            },
        )
        log.info(
            f"Sending Program completion email to learner with id [{user.id}] in Program [{program_uuid}]"
        )
        ace.send(msg)
    # We wouldn't want any issues that arise from formatting or sending this email message to interrupt the process
    # of issuing a learner their Program Certificate. We cast a wide net for exceptions here for this reason.
    except Exception as ex:  # pylint: disable=broad-except
        log.exception(
            f"Unable to send email to learner with id: [{user.id}] for Program [{program_uuid}]. "
            f"Error occurred while attempting to format or send message: {ex}")
Beispiel #3
0
def send_updated_emails_for_program(username, program_certificate):
    """ If the user has previously sent an email to a pathway org, we want to send
        an updated one when they finish the program.  This function is called from the
        credentials Program Certificate awarding API """
    site = program_certificate.site
    user = User.objects.get(username=username)
    program_uuid = program_certificate.program_uuid

    program = Program.objects.prefetch_related('pathways').get(
        site=site, uuid=program_uuid)
    pathways_set = frozenset(program.pathways.all())

    user_pathways = UserCreditPathway.objects.select_related('pathway').filter(
        user=user,
        pathway__in=pathways_set,
        status=UserCreditPathwayStatus.SENT)

    # Return here if the user doesn't have a program cert record
    try:
        pcr = ProgramCertRecord.objects.get(program=program, user=user)
    except ProgramCertRecord.DoesNotExist:
        logger.exception(
            "Program Cert Record for user_uuid %s, program_uuid %s does not exist",
            user.id, program.uuid)
        return

    # Send emails for those already marked as "SENT"
    for user_pathway in user_pathways:

        pathway = user_pathway.pathway
        record_path = reverse('records:public_programs',
                              kwargs={'uuid': pcr.uuid.hex})
        record_link = site.domain + record_path
        csv_link = urllib.parse.urljoin(record_link, "csv")

        msg = ProgramCreditRequest(site).personalize(
            recipient=Recipient(username=None, email_address=pathway.email),
            language=program_certificate.language,
            user_context={
                'pathway_name': pathway.name,
                'program_name': program.title,
                'record_link': record_link,
                'user_full_name': user.get_full_name(),
                'program_completed': True,
                'previously_sent': True,
                'csv_link': csv_link,
            },
        )
        ace.send(msg)
Beispiel #4
0
def send_program_certificate_created_message(username, program_certificate):
    """
    If the learner has earned a Program Certificate then we go ahead and send them an automated email congratulating
    them for their achievement. Emails to learners in credit eligible Programs will contain additional information.
    """
    user = User.objects.get(username=username)
    program_uuid = program_certificate.program_uuid
    program = Program.objects.get(site=program_certificate.site,
                                  uuid=program_uuid)

    custom_completion_email_settings = getattr(
        settings, 'CUSTOM_COMPLETION_EMAIL_TEMPLATE_EXTRA', {})
    custom_completion_email_content = (
        custom_completion_email_settings.get(str(program_uuid), {})
        or custom_completion_email_settings.get(program.type_slug, {}) or {})
    try:
        msg = ProgramCertificateIssuedMessage(
            program_certificate.site, user.email
        ).personalize(
            recipient=Recipient(username=user.username,
                                email_address=user.email),
            language=program_certificate.language,
            user_context={
                'program_title':
                program.title,
                'program_type':
                program.type,
                'custom_email_html_template_extra':
                custom_completion_email_content.get('html', ''),
                # remove any leading spaces of the plaintext content so that the email doesn't look horrendous
                'custom_email_plaintext_template_extra':
                textwrap.dedent(
                    custom_completion_email_content.get('plaintext', '')),
            },
        )
        log.info(
            "Sending Program completion email to learner with id [{}] in Program [{}]"
            .format(user.id, program_uuid))
        ace.send(msg)
    # We wouldn't want any issues that arise from formatting or sending this email message to interrupt the process
    # of issuing a learner their Program Certificate. We cast a wide net for exceptions here for this reason.
    except Exception as ex:  # pylint: disable=broad-except
        log.exception(
            "Unable to send email to learner with id: [{}] for Program [{}]. Error occurred while "
            "attempting to format or send message: {}".format(
                user.id, program_uuid, ex))
    def setUp(self):
        patcher = patch(
            'openedx.core.djangoapps.schedules.templatetags.ace.get_current_request'
        )
        self.mock_get_current_request = patcher.start()
        self.addCleanup(patcher.stop)

        self.fake_request = HttpRequest()
        self.fake_request.user = UserFactory.create()
        self.fake_request.site = SiteFactory.create()
        self.fake_request.site.domain = 'example.com'
        self.mock_get_current_request.return_value = self.fake_request

        self.message = Message(
            app_label='test_app_label',
            name='test_name',
            recipient=Recipient(username='******'),
            context={},
            send_uuid=uuid.uuid4(),
        )
        self.context = {'message': self.message}
Beispiel #6
0
    def setUp(self):
        super(EmailTemplateTagMixin, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments

        patcher = patch(
            'openedx.core.djangoapps.ace_common.templatetags.ace.get_current_request'
        )
        self.mock_get_current_request = patcher.start()
        self.addCleanup(patcher.stop)

        self.fake_request = HttpRequest()
        self.fake_request.user = UserFactory.create()
        self.fake_request.site = SiteFactory.create()
        self.fake_request.site.domain = 'example.com'
        self.mock_get_current_request.return_value = self.fake_request

        self.message = Message(
            app_label='test_app_label',
            name='test_name',
            recipient=Recipient(username='******'),
            context={},
            send_uuid=uuid.uuid4(),
        )
        self.context = {'message': self.message}