def setUp(self): self.product = create_product(num_in_stock=10) self.user_basket = Basket() self.user_basket.strategy = strategy.Default() add_product(self.user_basket, product=self.product) self.cookie_basket = Basket() self.cookie_basket.strategy = strategy.Default() add_product(self.cookie_basket, quantity=2, product=self.product) self.user_basket.merge(self.cookie_basket, add_quantities=False)
def setUp(self): self.product = factories.create_product() self.record = factories.create_stockrecord(self.product, price_excl_tax=D('10.00')) self.purchase_info = factories.create_purchase_info(self.record) self.main_basket = Basket() self.main_basket.strategy = strategy.Default() self.main_basket.add(self.product, quantity=2) self.merge_basket = Basket() self.merge_basket.strategy = strategy.Default() self.merge_basket.add(self.product, quantity=1) self.main_basket.merge(self.merge_basket)
def _get_basket(self, basket_id): if not basket_id: return None try: basket_id = int(basket_id) basket = Basket.objects.get(id=basket_id) basket.strategy = strategy.Default() # TODO: Remove as a part of REVMI-124 as this is a hacky solution # The problem is that orders are being created after payment processing, and the discount is not # saved in the database, so it needs to be calculated again in order to save the correct info to the # order. REVMI-124 will create the order before payment processing, when we have the discount context. self._add_dynamic_discount_to_request(basket) # End TODO Applicator().apply(basket, basket.owner, self.request) logger.info( 'Applicator applied, basket id: [%s]', basket.id) return basket except (ValueError, ObjectDoesNotExist) as error: logger.warning( 'Could not get basket--error: [%s]', str(error)) return None
def test_total_excludes_unavailable_products_with_unknown_price(self): new_product = factories.create_product() factories.create_stockrecord(new_product, price_excl_tax=D('5.00')) self.basket.add(new_product, 1) class UnavailableProductStrategy(strategy.Default): """ A test strategy that makes a specific product unavailable """ def availability_policy(self, product, stockrecord): if product == new_product: return availability.Unavailable() return super(UnavailableProductStrategy, self).availability_policy(product, stockrecord) def pricing_policy(self, product, stockrecord): if product == new_product: return prices.Unavailable() return super(UnavailableProductStrategy, self).pricing_policy(product, stockrecord) try: self.basket.strategy = UnavailableProductStrategy() self.assertEqual( self.basket.all_lines()[1].get_warning(), u"'D\xf9\uff4d\u03fb\u03d2 title' is no longer available") self.assertEqual(self.basket.total_excl_tax, 100) finally: self.basket.strategy = strategy.Default()
def create_order(number=None, basket=None, user=None, shipping_address=None, shipping_method=None, billing_address=None, total=None, **kwargs): """ Helper method for creating an order for testing """ if not basket: basket = Basket.objects.create() basket.strategy = strategy.Default() product = create_product() create_stockrecord( product, num_in_stock=10, price_excl_tax=D('10.00')) basket.add_product(product) if not basket.id: basket.save() if shipping_method is None: shipping_method = Free() if total is None: total = OrderTotalCalculator().calculate(basket, shipping_method) order = OrderCreator().place_order( order_number=number, user=user, basket=basket, shipping_address=shipping_address, shipping_method=shipping_method, billing_address=billing_address, total=total, **kwargs) basket.set_as_submitted() return order
def _get_basket(self, payment_id): """ Retrieve a basket using a payment ID. Arguments: payment_id: payment_id received from PayPal. Returns: It will return related basket or log exception and return None if duplicate payment_id received or any other exception occurred. """ try: basket = PaymentProcessorResponse.objects.get( processor_name=self.payment_processor.NAME, transaction_id=payment_id).basket basket.strategy = strategy.Default() return basket except MultipleObjectsReturned: logger.exception( u"Duplicate payment ID [%s] received from PayPal.", payment_id) return None except Exception: # pylint: disable=broad-except logger.exception( u"Unexpected error during basket retrieval while executing PayPal payment." ) return None
def setUp(self): self.basket = Basket() self.basket.strategy = strategy.Default() self.product = factories.create_product() self.record = factories.create_stockrecord(self.product, price_excl_tax=D('10.00')) self.purchase_info = factories.create_purchase_info(self.record) self.basket.add(self.product, 10)
def setUp(self): self.strategy = strategy.Default() parent = factories.create_product() factories.create_product(parent=parent, price=D('10.00'), num_in_stock=0) for x in range(2): factories.create_product(parent=parent) self.info = self.strategy.fetch_for_group(parent)
def create_basket(empty=False): basket = Basket.objects.create() basket.strategy = strategy.Default() if not empty: product = create_product() create_stockrecord(product) basket.add_product(product) return basket
def setUp(self): self.basket = Basket() self.basket.strategy = strategy.Default() self.product = factories.create_product() self.record = factories.create_stockrecord(currency='GBP', product=self.product, price=D('10.00')) self.purchase_info = factories.create_purchase_info(self.record) self.basket.add(self.product)
def test_can_reorder_a_previous_order(self): order_history_page = self.app.get( reverse('customer:order', args=[self.order.number]), user=self.user) form = order_history_page.forms['order_form_%d' % self.order.id] form.submit() basket = Basket.open.get(owner=self.user) basket.strategy = strategy.Default() self.assertEqual(1, basket.all_lines().count())
def test_line_tax_for_zero_tax_strategies(self): basket = Basket() basket.strategy = strategy.Default() product = factories.create_product() # Tax for the default strategy will be 0 factories.create_stockrecord( product, price_excl_tax=D('75.00'), num_in_stock=10) basket.add(product, 1) self.assertEqual(basket.lines.first().line_tax, D('0'))
def test_can_reorder_a_previous_order_line(self): order_history_page = self.app.get(reverse( 'customer:order', kwargs={'order_number': self.order.number}), user=self.user) line = self.order.lines.all()[0] form = order_history_page.forms['line_form_%d' % line.id] form.submit() basket = Basket.open.get(owner=self.user) basket.strategy = strategy.Default() self.assertEqual(1, basket.all_lines().count())
def test_totals_for_free_products(self): basket = Basket() basket.strategy = strategy.Default() # Add a zero-priced product to the basket product = factories.create_product() factories.create_stockrecord(product, price=D('0.00'), num_in_stock=10) basket.add(product, 1) self.assertEqual(basket.lines.count(), 1) self.assertEqual(basket.total_excl_tax, 0) self.assertEqual(basket.total_incl_tax, 0)
def _get_basket(self, payment_id): """ Retrieve a basket using a payment ID. Arguments: payment_id: payment_id received from PayPal. Returns: It will return related basket or log exception and return None if duplicate payment_id received or any other exception occurred. """ try: basket = PaymentProcessorResponse.objects.get( processor_name=self.payment_processor.NAME, transaction_id=payment_id).basket basket.strategy = strategy.Default() # TODO: Remove as a part of REVMI-124 as this is a hacky solution # The problem is that orders are being created after payment processing, and the discount is not # saved in the database, so it needs to be calculated again in order to save the correct info to the # order. REVMI-124 will create the order before payment processing, when we have the discount context. if waffle.flag_is_active( self.request, DYNAMIC_DISCOUNT_FLAG) and basket.lines.count() == 1: discount_lms_url = get_lms_url('/api/discounts/') lms_discount_client = EdxRestApiClient( discount_lms_url, jwt=self.request.site.siteconfiguration.access_token) ck = basket.lines.first().product.course_id user_id = self.request.user.lms_user_id try: response = lms_discount_client.user(user_id).course( ck).get() self.request.GET = self.request.GET.copy() self.request.GET['discount_jwt'] = response.get('jwt') except (SlumberHttpBaseException, Timeout) as error: logger.warning( 'Failed to get discount jwt from LMS. [%s] returned [%s]', discount_lms_url, error.response) # END TODO Applicator().apply(basket, basket.owner, self.request) basket_add_organization_attribute(basket, self.request.GET) return basket except MultipleObjectsReturned: logger.warning(u"Duplicate payment ID [%s] received from PayPal.", payment_id) return None except Exception: # pylint: disable=broad-except logger.exception( u"Unexpected error during basket retrieval while executing PayPal payment." ) return None
def _get_basket(self, basket_id): if not basket_id: return None try: basket_id = int(basket_id) basket = Basket.objects.get(id=basket_id) basket.strategy = strategy.Default() return basket except (ValueError, ObjectDoesNotExist): return None
def _get_basket(self, basket_id): if not basket_id: return None try: basket_id = int(basket_id) basket = Basket.objects.get(id=basket_id) basket.strategy = strategy.Default() Applicator().apply(basket, basket.owner, self.request) return basket except (ValueError, ObjectDoesNotExist): return None
def _get_basket(self, basket_id): if not basket_id: return None try: basket_id = int(basket_id) basket = Basket.objects.get(id=basket_id) basket.strategy = strategy.Default() # TODO: Remove as a part of REVMI-124 as this is a hacky solution # The problem is that orders are being created after payment processing, and the discount is not # saved in the database, so it needs to be calculated again in order to save the correct info to the # order. REVMI-124 will create the order before payment processing, when we have the discount context. if waffle.flag_is_active(self.request, DYNAMIC_DISCOUNT_FLAG) and basket.lines.count() == 1: # pragma: no cover pylint: disable=line-too-long discount_lms_url = get_lms_url('/api/discounts/') lms_discount_client = EdxRestApiClient( discount_lms_url, jwt=self.request.site.siteconfiguration.access_token) ck = basket.lines.first().product.course_id user_id = basket.owner.lms_user_id try: response = lms_discount_client.user(user_id).course( ck).get() self.request.POST = self.request.POST.copy() self.request.POST['discount_jwt'] = response.get('jwt') logger.info( """Received discount jwt from LMS with url: [%s], user_id: [%s], course_id: [%s], and basket_id: [%s] returned [%s]""", discount_lms_url, str(user_id), ck, basket.id, response) except (SlumberHttpBaseException, requests.exceptions.Timeout) as error: logger.warning( """Failed to receive discount jwt from LMS with url: [%s], user_id: [%s], course_id: [%s], and basket_id: [%s] returned [%s]""", discount_lms_url, str(user_id), ck, basket.id, vars(error.response) if hasattr(error, 'response') else '') # End TODO Applicator().apply(basket, basket.owner, self.request) logger.info('Applicator applied, basket id: [%s]', basket.id) return basket except (ValueError, ObjectDoesNotExist) as error: logger.warning('Could not get basket--error: [%s]', str(error)) return None
def add_product(basket, price=None, quantity=1, product=None): """ Helper to add a product to the basket. """ if not hasattr(basket, 'strategy'): basket.strategy = strategy.Default() if price is None: price = D('1') if product and product.has_stockrecords: record = product.stockrecords.all()[0] else: record = factories.create_stockrecord(product=product, price_excl_tax=price, num_in_stock=quantity + 1) basket.add_product(record.product, quantity)
def _get_basket(self, basket_id): if not basket_id: return None try: basket_id = int(basket_id) basket = Basket.objects.get(id=basket_id) basket.strategy = strategy.Default() Applicator().apply(basket, basket.owner, self.request) logger.info('Applicator applied, basket id: [%s]', basket.id) return basket except (ValueError, ObjectDoesNotExist) as error: logger.warning('Could not get basket--error: [%s]', str(error)) return None
def get_basket(self, basket_id): """ Retrieve a basket using a basket Id. Arguments: payment_id: payment_id received from AuthorizeNet. Returns: It will return related basket """ if not basket_id: return None try: basket = Basket.objects.get(id=basket_id) basket.strategy = strategy.Default() return basket except (ValueError, ObjectDoesNotExist): return None
def test_basket_lines_are_converted_to_xml(self): product = factories.create_product(price=D('12.99')) basket = Basket() # Nasty hack to make test suite work with both Oscar 0.5 and 0.6 try: from oscar.apps.partner import strategy except ImportError: pass else: basket.strategy = strategy.Default() basket.add_product(product) data = the3rdman.build_data_dict(basket=basket) doc = the3rdman.add_fraud_fields(**data) xml = doc.toxml() self.assertXmlElementEquals( xml, '3', 'The3rdMan.CustomerInformation.sales_channel')
def test_cannot_reorder_line_when_basket_maximum_exceeded(self): order = create_order(user=self.user) line = order.lines.all()[0] product = create_product(price=D('12.00')) product_page = self.get(line.product.get_absolute_url()) product_page.forms['add_to_basket_form'].submit() basket = Basket.objects.all()[0] basket.strategy = strategy.Default() self.assertEqual(len(basket.all_lines()), 1) # Try to reorder a line order_page = self.get(reverse('customer:order', args=(order.number,))) order_page.forms['line_form_%s' % line.id].submit() self.assertEqual(len(basket.all_lines()), 1) self.assertNotEqual(line.product.pk, product.pk)
def refund_basket_transactions(site, basket_ids): baskets = Basket.objects.filter(site=site, id__in=basket_ids) success_count = 0 failure_count = 0 for basket in baskets: basket.strategy = strategy.Default() Applicator().apply(basket, basket.owner, None) logger.info('Refunding transactions for basket [%d]...', basket.id) transactions = set( list( basket.paymentprocessorresponse_set.values_list( 'processor_name', 'transaction_id'))) for processor_name, transaction_id in transactions: try: logger.info( 'Issuing credit for [%s] transaction [%s] made against basket [%d]...', processor_name, transaction_id, basket.id) payment_processor = _get_payment_processor( site, processor_name) payment_processor.issue_credit(basket.order_number, basket, transaction_id, basket.total_excl_tax, basket.currency) success_count += 1 logger.info( 'Successfully issued credit for [%s] transaction [%s] made against basket [%d].', processor_name, transaction_id, basket.id) except Exception: # pylint: disable=broad-except failure_count += 1 logger.exception( 'Failed to issue credit for [%s] transaction [%s] made against basket [%d].', processor_name, transaction_id, basket.id) logger.info('Finished processing refunds for basket [%d].', basket.id) msg = 'Finished refunding basket transactions. [{success_count}] transactions were successfully refunded. ' \ '[{failure_count}] attempts failed.'.format(success_count=success_count, failure_count=failure_count) logger.info(msg) return success_count, failure_count
def test_cannot_reorder_line_when_basket_maximum_exceeded(self): order = create_order(user=self.user) line = order.lines.all()[0] # add a product product = create_product(price=D('12.00')) self.client.post(reverse('basket:add'), { 'product_id': product.id, 'quantity': 1 }) basket = Basket.objects.all()[0] basket.strategy = strategy.Default() self.assertEquals(len(basket.all_lines()), 1) self.client.post( reverse('customer:order-line', args=(order.number, line.pk)), {'action': 'reorder'}) self.assertEquals(len(basket.all_lines()), 1) self.assertNotEqual(line.product.pk, product.pk)
def _get_basket(self, payment_id): """ Retrieve a basket using a payment ID. Arguments: payment_id: payment_id received from PayPal. Returns: It will return related basket or log exception and return None if duplicate payment_id received or any other exception occurred. """ try: basket = PaymentProcessorResponse.objects.get( processor_name=self.payment_processor.NAME, transaction_id=payment_id).basket basket.strategy = strategy.Default() # TODO: Remove as a part of REVMI-124 as this is a hacky solution # The problem is that orders are being created after payment processing, and the discount is not # saved in the database, so it needs to be calculated again in order to save the correct info to the # order. REVMI-124 will create the order before payment processing, when we have the discount context. self._add_dynamic_discount_to_request(basket) # END TODO Applicator().apply(basket, basket.owner, self.request) basket_add_organization_attribute(basket, self.request.GET) return basket except MultipleObjectsReturned: logger.warning(u"Duplicate payment ID [%s] received from PayPal.", payment_id) return None except Exception: # pylint: disable=broad-except logger.exception( u"Unexpected error during basket retrieval while executing PayPal payment." ) return None
def get(self, request, ppr_id): ppr = get_object_or_404(PaymentProcessorResponse, id=ppr_id) basket = ppr.basket basket.strategy = strategy.Default() # What follows is basically a copy-paste from paypal's GET view handler receipt_url = get_receipt_page_url( order_number=basket.order_number, site_configuration=basket.site.siteconfiguration, disable_back_button=True, ) try: with transaction.atomic(): try: self.handle_payment(ppr.transaction_id, basket) except PaymentError: return redirect(self.payment_processor.error_url) except PaymentError: return redirect(self.payment_processor.error_url) except: # pylint: disable=bare-except logger.exception( "Attempts to handle payment for basket [%d] failed.", basket.id) return redirect(receipt_url) try: order = self.create_order(request, basket) except Exception: # pylint: disable=broad-except return redirect(receipt_url) try: self.handle_post_order(order) except Exception: # pylint: disable=broad-except self.log_order_placement_exception(basket.order_number, basket.id) return redirect(receipt_url)
def _get_basket(self, payment_id): """ Retrieve a basket using a payment ID. Arguments: payment_id: payment_id received from Alipay. Returns: """ try: basket = PaymentProcessorResponse.objects.get( processor_name=self.payment_processor.NAME, transaction_id=payment_id).basket basket.strategy = strategy.Default() Applicator().apply(basket, basket.owner, self.request) basket_add_organization_attribute(basket, self.request.GET) return basket except MultipleObjectsReturned: return None except Exception, e: logger.exception(e) return None
def setUp(self): self.basket = Basket() self.basket.strategy = strategy.Default()
def setUp(self): self.strategy = strategy.Default() parent = factories.create_product() for x in range(3): factories.create_product(parent=parent) self.info = self.strategy.fetch_for_group(parent)