Example #1
0
    def test_course_registration_features(self):
        query_features = ['code', 'course_id', 'transaction_group_name', 'created_by', 'redeemed_by']
        for i in range(5):
            course_code = CourseRegistrationCode(
                code="test_code{}".format(i), course_id=self.course_key.to_deprecated_string(),
                transaction_group_name='TestName', created_by=self.users[0]
            )
            course_code.save()

        order = Order(user=self.users[0], status='purchased')
        order.save()

        registration_code_redemption = RegistrationCodeRedemption(
            order=order, registration_code_id=1, redeemed_by=self.users[0]
        )
        registration_code_redemption.save()
        registration_codes = CourseRegistrationCode.objects.all()
        course_registration_list = course_registration_features(query_features, registration_codes, csv_type='download')
        self.assertEqual(len(course_registration_list), len(registration_codes))
        for course_registration in course_registration_list:
            self.assertEqual(set(course_registration.keys()), set(query_features))
            self.assertIn(course_registration['code'], [registration_code.code for registration_code in registration_codes])
            self.assertIn(
                course_registration['course_id'],
                [registration_code.course_id.to_deprecated_string() for registration_code in registration_codes]
            )
            self.assertIn(
                course_registration['transaction_group_name'],
                [registration_code.transaction_group_name for registration_code in registration_codes]
            )
Example #2
0
    def test_course_registration_features(self):
        query_features = [
            'code', 'redeem_code_url', 'course_id', 'company_name', 'created_by',
            'redeemed_by', 'invoice_id', 'purchaser', 'customer_reference_number', 'internal_reference'
        ]
        order = Order(user=self.instructor, status='purchased')
        order.save()

        registration_code_redemption = RegistrationCodeRedemption(
            registration_code_id=1, redeemed_by=self.instructor
        )
        registration_code_redemption.save()
        registration_codes = CourseRegistrationCode.objects.all()
        course_registration_list = course_registration_features(query_features, registration_codes, csv_type='download')
        self.assertEqual(len(course_registration_list), len(registration_codes))
        for course_registration in course_registration_list:
            self.assertEqual(set(course_registration.keys()), set(query_features))
            self.assertIn(course_registration['code'], [registration_code.code for registration_code in registration_codes])
            self.assertIn(
                course_registration['course_id'],
                [registration_code.course_id.to_deprecated_string() for registration_code in registration_codes]
            )
            self.assertIn(
                course_registration['company_name'],
                [getattr(registration_code.invoice, 'company_name') for registration_code in registration_codes]
            )
            self.assertIn(
                course_registration['invoice_id'],
                [registration_code.invoice_id for registration_code in registration_codes]
            )
Example #3
0
    def test_start_purchase(self):
        # Start the purchase, which will mark the cart as "paying"
        cart = Order.get_cart_for_user(user=self.user)
        CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor', currency='usd')
        cart.start_purchase()
        self.assertEqual(cart.status, 'paying')
        for item in cart.orderitem_set.all():
            self.assertEqual(item.status, 'paying')

        # Starting the purchase should be idempotent
        cart.start_purchase()
        self.assertEqual(cart.status, 'paying')
        for item in cart.orderitem_set.all():
            self.assertEqual(item.status, 'paying')

        # If we retrieve the cart for the user, we should get a different order
        next_cart = Order.get_cart_for_user(user=self.user)
        self.assertNotEqual(cart, next_cart)
        self.assertEqual(next_cart.status, 'cart')

        # Complete the first purchase
        cart.purchase()
        self.assertEqual(cart.status, 'purchased')
        for item in cart.orderitem_set.all():
            self.assertEqual(item.status, 'purchased')

        # Starting the purchase again should be a no-op
        cart.start_purchase()
        self.assertEqual(cart.status, 'purchased')
        for item in cart.orderitem_set.all():
            self.assertEqual(item.status, 'purchased')
 def test_user_cart_has_items(self):
     anon = AnonymousUser()
     self.assertFalse(Order.user_cart_has_items(anon))
     self.assertFalse(Order.user_cart_has_items(self.user))
     cart = Order.get_cart_for_user(self.user)
     item = OrderItem(order=cart, user=self.user)
     item.save()
     self.assertTrue(Order.user_cart_has_items(self.user))
Example #5
0
 def test_get_cart_for_user(self):
     # create a cart
     cart = Order.get_cart_for_user(user=self.user)
     # add something to it
     CertificateItem.add_to_order(cart, self.course_id, self.cost, 'verified')
     # should return the same cart
     cart2 = Order.get_cart_for_user(user=self.user)
     self.assertEquals(cart2.orderitem_set.count(), 1)
Example #6
0
 def test_billing_info_storage_off(self):
     cart = Order.get_cart_for_user(self.user)
     cart = Order.get_cart_for_user(self.user)
     self.purchase_with_data(cart)
     self.assertNotEqual(cart.bill_to_first, '')
     self.assertNotEqual(cart.bill_to_last, '')
     self.assertNotEqual(cart.bill_to_city, '')
     self.assertNotEqual(cart.bill_to_state, '')
     self.assertNotEqual(cart.bill_to_country, '')
     self.assertNotEqual(cart.bill_to_postalcode, '')
     # things we expect to be missing when the feature is off
     self.assertEqual(cart.bill_to_street1, '')
     self.assertEqual(cart.bill_to_street2, '')
     self.assertEqual(cart.bill_to_ccnum, '')
     self.assertEqual(cart.bill_to_cardtype, '')
Example #7
0
def checkout(request):
    store = Store.objects.get(subdomain=request.subdomain)
    cart = get_cart(request)
    if cart == {}:
        return redirect("/products/")
    try:
        order = Order(user=request.session["user"], store=store)
        order.save()
    except KeyError:
        return redirect("/home/", {"error_message": "Please sign in"})  #!!!
    for product, key in cart.iteritems():
        i = Item(product=product, quantity=key, order=order)
        i.save()
    request.session["cart"] = cart = {}
    return render_to_response("checkout.html", {"store_name": store.name})
Example #8
0
 def setUp(self):
     """ Create a user and an order. """
     self.user = UserFactory()
     self.order = Order.get_cart_for_user(self.user)
     self.order_item = OrderItem.objects.create(
         order=self.order, user=self.user, unit_cost=self.COST, line_cost=self.COST
     )
Example #9
0
    def test_refund_cert_callback_before_expiration(self):
        # If the expiration date has not yet passed on a verified mode, the user can be refunded
        many_days = datetime.timedelta(days=60)

        course = CourseFactory.create(org="refund_before_expiration", number="test", display_name="one")
        course_key = course.id
        course_mode = CourseMode(
            course_id=course_key,
            mode_slug="verified",
            mode_display_name="verified cert",
            min_price=self.cost,
            expiration_datetime=(datetime.datetime.now(pytz.utc) + many_days),
        )
        course_mode.save()

        CourseEnrollment.enroll(self.user, course_key, "verified")
        cart = Order.get_cart_for_user(user=self.user)
        CertificateItem.add_to_order(cart, course_key, self.cost, "verified")
        cart.purchase()

        CourseEnrollment.unenroll(self.user, course_key)
        target_certs = CertificateItem.objects.filter(
            course_id=course_key, user_id=self.user, status="refunded", mode="verified"
        )
        self.assertTrue(target_certs[0])
        self.assertTrue(target_certs[0].refund_requested_time)
        self.assertEquals(target_certs[0].order.status, "refunded")
    def test_student_used_enrollment_code_for_course_enrollment(self):
        """
        test to check the user enrollment source and payment status in the
        enrollment detailed report
        """
        student = UserFactory()
        self.client.login(username=student.username, password='******')
        student_cart = Order.get_cart_for_user(student)
        paid_course_reg_item = PaidCourseRegistration.add_to_order(student_cart, self.course.id)
        # update the quantity of the cart item paid_course_reg_item
        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'),
                                {'ItemId': paid_course_reg_item.id, 'qty': '4'})
        self.assertEqual(resp.status_code, 200)
        student_cart.purchase()

        course_reg_codes = CourseRegistrationCode.objects.filter(order=student_cart)
        redeem_url = reverse('register_code_redemption', args=[course_reg_codes[0].code])
        response = self.client.get(redeem_url)
        self.assertEquals(response.status_code, 200)
        # check button text
        self.assertTrue('Activate Course Enrollment' in response.content)

        response = self.client.post(redeem_url)
        self.assertEquals(response.status_code, 200)

        task_input = {'features': []}
        with patch('instructor_task.tasks_helper._get_current_task'):
            result = upload_enrollment_report(None, None, self.course.id, task_input, 'generating_enrollment_report')
        self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result)
        self._verify_cell_data_in_csv(student.username, 'Enrollment Source', 'Used Registration Code')
        self._verify_cell_data_in_csv(student.username, 'Payment Status', 'purchased')
Example #11
0
    def setUp(self):
        patcher = patch('student.models.tracker')
        self.mock_tracker = patcher.start()
        self.user = UserFactory.create()
        self.user.set_password('password')
        self.user.save()
        self.instructor = AdminFactory.create()
        self.cost = 40
        self.coupon_code = 'abcde'
        self.reg_code = 'qwerty'
        self.percentage_discount = 10
        self.course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course')
        self.course_key = self.course.id
        self.course_mode = CourseMode(course_id=self.course_key,
                                      mode_slug="honor",
                                      mode_display_name="honor cert",
                                      min_price=self.cost)
        self.course_mode.save()

        #Saving another testing course mode
        self.testing_cost = 20
        self.testing_course = CourseFactory.create(org='edX', number='888', display_name='Testing Super Course')
        self.testing_course_mode = CourseMode(course_id=self.testing_course.id,
                                              mode_slug="honor",
                                              mode_display_name="testing honor cert",
                                              min_price=self.testing_cost)
        self.testing_course_mode.save()

        verified_course = CourseFactory.create(org='org', number='test', display_name='Test Course')
        self.verified_course_key = verified_course.id
        self.cart = Order.get_cart_for_user(self.user)
        self.addCleanup(patcher.stop)
Example #12
0
    def test_refund_cert_callback_before_expiration_email(self):
        """ Test that refund emails are being sent correctly. """
        course = CourseFactory.create()
        course_key = course.id
        many_days = datetime.timedelta(days=60)

        course_mode = CourseMode(course_id=course_key,
                                 mode_slug="verified",
                                 mode_display_name="verified cert",
                                 min_price=self.cost,
                                 expiration_datetime=datetime.datetime.now(pytz.utc) + many_days)
        course_mode.save()

        CourseEnrollment.enroll(self.user, course_key, 'verified')
        cart = Order.get_cart_for_user(user=self.user)
        CertificateItem.add_to_order(cart, course_key, self.cost, 'verified')
        cart.purchase()

        mail.outbox = []
        with patch('shoppingcart.models.log.error') as mock_error_logger:
            CourseEnrollment.unenroll(self.user, course_key)
            self.assertFalse(mock_error_logger.called)
            self.assertEquals(len(mail.outbox), 1)
            self.assertEquals('[Refund] User-Requested Refund', mail.outbox[0].subject)
            self.assertEquals(settings.PAYMENT_SUPPORT_EMAIL, mail.outbox[0].from_email)
            self.assertIn('has requested a refund on Order', mail.outbox[0].body)
Example #13
0
    def setUp(self):
        patcher = patch("student.models.tracker")
        self.mock_tracker = patcher.start()
        self.user = UserFactory.create()
        self.user.set_password("password")
        self.user.save()
        self.instructor = AdminFactory.create()
        self.cost = 40
        self.coupon_code = "abcde"
        self.reg_code = "qwerty"
        self.percentage_discount = 10
        self.course = CourseFactory.create(org="MITx", number="999", display_name="Robot Super Course")
        self.course_key = self.course.id
        self.course_mode = CourseMode(
            course_id=self.course_key, mode_slug="honor", mode_display_name="honor cert", min_price=self.cost
        )
        self.course_mode.save()

        # Saving another testing course mode
        self.testing_cost = 20
        self.testing_course = CourseFactory.create(org="edX", number="888", display_name="Testing Super Course")
        self.testing_course_mode = CourseMode(
            course_id=self.testing_course.id,
            mode_slug="honor",
            mode_display_name="testing honor cert",
            min_price=self.testing_cost,
        )
        self.testing_course_mode.save()

        verified_course = CourseFactory.create(org="org", number="test", display_name="Test Course")
        self.verified_course_key = verified_course.id
        self.cart = Order.get_cart_for_user(self.user)
        self.addCleanup(patcher.stop)
Example #14
0
 def test_orderItem_purchased_callback(self):
     """
     This tests that calling purchased_callback on the base OrderItem class raises NotImplementedError
     """
     item = OrderItem(user=self.user, order=Order.get_cart_for_user(self.user))
     with self.assertRaises(NotImplementedError):
         item.purchased_callback()
Example #15
0
def checkout_with_shoppingcart(request, user, course_key, course_mode, amount):
    """ Create an order and trigger checkout using shoppingcart."""
    cart = Order.get_cart_for_user(user)
    cart.clear()
    enrollment_mode = course_mode.slug
    CertificateItem.add_to_order(cart, course_key, amount, enrollment_mode)

    # Change the order's status so that we don't accidentally modify it later.
    # We need to do this to ensure that the parameters we send to the payment system
    # match what we store in the database.
    # (Ordinarily we would do this client-side when the user submits the form, but since
    # the JavaScript on this page does that immediately, we make the change here instead.
    # This avoids a second AJAX call and some additional complication of the JavaScript.)
    # If a user later re-enters the verification / payment flow, she will create a new order.
    cart.start_purchase()

    callback_url = request.build_absolute_uri(
        reverse("shoppingcart.views.postpay_callback")
    )

    payment_data = {
        'payment_processor_name': settings.CC_PROCESSOR_NAME,
        'payment_page_url': get_purchase_endpoint(),
        'payment_form_data': get_signed_purchase_params(
            cart,
            callback_url=callback_url,
            extra_data=[unicode(course_key), course_mode.slug]
        ),
    }
    return payment_data
Example #16
0
 def test_cart_clear(self):
     cart = Order.get_cart_for_user(user=self.user)
     CertificateItem.add_to_order(cart, self.course_id, self.cost, 'verified')
     CertificateItem.add_to_order(cart, 'test/course1', self.cost, 'verified')
     self.assertEquals(cart.orderitem_set.count(), 2)
     cart.clear()
     self.assertEquals(cart.orderitem_set.count(), 0)
Example #17
0
    def test_single_item_template(self):
        cart = Order.get_cart_for_user(user=self.user)
        cert_item = CertificateItem.add_to_order(cart, self.course_key, self.cost, 'verified')
        self.assertEquals(cert_item.single_item_receipt_template, 'shoppingcart/receipt.html')

        cert_item = CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
        self.assertEquals(cert_item.single_item_receipt_template, 'shoppingcart/receipt.html')
Example #18
0
 def _create_cart(self):
     """Creates a cart and adds a CertificateItem to it"""
     cart = Order.get_cart_for_user(UserFactory.create())
     item = CertificateItem.add_to_order(
         cart, self.course_key, 10, 'honor', currency='usd'
     )
     return cart, item
Example #19
0
    def test_confirmation_email_error(self):
        CourseMode.objects.create(
            course_id=self.course_key,
            mode_slug="verified",
            mode_display_name="Verified",
            min_price=self.cost
        )

        cart = Order.get_cart_for_user(self.user)
        CertificateItem.add_to_order(cart, self.course_key, self.cost, 'verified')

        # Simulate an error when sending the confirmation
        # email.  This should NOT raise an exception.
        # If it does, then the implicit view-level
        # transaction could cause a roll-back, effectively
        # reversing order fulfillment.
        with patch.object(mail.message.EmailMessage, 'send') as mock_send:
            mock_send.side_effect = Exception("Kaboom!")
            cart.purchase()

        # Verify that the purchase completed successfully
        self.assertEqual(cart.status, 'purchased')

        # Verify that the user is enrolled as "verified"
        mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course_key)
        self.assertTrue(is_active)
        self.assertEqual(mode, 'verified')
Example #20
0
 def test_purchase_item_email_boto_failure(self, error_logger):
     cart = Order.get_cart_for_user(user=self.user)
     CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
     with patch.object(EmailMessage, 'send') as mock_send:
         mock_send.side_effect = BotoServerError("status", "reason")
         cart.purchase()
         self.assertTrue(error_logger.called)
Example #21
0
    def test_refund_cert_callback_before_expiration(self):
        # If the expiration date has not yet passed on a verified mode, the user can be refunded
        many_days = datetime.timedelta(days=60)

        course = CourseFactory.create()
        self.course_key = course.id
        course_mode = CourseMode(course_id=self.course_key,
                                 mode_slug="verified",
                                 mode_display_name="verified cert",
                                 min_price=self.cost,
                                 expiration_datetime=(datetime.datetime.now(pytz.utc) + many_days))
        course_mode.save()

        # need to prevent analytics errors from appearing in stderr
        with patch('sys.stderr', sys.stdout.write):
            CourseEnrollment.enroll(self.user, self.course_key, 'verified')
            cart = Order.get_cart_for_user(user=self.user)
            CertificateItem.add_to_order(cart, self.course_key, self.cost, 'verified')
            cart.purchase()
            CourseEnrollment.unenroll(self.user, self.course_key)

        target_certs = CertificateItem.objects.filter(course_id=self.course_key, user_id=self.user, status='refunded', mode='verified')
        self.assertTrue(target_certs[0])
        self.assertTrue(target_certs[0].refund_requested_time)
        self.assertEquals(target_certs[0].order.status, 'refunded')
        self._assert_refund_tracked()
Example #22
0
 def test_purchase_twice(self):
     cart = Order.get_cart_for_user(self.user)
     CertificateItem.add_to_order(cart, self.course_id, self.cost, 'honor')
     # purchase the cart more than once
     cart.purchase()
     cart.purchase()
     self.assertEquals(len(mail.outbox), 1)
Example #23
0
    def test_retire_order_cart(self):
        """Test that an order in cart can successfully be retired"""
        cart = Order.get_cart_for_user(user=self.user)
        CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor', currency='usd')

        cart.retire()
        self.assertEqual(cart.status, 'defunct-cart')
        self.assertEqual(cart.orderitem_set.get().status, 'defunct-cart')
 def add_to_cart(self):
     """
     Adds content to self.user's cart
     """
     course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course')
     CourseModeFactory.create(course_id=course.id)
     cart = Order.get_cart_for_user(self.user)
     PaidCourseRegistration.add_to_order(cart, course.id)
Example #25
0
    def test_payment_separate_from_verification_email(self):
        cart = Order.get_cart_for_user(user=self.user)
        item = CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
        cart.purchase()

        self.assertEquals(len(mail.outbox), 1)
        # Verify that the verification reminder appears in the sent email.
        self.assertIn(item.additional_instruction_text(), mail.outbox[0].body)
Example #26
0
 def test_existing_enrollment(self):
     CourseEnrollment.enroll(self.user, self.course_id)
     cart = Order.get_cart_for_user(user=self.user)
     CertificateItem.add_to_order(cart, self.course_id, self.cost, 'verified')
     # verify that we are still enrolled
     self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course_id))
     cart.purchase()
     enrollment = CourseEnrollment.objects.get(user=self.user, course_id=self.course_id)
     self.assertEquals(enrollment.mode, u'verified')
Example #27
0
 def _enroll(self, purchase=True):
     # pylint: disable=missing-docstring
     CourseEnrollment.enroll(self.student, self.course_id, self.course_mode.mode_slug)
     if purchase:
         self.order = Order.get_cart_for_user(self.student)
         CertificateItem.add_to_order(self.order, self.course_id, 1, self.course_mode.mode_slug)
         self.order.purchase()
     self.course_mode.expiration_datetime = datetime.datetime(1983, 4, 6, tzinfo=pytz.UTC)
     self.course_mode.save()
Example #28
0
 def test_user_cart_has_both_items(self):
     """
     This test exists b/c having both CertificateItem and PaidCourseRegistration in an order used to break
     PaidCourseRegistration.contained_in_order
     """
     cart = Order.get_cart_for_user(self.user)
     CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
     PaidCourseRegistration.add_to_order(self.cart, self.course_key)
     self.assertTrue(PaidCourseRegistration.contained_in_order(cart, self.course_key))
Example #29
0
 def test_cart_clear(self):
     cart = Order.get_cart_for_user(user=self.user)
     CertificateItem.add_to_order(cart, self.course_id, self.cost, 'honor')
     CertificateItem.add_to_order(cart, 'org/test/Test_Course_1', self.cost, 'honor')
     self.assertEquals(cart.orderitem_set.count(), 2)
     self.assertTrue(cart.has_items())
     cart.clear()
     self.assertEquals(cart.orderitem_set.count(), 0)
     self.assertFalse(cart.has_items())
Example #30
0
 def test_cart_clear(self):
     cart = Order.get_cart_for_user(user=self.user)
     CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
     CertificateItem.add_to_order(cart, SlashSeparatedCourseKey('org', 'test', 'Test_Course_1'), self.cost, 'honor')
     self.assertEquals(cart.orderitem_set.count(), 2)
     self.assertTrue(cart.has_items())
     cart.clear()
     self.assertEquals(cart.orderitem_set.count(), 0)
     self.assertFalse(cart.has_items())
Example #31
0
    def test_payment_accepted_order(self):
        """
        Tests payment_accepted cases with an order
        """
        student1 = UserFactory()
        student1.save()

        order1 = Order.get_cart_for_user(student1)
        params = {
            'card_accountNumber': '1234',
            'card_cardType': '001',
            'billTo_firstName': student1.first_name,
            'orderNumber': str(order1.id),
            'orderCurrency': 'usd',
            'decision': 'ACCEPT',
            'ccAuthReply_amount': '0.00'
        }

        # tests for an order number that doesn't match up
        params_bad_ordernum = params.copy()
        params_bad_ordernum['orderNumber'] = str(order1.id + 10)
        with self.assertRaises(CCProcessorDataException):
            payment_accepted(params_bad_ordernum)

        # tests for a reply amount of the wrong type
        params_wrong_type_amt = params.copy()
        params_wrong_type_amt['ccAuthReply_amount'] = 'ab'
        with self.assertRaises(CCProcessorDataException):
            payment_accepted(params_wrong_type_amt)

        # tests for a reply amount of the wrong type
        params_wrong_amt = params.copy()
        params_wrong_amt['ccAuthReply_amount'] = '1.00'
        with self.assertRaises(CCProcessorWrongAmountException):
            payment_accepted(params_wrong_amt)

        # tests for a not accepted order
        params_not_accepted = params.copy()
        params_not_accepted['decision'] = "REJECT"
        self.assertFalse(payment_accepted(params_not_accepted)['accepted'])

        # finally, tests an accepted order
        self.assertTrue(payment_accepted(params)['accepted'])
Example #32
0
 def test_add_item_to_cart_currency_match(self):
     cart = Order.get_cart_for_user(user=self.user)
     CertificateItem.add_to_order(cart,
                                  self.course_key,
                                  self.cost,
                                  'honor',
                                  currency='eur')
     # verify that a new item has been added
     self.assertEquals(cart.orderitem_set.count(), 1)
     # verify that the cart's currency was updated
     self.assertEquals(cart.currency, 'eur')
     with self.assertRaises(InvalidCartItem):
         CertificateItem.add_to_order(cart,
                                      self.course_key,
                                      self.cost,
                                      'honor',
                                      currency='usd')
     # assert that this item did not get added to the cart
     self.assertEquals(cart.orderitem_set.count(), 1)
Example #33
0
    def test_purchase(self):
        # This test is for testing the subclassing functionality of OrderItem, but in
        # order to do this, we end up testing the specific functionality of
        # CertificateItem, which is not quite good unit test form. Sorry.
        cart = Order.get_cart_for_user(user=self.user)
        self.assertFalse(
            CourseEnrollment.is_enrolled(self.user, self.course_key))
        item = CertificateItem.add_to_order(cart, self.course_key, self.cost,
                                            'honor')
        # course enrollment object should be created but still inactive
        self.assertFalse(
            CourseEnrollment.is_enrolled(self.user, self.course_key))
        cart.purchase()
        self.assertTrue(
            CourseEnrollment.is_enrolled(self.user, self.course_key))

        # test e-mail sending
        self.assertEquals(len(mail.outbox), 1)
        self.assertEquals('Order Payment Confirmation', mail.outbox[0].subject)
        self.assertIn(settings.PAYMENT_SUPPORT_EMAIL, mail.outbox[0].body)
        self.assertIn(unicode(cart.total_cost), mail.outbox[0].body)
        self.assertIn(item.additional_instruction_text, mail.outbox[0].body)

        # Assert Google Analytics event fired for purchase.
        self.mock_tracker.track.assert_called_once_with(  # pylint: disable=E1103
            1,
            'Completed Order',
            {
                'orderId': 1,
                'currency': 'usd',
                'total': '40',
                'products': [
                    {
                        'sku': u'CertificateItem-' + unicode(self.course_key) + u'-honor',
                        'category': 'CertificateItem honor',
                        'price': '40',
                        'id': 1,
                        'quantity': 1
                    }
                ]
            },
            context={'Google Analytics': {'clientId': None}}
        )
Example #34
0
    def test_show_receipt_404s(self):
        PaidCourseRegistration.add_to_order(self.cart, self.course_id)
        CertificateItem.add_to_order(self.cart, self.verified_course_id,
                                     self.cost, 'honor')
        self.cart.purchase()

        user2 = UserFactory.create()
        cart2 = Order.get_cart_for_user(user2)
        PaidCourseRegistration.add_to_order(cart2, self.course_id)
        cart2.purchase()

        self.login_user()
        resp = self.client.get(
            reverse('shoppingcart.views.show_receipt', args=[cart2.id]))
        self.assertEqual(resp.status_code, 404)

        resp2 = self.client.get(
            reverse('shoppingcart.views.show_receipt', args=[1000]))
        self.assertEqual(resp2.status_code, 404)
    def test_total_credit_cart_sales_amount(self):
        """
        Test to check the total amount for all the credit card purchases.
        """
        student = UserFactory.create()
        self.client.login(username=student.username, password="******")
        student_cart = Order.get_cart_for_user(student)
        item = self.add_course_to_user_cart(student_cart, self.course.id)
        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item.id, 'qty': 4})
        self.assertEqual(resp.status_code, 200)
        student_cart.purchase()

        self.client.login(username=self.instructor.username, password="******")
        CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
        single_purchase_total = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course.id)
        bulk_purchase_total = CourseRegCodeItem.get_total_amount_of_purchased_item(self.course.id)
        total_amount = single_purchase_total + bulk_purchase_total
        response = self.client.get(self.url)
        self.assertIn('{currency}{amount}'.format(currency='$', amount=total_amount), response.content)
Example #36
0
    def setUp(self):
        super(ItemizedPurchaseReportTest, self).setUp()

        self.user = UserFactory.create()
        self.cost = 40
        self.course = CourseFactory.create(org='MITx', number='999', display_name=u'Robot Super Course')
        self.course_key = self.course.id
        course_mode = CourseMode(course_id=self.course_key,
                                 mode_slug="honor",
                                 mode_display_name="honor cert",
                                 min_price=self.cost)
        course_mode.save()
        course_mode2 = CourseMode(course_id=self.course_key,
                                  mode_slug="verified",
                                  mode_display_name="verified cert",
                                  min_price=self.cost)
        course_mode2.save()
        self.annotation = PaidCourseRegistrationAnnotation(course_id=self.course_key, annotation=self.TEST_ANNOTATION)
        self.annotation.save()
        self.course_reg_code_annotation = CourseRegCodeItemAnnotation(course_id=self.course_key, annotation=self.TEST_ANNOTATION)
        self.course_reg_code_annotation.save()
        self.cart = Order.get_cart_for_user(self.user)
        self.reg = PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug=course_mode.mode_slug)
        self.cert_item = CertificateItem.add_to_order(self.cart, self.course_key, self.cost, 'verified')
        self.cart.purchase()
        self.now = datetime.datetime.now(pytz.UTC)

        paid_reg = PaidCourseRegistration.objects.get(course_id=self.course_key, user=self.user)
        paid_reg.fulfilled_time = self.now
        paid_reg.refund_requested_time = self.now
        paid_reg.save()

        cert = CertificateItem.objects.get(course_id=self.course_key, user=self.user)
        cert.fulfilled_time = self.now
        cert.refund_requested_time = self.now
        cert.save()

        self.CORRECT_CSV = dedent("""
            Purchase Time,Order ID,Status,Quantity,Unit Cost,Total Cost,Currency,Description,Comments
            {time_str},1,purchased,1,40.00,40.00,usd,Registration for Course: Robot Super Course,Ba\xc3\xbc\xe5\x8c\x85
            {time_str},1,purchased,1,40.00,40.00,usd,verified cert for course Robot Super Course,
            """.format(time_str=str(self.now)))
Example #37
0
 def setUp(self):
     self.user = UserFactory.create()
     self.user.set_password('password')
     self.user.save()
     self.course_id = "MITx/999/Robot_Super_Course"
     self.cost = 40
     self.course = CourseFactory.create(org='MITx',
                                        number='999',
                                        display_name='Robot Super Course')
     self.course_mode = CourseMode(course_id=self.course_id,
                                   mode_slug="honor",
                                   mode_display_name="honor cert",
                                   min_price=self.cost)
     self.course_mode.save()
     self.verified_course_id = 'org/test/Test_Course'
     CourseFactory.create(org='org',
                          number='test',
                          run='course1',
                          display_name='Test Course')
     self.cart = Order.get_cart_for_user(self.user)
Example #38
0
    def test_total_amount_of_purchased_course(self):
        self.add_course_to_user_cart(self.course_key)
        self.assertEquals(self.cart.orderitem_set.count(), 1)
        self.add_coupon(self.course_key, True, self.coupon_code)
        resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
        self.assertEqual(resp.status_code, 200)

        self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')

        # Total amount of a particular course that is purchased by different users
        total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course_key)
        self.assertEqual(total_amount, 36)

        self.client.login(username=self.instructor.username, password="******")
        cart = Order.get_cart_for_user(self.instructor)
        PaidCourseRegistration.add_to_order(cart, self.course_key)
        cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')

        total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course_key)
        self.assertEqual(total_amount, 76)
Example #39
0
    def test_retire_order_error(self, order_status, item_status, exception):
        """
        Test error cases for retiring an order:
        1) Order item has a different status than the order
        2) The order's status isn't in "cart" or "paying"
        """
        cart = Order.get_cart_for_user(user=self.user)
        item = CertificateItem.add_to_order(cart,
                                            self.course_key,
                                            self.cost,
                                            'honor',
                                            currency='usd')

        cart.status = order_status
        cart.save()
        item.status = item_status
        item.save()

        with self.assertRaises(exception):
            cart.retire()
Example #40
0
    def test_refund_cert_callback_no_expiration(self):
        # When there is no expiration date on a verified mode, the user can always get a refund

        # need to prevent analytics errors from appearing in stderr
        with patch('sys.stderr', sys.stdout.write):
            CourseEnrollment.enroll(self.user, self.course_key, 'verified')
            cart = Order.get_cart_for_user(user=self.user)
            CertificateItem.add_to_order(cart, self.course_key, self.cost,
                                         'verified')
            cart.purchase()
            CourseEnrollment.unenroll(self.user, self.course_key)

        target_certs = CertificateItem.objects.filter(
            course_id=self.course_key,
            user_id=self.user,
            status='refunded',
            mode='verified')
        self.assertTrue(target_certs[0])
        self.assertTrue(target_certs[0].refund_requested_time)
        self.assertEquals(target_certs[0].order.status, 'refunded')
        self._assert_refund_tracked()
Example #41
0
    def test_refund_cert_callback_before_expiration_email_error(self, error_logger):
        # If there's an error sending an email to billing, we need to log this error
        course_id = "refund_before_expiration/test/one"
        many_days = datetime.timedelta(days=60)

        CourseFactory.create(org='refund_before_expiration', number='test', run='course', display_name='one')
        course_mode = CourseMode(course_id=course_id,
                                 mode_slug="verified",
                                 mode_display_name="verified cert",
                                 min_price=self.cost,
                                 expiration_datetime=datetime.datetime.now(pytz.utc) + many_days)
        course_mode.save()

        CourseEnrollment.enroll(self.user, course_id, 'verified')
        cart = Order.get_cart_for_user(user=self.user)
        CertificateItem.add_to_order(cart, course_id, self.cost, 'verified')
        cart.purchase()

        with patch('shoppingcart.models.send_mail', side_effect=smtplib.SMTPException):
            CourseEnrollment.unenroll(self.user, course_id)
            self.assertTrue(error_logger.called)
    def test_purchase(self):
        # This test is for testing the subclassing functionality of OrderItem, but in
        # order to do this, we end up testing the specific functionality of
        # CertificateItem, which is not quite good unit test form. Sorry.
        cart = Order.get_cart_for_user(user=self.user)
        self.assertFalse(
            CourseEnrollment.is_enrolled(self.user, self.course_id))
        CertificateItem.add_to_order(cart, self.course_id, self.cost,
                                     'verified')
        # course enrollment object should be created but still inactive
        self.assertFalse(
            CourseEnrollment.is_enrolled(self.user, self.course_id))
        cart.purchase()
        self.assertTrue(CourseEnrollment.is_enrolled(self.user,
                                                     self.course_id))

        # test e-mail sending
        self.assertEquals(len(mail.outbox), 1)
        self.assertEquals('Order Payment Confirmation', mail.outbox[0].subject)
        self.assertIn(settings.PAYMENT_SUPPORT_EMAIL, mail.outbox[0].body)
        self.assertIn(unicode(cart.total_cost), mail.outbox[0].body)
Example #43
0
    def post(self, request, *args, **kwargs):
        u_client = request.user
        u_cart = request.user.cart
        #lineas = ProductList.objects.filter(cart=u_cart)
        cart_lines = u_cart.productlist_set.all()

        #Creo una nueva compra
        new_order = Order()
        #Datos del cliente
        if u_client.profile.first_name and u_client.profile.last_name:
            new_order.c_name = u_client.profile.first_name + ' ' +  u_client.profile.last_name
        else:
            new_order.c_name = 'Sin nombre'
        new_order.c_email = u_client.email
        new_order.c_profile_pk = u_client.profile.pk
        new_order.save()

        #Guardo los libros del carrito en la compra
        for l in cart_lines:
            #Por cada linea del carrito creo una linea de la orden
            new_order_line = OrderLine()

            #A que orden pertenece
            new_order_line.order = new_order

            #Datos del libro
            new_order_line.b_title = l.book.title
            new_order_line.b_editorial = l.book.editorial.name
            new_order_line.b_price = l.book.get_price()
            new_order_line.b_pk = l.book.pk
            new_order_line.quantity = l.quantity

            new_order_line.save()
            #Elimino los libros del carrito
            l.delete()
        return redirect(new_order)
Example #44
0
    def test_process_postpay_accepted(self):
        """
        Tests the ACCEPTED path of process_postpay
        """
        student1 = UserFactory()
        student1.save()

        order1 = Order.get_cart_for_user(student1)
        params = {
            'card_accountNumber': '1234',
            'card_cardType': '001',
            'billTo_firstName': student1.first_name,
            'orderNumber': str(order1.id),
            'orderCurrency': 'usd',
            'decision': 'ACCEPT',
            'ccAuthReply_amount': '0.00'
        }
        result = process_postpay_callback(params)
        self.assertTrue(result['success'])
        self.assertEqual(result['order'], order1)
        order1 = Order.objects.get(id=order1.id)  # reload from DB to capture side-effect of process_postpay_callback
        self.assertEqual(order1.status, 'purchased')
        self.assertFalse(result['error_html'])
Example #45
0
    def test_refund_cert_callback_after_expiration(self):
        # If the expiration date has passed, the user cannot get a refund
        many_days = datetime.timedelta(days=60)

        course = CourseFactory.create()
        course_key = course.id
        course_mode = CourseMode(course_id=course_key,
                                 mode_slug="verified",
                                 mode_display_name="verified cert",
                                 min_price=self.cost,)
        course_mode.save()

        CourseEnrollment.enroll(self.user, course_key, 'verified')
        cart = Order.get_cart_for_user(user=self.user)
        CertificateItem.add_to_order(cart, course_key, self.cost, 'verified')
        cart.purchase()

        course_mode.expiration_datetime = (datetime.datetime.now(pytz.utc) - many_days)
        course_mode.save()

        CourseEnrollment.unenroll(self.user, course_key)
        target_certs = CertificateItem.objects.filter(course_id=course_key, user_id=self.user, status='refunded', mode='verified')
        self.assertEqual(len(target_certs), 0)
Example #46
0
    def setUp(self):
        self.user = UserFactory.create()
        self.user.set_password('password')
        self.user.save()
        self.cost = 40
        self.course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course')
        self.course_key = self.course.id
        self.course_mode = CourseMode(course_id=self.course_key,
                                      mode_slug="honor",
                                      mode_display_name="honor cert",
                                      min_price=self.cost)
        self.course_mode.save()
        self.course_mode2 = CourseMode(course_id=self.course_key,
                                       mode_slug="verified",
                                       mode_display_name="verified cert",
                                       min_price=self.cost)
        self.course_mode2.save()
        verified_course = CourseFactory.create(org='org', number='test', display_name='Test Course')

        self.verified_course_key = verified_course.id
        self.cart = Order.get_cart_for_user(self.user)
        self.dl_grp = Group(name=settings.PAYMENT_REPORT_GENERATOR_GROUP)
        self.dl_grp.save()
    def test_add_white_label_to_cart(self):
        # Create a white label course (honor with a minimum price)
        CourseModeFactory.create(course_id=self.course.id,
                                 mode_slug="honor",
                                 mode_display_name="Honor",
                                 min_price=100)

        # Simulate the pipeline step for enrolling in this course
        strategy = self._fake_strategy()
        strategy.session_set('enroll_course_id', unicode(self.course.id))
        result = pipeline.change_enrollment(strategy, 1, user=self.user)  # pylint: disable=assignment-from-no-return,redundant-keyword-arg
        self.assertEqual(result, {})

        # Expect that the uesr is NOT enrolled in the course
        # because the user has not yet paid
        self.assertFalse(
            CourseEnrollment.is_enrolled(self.user, self.course.id))

        # Expect that the course was added to the shopping cart
        cart = Order.get_cart_for_user(self.user)
        self.assertTrue(cart.has_items(PaidCourseRegistration))
        order_item = PaidCourseRegistration.objects.get(order=cart)
        self.assertEqual(order_item.course_id, self.course.id)
Example #48
0
    def test_process_postpay_not_accepted(self):
        """
        Tests the non-ACCEPTED path of process_postpay
        """
        student1 = UserFactory()
        student1.save()

        order1 = Order.get_cart_for_user(student1)
        params = {
            'card_accountNumber': '1234',
            'card_cardType': '001',
            'billTo_firstName': student1.first_name,
            'orderNumber': str(order1.id),
            'orderCurrency': 'usd',
            'decision': 'REJECT',
            'ccAuthReply_amount': '0.00',
            'reasonCode': '207'
        }
        result = process_postpay_callback(params)
        self.assertFalse(result['success'])
        self.assertEqual(result['order'], order1)
        self.assertEqual(order1.status, 'cart')
        self.assertIn(REASONCODE_MAP['207'], result['error_html'])
Example #49
0
    def test_refund_cert_callback_before_expiration(self):
        # If the expiration date has not yet passed on a verified mode, the user can be refunded
        many_days = datetime.timedelta(days=60)

        course = CourseFactory.create()
        course_key = course.id
        course_mode = CourseMode(course_id=course_key,
                                 mode_slug="verified",
                                 mode_display_name="verified cert",
                                 min_price=self.cost,
                                 expiration_datetime=(datetime.datetime.now(pytz.utc) + many_days))
        course_mode.save()

        CourseEnrollment.enroll(self.user, course_key, 'verified')
        cart = Order.get_cart_for_user(user=self.user)
        CertificateItem.add_to_order(cart, course_key, self.cost, 'verified')
        cart.purchase()

        CourseEnrollment.unenroll(self.user, course_key)
        target_certs = CertificateItem.objects.filter(course_id=course_key, user_id=self.user, status='refunded', mode='verified')
        self.assertTrue(target_certs[0])
        self.assertTrue(target_certs[0].refund_requested_time)
        self.assertEquals(target_certs[0].order.status, 'refunded')
Example #50
0
    def test_render_purchase_form_html(self, render):
        """
        Tests the rendering of the purchase form
        """
        student1 = UserFactory()
        student1.save()

        order1 = Order.get_cart_for_user(student1)
        item1 = OrderItem(order=order1,
                          user=student1,
                          unit_cost=1.0,
                          line_cost=1.0)
        item1.save()
        html = render_purchase_form_html(order1)
        ((template, context), render_kwargs) = render.call_args

        self.assertEqual(template, 'shoppingcart/cybersource_form.html')
        self.assertDictContainsSubset(
            {
                'amount': '1.00',
                'currency': 'usd',
                'orderPage_transactionType': 'sale',
                'orderNumber': str(order1.id)
            }, context['params'])
    def setUp(self, cutoff_date):
        super(ReportTypeTests, self).setUp()
        cutoff_date.return_value = datetime.datetime.now(
            pytz.UTC) + datetime.timedelta(days=1)
        # Need to make a *lot* of users for this one
        self.first_verified_user = UserFactory.create(profile__name="John Doe")
        self.second_verified_user = UserFactory.create(
            profile__name="Jane Deer")
        self.first_audit_user = UserFactory.create(profile__name="Joe Miller")
        self.second_audit_user = UserFactory.create(
            profile__name="Simon Blackquill")
        self.third_audit_user = UserFactory.create(profile__name="Super Mario")
        self.honor_user = UserFactory.create(profile__name="Princess Peach")
        self.first_refund_user = UserFactory.create(
            profile__name="King Bowsér")
        self.second_refund_user = UserFactory.create(
            profile__name="Súsan Smith")

        # Two are verified, three are audit, one honor

        self.cost = 40
        self.course = CourseFactory.create(org='MITx',
                                           number='999',
                                           display_name=u'Robot Super Course')
        self.course_key = self.course.id
        course_mode = CourseMode(course_id=self.course_key,
                                 mode_slug="honor",
                                 mode_display_name="honor cert",
                                 min_price=self.cost)
        course_mode.save()

        course_mode2 = CourseMode(course_id=self.course_key,
                                  mode_slug="verified",
                                  mode_display_name="verified cert",
                                  min_price=self.cost)
        course_mode2.save()

        # User 1 & 2 will be verified
        self.cart1 = Order.get_cart_for_user(self.first_verified_user)
        CertificateItem.add_to_order(self.cart1, self.course_key, self.cost,
                                     'verified')
        self.cart1.purchase()

        self.cart2 = Order.get_cart_for_user(self.second_verified_user)
        CertificateItem.add_to_order(self.cart2, self.course_key, self.cost,
                                     'verified')
        self.cart2.purchase()

        # Users 3, 4, and 5 are audit
        CourseEnrollment.enroll(self.first_audit_user, self.course_key,
                                "audit")
        CourseEnrollment.enroll(self.second_audit_user, self.course_key,
                                "audit")
        CourseEnrollment.enroll(self.third_audit_user, self.course_key,
                                "audit")

        # User 6 is honor
        CourseEnrollment.enroll(self.honor_user, self.course_key, "honor")

        self.now = datetime.datetime.now(pytz.UTC)

        # Users 7 & 8 are refunds
        self.cart = Order.get_cart_for_user(self.first_refund_user)
        CertificateItem.add_to_order(self.cart, self.course_key, self.cost,
                                     'verified')
        self.cart.purchase()
        CourseEnrollment.unenroll(self.first_refund_user, self.course_key)

        self.cart = Order.get_cart_for_user(self.second_refund_user)
        CertificateItem.add_to_order(self.cart, self.course_key, self.cost,
                                     'verified')
        self.cart.purchase(self.second_refund_user.username, self.course_key)
        CourseEnrollment.unenroll(self.second_refund_user, self.course_key)

        self.test_time = datetime.datetime.now(pytz.UTC)

        first_refund = CertificateItem.objects.get(id=3)
        first_refund.fulfilled_time = self.test_time
        first_refund.refund_requested_time = self.test_time
        first_refund.save()

        second_refund = CertificateItem.objects.get(id=4)
        second_refund.fulfilled_time = self.test_time
        second_refund.refund_requested_time = self.test_time
        second_refund.save()

        self.CORRECT_REFUND_REPORT_CSV = dedent(u"""
            Order Number,Customer Name,Date of Original Transaction,Date of Refund,Amount of Refund,Service Fees (if any)
            3,King Bowsér,{time_str},{time_str},40.00,0.00
            4,Súsan Smith,{time_str},{time_str},40.00,0.00
            """.format(time_str=str(self.test_time)))

        self.CORRECT_CERT_STATUS_CSV = dedent("""
            University,Course,Course Announce Date,Course Start Date,Course Registration Close Date,Course Registration Period,Total Enrolled,Audit Enrollment,Honor Code Enrollment,Verified Enrollment,Gross Revenue,Gross Revenue over the Minimum,Number of Verified Students Contributing More than the Minimum,Number of Refunds,Dollars Refunded
            MITx,999 Robot Super Course,,,,,6,3,1,2,80.00,0.00,0,2,80.00
            """.format(time_str=str(self.test_time)))

        self.CORRECT_UNI_REVENUE_SHARE_CSV = dedent("""
            University,Course,Number of Transactions,Total Payments Collected,Service Fees (if any),Number of Successful Refunds,Total Amount of Refunds
            MITx,999 Robot Super Course,6,80.00,0.00,2,80.00
            """.format(time_str=str(self.test_time)))
Example #52
0
 def test_user_cart_has_certificate_items(self):
     cart = Order.get_cart_for_user(self.user)
     CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
     self.assertTrue(Order.user_cart_has_items(self.user, CertificateItem))
     self.assertFalse(Order.user_cart_has_items(self.user, PaidCourseRegistration))
Example #53
0
 def test_purchase_item_email_smtp_failure(self, error_logger):
     cart = Order.get_cart_for_user(user=self.user)
     CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
     with patch('shoppingcart.models.send_mail', side_effect=smtplib.SMTPException):
         cart.purchase()
         self.assertTrue(error_logger.called)
Example #54
0
 def test_user_cart_has_paid_course_registration_items(self):
     cart = Order.get_cart_for_user(self.user)
     item = PaidCourseRegistration(order=cart, user=self.user)
     item.save()
     self.assertTrue(Order.user_cart_has_items(self.user, PaidCourseRegistration))
     self.assertFalse(Order.user_cart_has_items(self.user, CertificateItem))
Example #55
0
 def setUp(self):
     """Create a test user and order. """
     super(DonationTest, self).setUp()
     self.user = UserFactory.create()
     self.cart = Order.get_cart_for_user(self.user)
Example #56
0
def create_order(request):
    """
    Submit PhotoVerification and create a new Order for this verified cert
    """
    if not SoftwareSecurePhotoVerification.user_has_valid_or_pending(
            request.user):
        attempt = SoftwareSecurePhotoVerification(user=request.user)
        try:
            b64_face_image = request.POST['face_image'].split(",")[1]
            b64_photo_id_image = request.POST['photo_id_image'].split(",")[1]
        except IndexError:
            context = {
                'success': False,
            }
            return JsonResponse(context)
        attempt.upload_face_image(b64_face_image.decode('base64'))
        attempt.upload_photo_id_image(b64_photo_id_image.decode('base64'))
        attempt.mark_ready()

        attempt.save()

    course_id = request.POST['course_id']
    course_id = CourseKey.from_string(course_id)
    donation_for_course = request.session.get('donation_for_course', {})
    current_donation = donation_for_course.get(unicode(course_id),
                                               decimal.Decimal(0))
    contribution = request.POST.get(
        "contribution", donation_for_course.get(unicode(course_id), 0))
    try:
        amount = decimal.Decimal(contribution).quantize(
            decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN)
    except decimal.InvalidOperation:
        return HttpResponseBadRequest(_("Selected price is not valid number."))

    if amount != current_donation:
        donation_for_course[unicode(course_id)] = amount
        request.session['donation_for_course'] = donation_for_course

    # prefer professional mode over verified_mode
    current_mode = CourseMode.verified_mode_for_course(course_id)

    # make sure this course has a verified mode
    if not current_mode:
        return HttpResponseBadRequest(
            _("This course doesn't support verified certificates"))

    if current_mode.slug == 'professional':
        amount = current_mode.min_price

    if amount < current_mode.min_price:
        return HttpResponseBadRequest(
            _("No selected price or selected price is below minimum."))

    # I know, we should check this is valid. All kinds of stuff missing here
    cart = Order.get_cart_for_user(request.user)
    cart.clear()
    enrollment_mode = current_mode.slug
    CertificateItem.add_to_order(cart, course_id, amount, enrollment_mode)

    # Change the order's status so that we don't accidentally modify it later.
    # We need to do this to ensure that the parameters we send to the payment system
    # match what we store in the database.
    # (Ordinarily we would do this client-side when the user submits the form, but since
    # the JavaScript on this page does that immediately, we make the change here instead.
    # This avoids a second AJAX call and some additional complication of the JavaScript.)
    # If a user later re-enters the verification / payment flow, she will create a new order.
    cart.start_purchase()

    callback_url = request.build_absolute_uri(
        reverse("shoppingcart.views.postpay_callback"))

    params = get_signed_purchase_params(cart,
                                        callback_url=callback_url,
                                        extra_data=[unicode(course_id)])

    params['success'] = True
    return HttpResponse(json.dumps(params), content_type="text/json")
Example #57
0
    def test_sale_order_features_without_discount(self):
        """
         Test Order Sales Report CSV
        """
        query_features = [
            ('id', 'Order Id'),
            ('company_name', 'Company Name'),
            ('company_contact_name', 'Company Contact Name'),
            ('company_contact_email', 'Company Contact Email'),
            ('total_amount', 'Total Amount'),
            ('total_codes', 'Total Codes'),
            ('total_used_codes', 'Total Used Codes'),
            ('logged_in_username', 'Login Username'),
            ('logged_in_email', 'Login User Email'),
            ('purchase_time', 'Date of Sale'),
            ('customer_reference_number', 'Customer Reference Number'),
            ('recipient_name', 'Recipient Name'),
            ('recipient_email', 'Recipient Email'),
            ('bill_to_street1', 'Street 1'),
            ('bill_to_street2', 'Street 2'),
            ('bill_to_city', 'City'),
            ('bill_to_state', 'State'),
            ('bill_to_postalcode', 'Postal Code'),
            ('bill_to_country', 'Country'),
            ('order_type', 'Order Type'),
            ('status', 'Order Item Status'),
            ('coupon_code', 'Coupon Code'),
            ('unit_cost', 'Unit Price'),
            ('list_price', 'List Price'),
            ('codes', 'Registration Codes'),
            ('course_id', 'Course Id'),
            ('quantity', 'Quantity'),
            ('total_discount', 'Total Discount'),
            ('total_amount', 'Total Amount Paid'),
        ]
        # add the coupon code for the course
        order = Order.get_cart_for_user(self.instructor)
        order.order_type = 'business'
        order.save()
        order.add_billing_details(
            company_name='Test Company',
            company_contact_name='Test',
            company_contact_email='test@123',
            recipient_name='R1', recipient_email='',
            customer_reference_number='PO#23'
        )
        CourseRegCodeItem.add_to_order(order, self.course.id, 4)
        order.purchase()

        # get the updated item
        item = order.orderitem_set.all().select_subclasses()[0]

        db_columns = [x[0] for x in query_features]
        sale_order_records_list = sale_order_record_features(self.course.id, db_columns)

        for sale_order_record in sale_order_records_list:
            self.assertEqual(sale_order_record['recipient_email'], order.recipient_email)
            self.assertEqual(sale_order_record['recipient_name'], order.recipient_name)
            self.assertEqual(sale_order_record['company_name'], order.company_name)
            self.assertEqual(sale_order_record['company_contact_name'], order.company_contact_name)
            self.assertEqual(sale_order_record['company_contact_email'], order.company_contact_email)
            self.assertEqual(sale_order_record['customer_reference_number'], order.customer_reference_number)
            self.assertEqual(sale_order_record['unit_cost'], item.unit_cost)
            # Make sure list price is not None and matches the unit price since no discount was applied.
            self.assertIsNotNone(sale_order_record['list_price'])
            self.assertEqual(sale_order_record['list_price'], item.unit_cost)
            self.assertEqual(sale_order_record['status'], item.status)
            self.assertEqual(sale_order_record['coupon_code'], 'N/A')
            self.assertEqual(sale_order_record['total_amount'], item.unit_cost * item.qty)
            self.assertEqual(sale_order_record['total_discount'], 0)
            self.assertEqual(sale_order_record['quantity'], item.qty)
Example #58
0
    def test_sale_order_features_with_discount(self):
        """
         Test Order Sales Report CSV
        """
        query_features = [
            ('id', 'Order Id'),
            ('company_name', 'Company Name'),
            ('company_contact_name', 'Company Contact Name'),
            ('company_contact_email', 'Company Contact Email'),
            ('total_amount', 'Total Amount'),
            ('total_codes', 'Total Codes'),
            ('total_used_codes', 'Total Used Codes'),
            ('logged_in_username', 'Login Username'),
            ('logged_in_email', 'Login User Email'),
            ('purchase_time', 'Date of Sale'),
            ('customer_reference_number', 'Customer Reference Number'),
            ('recipient_name', 'Recipient Name'),
            ('recipient_email', 'Recipient Email'),
            ('bill_to_street1', 'Street 1'),
            ('bill_to_street2', 'Street 2'),
            ('bill_to_city', 'City'),
            ('bill_to_state', 'State'),
            ('bill_to_postalcode', 'Postal Code'),
            ('bill_to_country', 'Country'),
            ('order_type', 'Order Type'),
            ('status', 'Order Item Status'),
            ('coupon_code', 'Coupon Code'),
            ('unit_cost', 'Unit Price'),
            ('list_price', 'List Price'),
            ('codes', 'Registration Codes'),
            ('course_id', 'Course Id')
        ]
        # add the coupon code for the course
        coupon = Coupon(
            code='test_code',
            description='test_description',
            course_id=self.course.id,
            percentage_discount='10',
            created_by=self.instructor,
            is_active=True
        )
        coupon.save()
        order = Order.get_cart_for_user(self.instructor)
        order.order_type = 'business'
        order.save()
        order.add_billing_details(
            company_name='Test Company',
            company_contact_name='Test',
            company_contact_email='test@123',
            recipient_name='R1', recipient_email='',
            customer_reference_number='PO#23'
        )
        CourseRegCodeItem.add_to_order(order, self.course.id, 4)
        # apply the coupon code to the item in the cart
        resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': coupon.code})
        self.assertEqual(resp.status_code, 200)
        order.purchase()

        # get the updated item
        item = order.orderitem_set.all().select_subclasses()[0]
        # get the redeemed coupon information
        coupon_redemption = CouponRedemption.objects.select_related('coupon').filter(order=order)

        db_columns = [x[0] for x in query_features]
        sale_order_records_list = sale_order_record_features(self.course.id, db_columns)

        for sale_order_record in sale_order_records_list:
            self.assertEqual(sale_order_record['recipient_email'], order.recipient_email)
            self.assertEqual(sale_order_record['recipient_name'], order.recipient_name)
            self.assertEqual(sale_order_record['company_name'], order.company_name)
            self.assertEqual(sale_order_record['company_contact_name'], order.company_contact_name)
            self.assertEqual(sale_order_record['company_contact_email'], order.company_contact_email)
            self.assertEqual(sale_order_record['customer_reference_number'], order.customer_reference_number)
            self.assertEqual(sale_order_record['unit_cost'], item.unit_cost)
            self.assertEqual(sale_order_record['list_price'], item.list_price)
            self.assertEqual(sale_order_record['status'], item.status)
            self.assertEqual(sale_order_record['coupon_code'], coupon_redemption[0].coupon.code)
Example #59
0
 def test_purchase_item_email_boto_failure(self, error_logger):
     cart = Order.get_cart_for_user(user=self.user)
     CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
     with patch('shoppingcart.models.send_mail', side_effect=BotoServerError("status", "reason")):
         cart.purchase()
         self.assertTrue(error_logger.called)
Example #60
0
    def setUp(self):
        super(TestOrderHistoryOnSiteDashboard, self).setUp()

        patcher = patch('student.models.tracker')
        self.mock_tracker = patcher.start()
        self.user = UserFactory.create()
        self.user.set_password('password')
        self.user.save()

        self.addCleanup(patcher.stop)

        # First Order with our (fakeX) site's course.
        course1 = CourseFactory.create(org='fakeX', number='999', display_name='fakeX Course')
        course1_key = course1.id
        course1_mode = CourseMode(course_id=course1_key,
                                  mode_slug="honor",
                                  mode_display_name="honor cert",
                                  min_price=20)
        course1_mode.save()

        cart = Order.get_cart_for_user(self.user)
        PaidCourseRegistration.add_to_order(cart, course1_key)
        cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
        self.fakex_site_order_id = cart.id

        # Second Order with another(fooX) site's course
        course2 = CourseFactory.create(org='fooX', number='888', display_name='fooX Course')
        course2_key = course2.id
        course2_mode = CourseMode(course_id=course2.id,
                                  mode_slug="honor",
                                  mode_display_name="honor cert",
                                  min_price=20)
        course2_mode.save()

        cart = Order.get_cart_for_user(self.user)
        PaidCourseRegistration.add_to_order(cart, course2_key)
        cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
        self.foox_site_order_id = cart.id

        # Third Order with course not attributed to any site.
        course3 = CourseFactory.create(org='fakeOtherX', number='777', display_name='fakeOtherX Course')
        course3_key = course3.id
        course3_mode = CourseMode(course_id=course3.id,
                                  mode_slug="honor",
                                  mode_display_name="honor cert",
                                  min_price=20)
        course3_mode.save()

        cart = Order.get_cart_for_user(self.user)
        PaidCourseRegistration.add_to_order(cart, course3_key)
        cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
        self.order_id = cart.id

        # Fourth Order with course not attributed to any site but with a CertificateItem
        course4 = CourseFactory.create(org='fakeOtherX', number='888')
        course4_key = course4.id
        course4_mode = CourseMode(course_id=course4.id,
                                  mode_slug="verified",
                                  mode_display_name="verified cert",
                                  min_price=20)
        course4_mode.save()

        cart = Order.get_cart_for_user(self.user)
        CertificateItem.add_to_order(cart, course4_key, 20.0, 'verified')
        cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
        self.certificate_order_id = cart.id

        # Fifth Order with course not attributed to any site but with a Donation
        course5 = CourseFactory.create(org='fakeOtherX', number='999')
        course5_key = course5.id

        cart = Order.get_cart_for_user(self.user)
        Donation.add_to_order(cart, 20.0, course5_key)
        cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
        self.donation_order_id = cart.id

        # also add a donation not associated with a course to make sure the None case works OK
        Donation.add_to_order(cart, 10.0, None)
        cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
        self.courseless_donation_order_id = cart.id