Exemplo n.º 1
0
    def _collect_one_click_purchase_eligibility_data(self):
        """
        Extend the program data with data about learner's eligibility for one click purchase,
        discount data of the program and SKUs of seats that should be added to basket.
        """
        if 'professional' in self.data['applicable_seat_types']:
            self.data['applicable_seat_types'].append('no-id-professional')
        applicable_seat_types = set(
            seat for seat in self.data['applicable_seat_types']
            if seat != 'credit')

        is_learner_eligible_for_one_click_purchase = self.data[
            'is_program_eligible_for_one_click_purchase']
        bundle_uuid = self.data.get('uuid')
        skus = []
        bundle_variant = 'full'

        if is_learner_eligible_for_one_click_purchase:
            courses = self.data['courses']
            if not self.user.is_anonymous:
                courses = self._filter_out_courses_with_enrollments(courses)
                courses = self._filter_out_courses_with_entitlements(courses)

            if len(courses) < len(self.data['courses']):
                bundle_variant = 'partial'

            for course in courses:
                entitlement_product = False
                for entitlement in course.get('entitlements', []):
                    # We add the first entitlement product found with an applicable seat type because, at this time,
                    # we are assuming that, for any given course, there is at most one paid entitlement available.
                    if entitlement['mode'] in applicable_seat_types:
                        skus.append(entitlement['sku'])
                        entitlement_product = True
                        break
                if not entitlement_product:
                    course_runs = course.get('course_runs', [])
                    published_course_runs = [
                        run for run in course_runs
                        if run['status'] == 'published'
                    ]
                    if len(published_course_runs) == 1:
                        for seat in published_course_runs[0]['seats']:
                            if seat['type'] in applicable_seat_types and seat[
                                    'sku']:
                                skus.append(seat['sku'])
                                break
                    else:
                        # If a course in the program has more than 1 published course run
                        # learner won't be eligible for a one click purchase.
                        skus = []
                        break

        if skus:
            try:
                api_user = self.user
                is_anonymous = False
                if not self.user.is_authenticated:
                    user = get_user_model()
                    service_user = user.objects.get(
                        username=settings.ECOMMERCE_SERVICE_WORKER_USERNAME)
                    api_user = service_user
                    is_anonymous = True

                api = ecommerce_api_client(api_user)

                # The user specific program price is slow to calculate, so use switch to force the
                # anonymous price for all users. See LEARNER-5555 for more details.
                if is_anonymous or ALWAYS_CALCULATE_PROGRAM_PRICE_AS_ANONYMOUS_USER.is_enabled(
                ):
                    # The bundle uuid is necessary to see the program's discounted price
                    if bundle_uuid:
                        discount_data = api.baskets.calculate.get(
                            sku=skus, is_anonymous=True, bundle=bundle_uuid)
                    else:
                        discount_data = api.baskets.calculate.get(
                            sku=skus, is_anonymous=True)
                else:
                    if bundle_uuid:
                        discount_data = api.baskets.calculate.get(
                            sku=skus,
                            username=self.user.username,
                            bundle=bundle_uuid)
                    else:
                        discount_data = api.baskets.calculate.get(
                            sku=skus, username=self.user.username)

                program_discounted_price = discount_data['total_incl_tax']
                program_full_price = discount_data[
                    'total_incl_tax_excl_discounts']
                discount_data[
                    'is_discounted'] = program_discounted_price < program_full_price
                discount_data[
                    'discount_value'] = program_full_price - program_discounted_price

                self.data.update({
                    'discount_data':
                    discount_data,
                    'full_program_price':
                    discount_data['total_incl_tax'],
                    'variant':
                    bundle_variant
                })
            except (ConnectionError, SlumberBaseException, Timeout):
                log.exception(
                    u'Failed to get discount price for following product SKUs: %s ',
                    ', '.join(skus))
                self.data.update({'discount_data': {'is_discounted': False}})
        else:
            is_learner_eligible_for_one_click_purchase = False

        self.data.update({
            'is_learner_eligible_for_one_click_purchase':
            is_learner_eligible_for_one_click_purchase,
            'skus': skus,
        })
Exemplo n.º 2
0
    def _collect_one_click_purchase_eligibility_data(self):
        """
        Extend the program data with data about learner's eligibility for one click purchase,
        discount data of the program and SKUs of seats that should be added to basket.
        """
        if 'professional' in self.data['applicable_seat_types']:
            self.data['applicable_seat_types'].append('no-id-professional')
        applicable_seat_types = set(seat for seat in self.data['applicable_seat_types'] if seat != 'credit')

        is_learner_eligible_for_one_click_purchase = self.data['is_program_eligible_for_one_click_purchase']
        skus = []
        bundle_variant = 'full'

        if is_learner_eligible_for_one_click_purchase:
            courses = self.data['courses']
            if not self.user.is_anonymous:
                courses = self._filter_out_courses_with_enrollments(courses)
                courses = self._filter_out_courses_with_entitlements(courses)

            if len(courses) < len(self.data['courses']):
                bundle_variant = 'partial'

            for course in courses:
                entitlement_product = False
                for entitlement in course.get('entitlements', []):
                    # We add the first entitlement product found with an applicable seat type because, at this time,
                    # we are assuming that, for any given course, there is at most one paid entitlement available.
                    if entitlement['mode'] in applicable_seat_types:
                        skus.append(entitlement['sku'])
                        entitlement_product = True
                        break
                if not entitlement_product:
                    course_runs = course.get('course_runs', [])
                    published_course_runs = [run for run in course_runs if run['status'] == 'published']
                    if len(published_course_runs) == 1:
                        for seat in published_course_runs[0]['seats']:
                            if seat['type'] in applicable_seat_types and seat['sku']:
                                skus.append(seat['sku'])
                                break
                    else:
                        # If a course in the program has more than 1 published course run
                        # learner won't be eligible for a one click purchase.
                        skus = []
                        break

        if skus:
            try:
                api_user = self.user
                is_anonymous = False
                if not self.user.is_authenticated:
                    user = get_user_model()
                    service_user = user.objects.get(username=settings.ECOMMERCE_SERVICE_WORKER_USERNAME)
                    api_user = service_user
                    is_anonymous = True

                api = ecommerce_api_client(api_user)

                # The user specific program price is slow to calculate, so use switch to force the
                # anonymous price for all users. See LEARNER-5555 for more details.
                if is_anonymous or ALWAYS_CALCULATE_PROGRAM_PRICE_AS_ANONYMOUS_USER.is_enabled():
                    discount_data = api.baskets.calculate.get(sku=skus, is_anonymous=True)
                else:
                    discount_data = api.baskets.calculate.get(sku=skus, username=self.user.username)

                program_discounted_price = discount_data['total_incl_tax']
                program_full_price = discount_data['total_incl_tax_excl_discounts']
                discount_data['is_discounted'] = program_discounted_price < program_full_price
                discount_data['discount_value'] = program_full_price - program_discounted_price

                self.data.update({
                    'discount_data': discount_data,
                    'full_program_price': discount_data['total_incl_tax'],
                    'variant': bundle_variant
                })
            except (ConnectionError, SlumberBaseException, Timeout):
                log.exception(u'Failed to get discount price for following product SKUs: %s ', ', '.join(skus))
                self.data.update({
                    'discount_data': {'is_discounted': False}
                })
        else:
            is_learner_eligible_for_one_click_purchase = False

        self.data.update({
            'is_learner_eligible_for_one_click_purchase': is_learner_eligible_for_one_click_purchase,
            'skus': skus,
        })