コード例 #1
0
 def test_ecu_needs_consent(self):
     opts = {
         'ec_uuid': 'fake-uuid',
         'course_id': 'course-v1:real+course+id',
         'username': '******',
     }
     kw = {
         'enterprise_customer_uuid': 'fake-uuid',
         'course_id': 'course-v1:real+course+id',
         'username': '******',
         'site': self.site
     }
     self.mock_access_token_response()
     self.mock_consent_get(**opts)
     self.assertEqual(enterprise_customer_user_needs_consent(**kw), False)
     self.mock_consent_missing(**opts)
     self.assertEqual(enterprise_customer_user_needs_consent(**kw), True)
     self.mock_consent_not_required(**opts)
     self.assertEqual(enterprise_customer_user_needs_consent(**kw), False)
コード例 #2
0
    def test_ecu_needs_consent_no_link(self, ec_consent_enabled,
                                       expected_consent_requirement):
        """
        Test that when there's no EnterpriseCustomerUser, the consent requirement comes down
        to whether the EnterpriseCustomer wants consent.
        """
        self.mock_access_token_response()
        self.mock_enterprise_learner_api_for_learner_with_no_enterprise()
        uuid = TEST_ENTERPRISE_CUSTOMER_UUID
        self.mock_specific_enterprise_customer_api(
            uuid, consent_enabled=ec_consent_enabled)

        consent_needed = enterprise_customer_user_needs_consent(
            self.site, TEST_ENTERPRISE_CUSTOMER_UUID,
            'course-v1:edX+DemoX+Demo_Course', 'admin')
        self.assertEqual(consent_needed, expected_consent_requirement)
コード例 #3
0
    def test_ecu_needs_consent_link_exists(self, account_consent_provided,
                                           course_consent_provided,
                                           consent_enabled, results_present,
                                           expected_consent_requirement):
        self.mock_access_token_response()
        uuid = TEST_ENTERPRISE_CUSTOMER_UUID
        self.mock_enterprise_learner_api(
            enterprise_customer_uuid=uuid,
            consent_provided=account_consent_provided,
            consent_enabled=consent_enabled,
        )
        self.mock_enterprise_course_enrollment_api(
            consent_granted=course_consent_provided,
            results_present=results_present,
        )

        consent_needed = enterprise_customer_user_needs_consent(
            self.site, TEST_ENTERPRISE_CUSTOMER_UUID,
            'course-v1:edX+DemoX+Demo_Course', 'admin')
        self.assertEqual(consent_needed, expected_consent_requirement)
コード例 #4
0
ファイル: views.py プロジェクト: dario617/ecommerce
 def _redirect_for_enterprise_data_sharing_consent(self, basket):
     """
     Redirect to LMS to get data sharing consent from learner.
     """
     # check if basket contains only a single product of type seat
     if basket.lines.count() == 1 and basket.lines.first(
     ).product.is_seat_product:
         enterprise_custmer_uuid = get_enterprise_customer_from_enterprise_offer(
             basket)
         product = basket.lines.first().product
         course = product.course
         if enterprise_custmer_uuid is not None and enterprise_customer_user_needs_consent(
                 self.request.site,
                 enterprise_custmer_uuid,
                 course.id,
                 self.request.user.username,
         ):
             redirect_url = construct_enterprise_course_consent_url(
                 self.request, product.course.id, enterprise_custmer_uuid)
             raise RedirectException(
                 response=HttpResponseRedirect(redirect_url))
コード例 #5
0
ファイル: views.py プロジェクト: sameenfatima78/ecommerce
    def get(self, request):  # pylint: disable=too-many-statements
        """
        Looks up the passed code and adds the matching product to a basket,
        then applies the voucher and if the basket total is FREE places the order and
        enrolls the user in the course.
        """
        template_name = 'coupons/_offer_error.html'
        code = request.GET.get('code')
        sku = request.GET.get('sku')
        failure_url = request.GET.get('failure_url')
        site_configuration = request.site.siteconfiguration

        if not code:
            return render(request, template_name,
                          {'error': _('Code not provided.')})
        if not sku:
            return render(request, template_name,
                          {'error': _('SKU not provided.')})

        try:
            voucher = Voucher.objects.get(code=code)
        except Voucher.DoesNotExist:
            msg = 'No voucher found with code {code}'.format(code=code)
            return render(request, template_name, {'error': _(msg)})

        try:
            product = StockRecord.objects.get(partner_sku=sku).product
        except StockRecord.DoesNotExist:
            return render(request, template_name,
                          {'error': _('The product does not exist.')})

        valid_voucher, msg = voucher_is_valid(voucher, [product], request)
        if not valid_voucher:
            logger.warning(
                '[Code Redemption Failure] The voucher is not valid for this product. '
                'User: %s, Product: %s, Code: %s, Message: %s',
                request.user.username, product.id, voucher.code, msg)
            return render(request, template_name, {'error': msg})

        offer = voucher.best_offer
        if not offer.is_email_valid(request.user.email):
            logger.warning(
                '[Code Redemption Failure] Unable to apply offer because the user\'s email '
                'does not meet the domain requirements. '
                'User: %s, Offer: %s, Code: %s', request.user.username,
                offer.id, voucher.code)
            return render(
                request, template_name,
                {'error': _('You are not eligible to use this coupon.')})

        email_confirmation_response = get_redirect_to_email_confirmation_if_required(
            request, offer, product)
        if email_confirmation_response:
            return email_confirmation_response

        try:
            enterprise_customer = get_enterprise_customer_from_voucher(
                request.site, voucher)
        except EnterpriseDoesNotExist as e:
            # If an EnterpriseException is caught while pulling the EnterpriseCustomer, that means there's no
            # corresponding EnterpriseCustomer in the Enterprise service (which should never happen).
            logger.exception(six.text_type(e))
            return render(
                request, template_name, {
                    'error':
                    _('Couldn\'t find a matching Enterprise Customer for this coupon.'
                      )
                })

        if enterprise_customer and product.is_course_entitlement_product:
            return render(
                request, template_name, {
                    'error':
                    _('This coupon code is not valid for entitlement course product. Try a different course.'
                      )
                })

        if enterprise_customer is not None and enterprise_customer_user_needs_consent(
                request.site,
                enterprise_customer['id'],
                product.course.id,
                request.user.username,
        ):
            consent_token = get_enterprise_customer_data_sharing_consent_token(
                request.user.access_token, product.course.id,
                enterprise_customer['id'])
            received_consent_token = request.GET.get('consent_token')
            if received_consent_token:
                # If the consent token is set, then the user is returning from the consent view. Render out an error
                # if the computed token doesn't match the one received from the redirect URL.
                if received_consent_token != consent_token:
                    logger.warning(
                        '[Code Redemption Failure] Unable to complete code redemption because of '
                        'invalid consent. User: %s, Offer: %s, Code: %s',
                        request.user.username, offer.id, voucher.code)
                    return render(request, template_name, {
                        'error':
                        _('Invalid data sharing consent token provided.')
                    })
            else:
                # The user hasn't been redirected to the interstitial consent view to collect consent, so
                # redirect them now.
                redirect_url = get_enterprise_course_consent_url(
                    request.site,
                    code,
                    sku,
                    consent_token,
                    product.course.id,
                    enterprise_customer['id'],
                    failure_url=failure_url)
                return HttpResponseRedirect(redirect_url)

        try:
            basket = prepare_basket(request, [product], voucher)
        except AlreadyPlacedOrderException:
            msg = _('You have already purchased {course} seat.').format(
                course=product.course.name)
            return render(request, template_name, {'error': msg})

        if basket.total_excl_tax == 0:
            try:
                order = self.place_free_order(basket)
                return HttpResponseRedirect(
                    get_receipt_page_url(
                        site_configuration,
                        order.number,
                        disable_back_button=True,
                    ), )
            except:  # pylint: disable=bare-except
                logger.exception(
                    'Failed to create a free order for basket [%d]', basket.id)
                return absolute_redirect(self.request, 'checkout:error')

        if enterprise_customer:
            if is_voucher_applied(basket, voucher):
                message = _(
                    'A discount has been applied, courtesy of {enterprise_customer_name}.'
                ).format(
                    enterprise_customer_name=enterprise_customer.get('name'))
                messages.info(self.request, message)
            else:
                # Display a generic message to the user if a condition-specific
                # message has not already been added by an unsatified Condition class.
                if not messages.get_messages(self.request):
                    messages.warning(
                        self.request,
                        _('This coupon code is not valid for this course. Try a different course.'
                          ))
                self.request.basket.vouchers.remove(voucher)

        # The coupon_redeem_redirect query param is used to communicate to the Payment MFE that it may redirect
        # and should not display the payment form before making that determination.
        # TODO: It would be cleaner if the user could be redirected to their final destination up front.
        redirect_url = get_payment_microfrontend_or_basket_url(
            self.request) + "?coupon_redeem_redirect=1"
        return HttpResponseRedirect(redirect_url)
コード例 #6
0
    def get(self, request):
        """
        Looks up the passed code and adds the matching product to a basket,
        then applies the voucher and if the basket total is FREE places the order and
        enrolls the user in the course.
        """
        template_name = 'coupons/_offer_error.html'
        code = request.GET.get('code')
        sku = request.GET.get('sku')
        failure_url = request.GET.get('failure_url')
        site_configuration = request.site.siteconfiguration

        if not code:
            return render(request, template_name,
                          {'error': _('Code not provided.')})
        if not sku:
            return render(request, template_name,
                          {'error': _('SKU not provided.')})

        try:
            voucher = Voucher.objects.get(code=code)
        except Voucher.DoesNotExist:
            msg = 'No voucher found with code {code}'.format(code=code)
            return render(request, template_name, {'error': _(msg)})

        try:
            product = StockRecord.objects.get(partner_sku=sku).product
        except StockRecord.DoesNotExist:
            return render(request, template_name,
                          {'error': _('The product does not exist.')})

        valid_voucher, msg = voucher_is_valid(voucher, [product], request)
        if not valid_voucher:
            return render(request, template_name, {'error': msg})

        offer = voucher.offers.first()
        if not offer.is_email_valid(request.user.email):
            return render(
                request, template_name,
                {'error': _('You are not eligible to use this coupon.')})

        email_confirmation_response = render_email_confirmation_if_required(
            request, offer, product)
        if email_confirmation_response:
            return email_confirmation_response

        try:
            enterprise_customer = get_enterprise_customer_from_voucher(
                request.site, voucher)
        except EnterpriseDoesNotExist as e:
            # If an EnterpriseException is caught while pulling the EnterpriseCustomer, that means there's no
            # corresponding EnterpriseCustomer in the Enterprise service (which should never happen).
            logger.exception(e.message)
            return render(
                request, template_name, {
                    'error':
                    _('Couldn\'t find a matching Enterprise Customer for this coupon.'
                      )
                })

        if enterprise_customer is not None and enterprise_customer_user_needs_consent(
                request.site,
                enterprise_customer['id'],
                product.course.id,
                request.user.username,
        ):
            consent_token = get_enterprise_customer_data_sharing_consent_token(
                request.user.access_token, product.course.id,
                enterprise_customer['id'])
            received_consent_token = request.GET.get('consent_token')
            if received_consent_token:
                # If the consent token is set, then the user is returning from the consent view. Render out an error
                # if the computed token doesn't match the one received from the redirect URL.
                if received_consent_token != consent_token:
                    return render(request, template_name, {
                        'error':
                        _('Invalid data sharing consent token provided.')
                    })
            else:
                # The user hasn't been redirected to the interstitial consent view to collect consent, so
                # redirect them now.
                redirect_url = get_enterprise_course_consent_url(
                    request.site,
                    code,
                    sku,
                    consent_token,
                    product.course.id,
                    enterprise_customer['id'],
                    failure_url=failure_url)
                return HttpResponseRedirect(redirect_url)

        try:
            basket = prepare_basket(request, [product], voucher)
        except AlreadyPlacedOrderException:
            msg = _('You have already purchased {course} seat.').format(
                course=product.course.name)
            return render(request, template_name, {'error': msg})

        if basket.total_excl_tax == 0:
            try:
                order = self.place_free_order(basket)
                return HttpResponseRedirect(
                    get_receipt_page_url(site_configuration, order.number))
            except:  # pylint: disable=bare-except
                logger.exception(
                    'Failed to create a free order for basket [%d]', basket.id)
                return HttpResponseRedirect(reverse('checkout:error'))

        if enterprise_customer:
            if is_voucher_applied(basket, voucher):
                message = _(
                    'A discount has been applied, courtesy of {enterprise_customer_name}.'
                ).format(
                    enterprise_customer_name=enterprise_customer.get('name'))
                message = '<i class="fa fa-info-circle"></i> {}'.format(
                    message)
                messages.info(self.request, message, extra_tags='safe')
            else:
                messages.warning(
                    self.request,
                    _('This coupon code is not valid for this course. Try a different course.'
                      ))
                self.request.basket.vouchers.remove(voucher)

        return HttpResponseRedirect(reverse('basket:summary'))