def get_offers_from_catalog(self, request, voucher): """ Helper method for collecting offers from catalog query or enterprise catalog. Args: request (WSGIRequest): Request data. voucher (Voucher): Oscar Voucher for which the offers are returned. Returns: A list of dictionaries with retrieved offers and a link to the next page of the Course Discovery results. """ benefit = voucher.best_offer.benefit condition = voucher.best_offer.condition # Pull all catalog related data from the offer. catalog_query = benefit.range.catalog_query if benefit.range else None catalog_id = benefit.range.course_catalog if benefit.range else None enterprise_customer = (condition.enterprise_customer_uuid or (benefit.range and benefit.range.enterprise_customer)) enterprise_catalog = (condition.enterprise_customer_catalog_uuid or (benefit.range and benefit.range.enterprise_customer_catalog)) if catalog_id: catalog = fetch_course_catalog(request.site, catalog_id) catalog_query = catalog.get("query") if catalog else catalog_query # There is no catalog related data specified for this condition, so return None. if not catalog_query and not enterprise_customer: return None, None if enterprise_catalog: response = get_enterprise_catalog( site=request.site, enterprise_catalog=enterprise_catalog, limit=request.GET.get('limit', DEFAULT_CATALOG_PAGE_SIZE), page=request.GET.get('page'), ) elif catalog_query: response = get_catalog_course_runs( site=request.site, query=catalog_query, limit=request.GET.get('limit', DEFAULT_CATALOG_PAGE_SIZE), offset=request.GET.get('offset'), ) else: logger.warning( 'User is trying to redeem Voucher %s, but no catalog information is configured!', voucher.code) return [], None next_page = response['next'] offers = self.convert_catalog_response_to_offers( request, voucher, response) return offers, next_page
def test_fetch_course_catalog(self): """ Verify that fetch_course_catalog is cached We expect 2 calls to set_all_tiers due to: - the site_configuration api setup - the result being cached """ self.mock_access_token_response() self.mock_catalog_detail_endpoint(self.site_configuration.discovery_api_url) with patch.object(TieredCache, 'set_all_tiers', wraps=TieredCache.set_all_tiers) as mocked_set_all_tiers: mocked_set_all_tiers.assert_not_called() _ = fetch_course_catalog(self.site, 1) self.assertEqual(mocked_set_all_tiers.call_count, 2) _ = fetch_course_catalog(self.site, 1) self.assertEqual(mocked_set_all_tiers.call_count, 2)
def get_offers(self, request, voucher): """ Get the course offers associated with the voucher. Arguments: request (HttpRequest): Request data. voucher (Voucher): Oscar Voucher for which the offers are returned. Returns: dict: Dictionary containing a link to the next page of Course Discovery results and a List of course offers where each offer is represented as a dictionary. """ benefit = voucher.offers.first().benefit catalog_query = benefit.range.catalog_query catalog_id = benefit.range.course_catalog enterprise_catalog = benefit.range.enterprise_customer_catalog next_page = None offers = [] if catalog_id: catalog = fetch_course_catalog(request.site, catalog_id) catalog_query = catalog.get("query") if catalog else catalog_query if catalog_query or enterprise_catalog: offers, next_page = self.get_offers_from_catalog( request, voucher, catalog_query, enterprise_catalog) else: product_range = voucher.offers.first().benefit.range products = product_range.all_products() if products: product = products[0] else: raise Product.DoesNotExist course_id = product.course_id course = get_object_or_404(Course, id=course_id) stock_record = get_object_or_404(StockRecord, product__id=product.id) course_info = get_course_info_from_catalog(request.site, product) if course_info: offers.append( self.get_course_offer_data( benefit=benefit, course=course, course_info=course_info, credit_provider_price=None, multiple_credit_providers=False, is_verified=(course.type == 'verified'), product=product, stock_record=stock_record, voucher=voucher)) return {'next': next_page, 'results': offers}