diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py index b67497ec1b..b45926f187 100644 --- a/lms/djangoapps/instructor/tests/test_api.py +++ b/lms/djangoapps/instructor/tests/test_api.py @@ -62,7 +62,10 @@ from instructor_task.api_helper import AlreadyRunningError from .test_tools import msk_from_problem_urlname from ..views.tools import get_extended_due -EXPECTED_CSV_HEADER = '"code","course_id","company_name","created_by","redeemed_by","invoice_id","purchaser","customer_reference_number","internal_reference"' +EXPECTED_CSV_HEADER = ( + '"code","redeem_code_url","course_id","company_name","created_by","redeemed_by","invoice_id","purchaser",' + '"customer_reference_number","internal_reference"' +) EXPECTED_COUPON_CSV_HEADER = '"code","course_id","percentage_discount","code_redeemed_count","description"' # ddt data for test cases involving reports @@ -3117,6 +3120,38 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase): self.assertTrue(body.startswith(EXPECTED_CSV_HEADER)) self.assertEqual(len(body.split('\n')), 17) + def test_generate_course_registration_with_redeem_url_codes_csv(self): + """ + Test to generate a response of all the generated course registration codes + """ + url = reverse('generate_registration_codes', + kwargs={'course_id': self.course.id.to_deprecated_string()}) + + data = { + 'total_registration_codes': 15, 'company_name': 'Group Alpha', 'company_contact_name': 'Test@company.com', + 'company_contact_email': 'Test@company.com', 'sale_price': 122.45, 'recipient_name': 'Test123', + 'recipient_email': 'test@123.com', 'address_line_1': 'Portland Street', 'address_line_2': '', + 'address_line_3': '', 'city': '', 'state': '', 'zip': '', 'country': '', + 'customer_reference_number': '123A23F', 'internal_reference': '', 'invoice': '' + } + + response = self.client.post(url, data, **{'HTTP_HOST': 'localhost'}) + + self.assertEqual(response.status_code, 200, response.content) + self.assertEqual(response['Content-Type'], 'text/csv') + body = response.content.replace('\r', '') + self.assertTrue(body.startswith(EXPECTED_CSV_HEADER)) + self.assertEqual(len(body.split('\n')), 17) + rows = body.split('\n') + index = 1 + while index < len(rows): + if rows[index]: + row_data = rows[index].split(',') + code = row_data[0].replace('"', '') + self.assertTrue(row_data[1].startswith('"http') + and row_data[1].endswith('/shoppingcart/register/redeem/{0}/"'.format(code))) + index += 1 + @patch.object(instructor.views.api, 'random_code_generator', Mock(side_effect=['first', 'second', 'third', 'fourth'])) def test_generate_course_registration_codes_matching_existing_coupon_code(self): diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py index dc0291e9f4..7738cfc8e6 100644 --- a/lms/djangoapps/instructor/views/api.py +++ b/lms/djangoapps/instructor/views/api.py @@ -1099,7 +1099,7 @@ def registration_codes_csv(file_name, codes_list, csv_type=None): """ # csv headers query_features = [ - 'code', 'course_id', 'company_name', 'created_by', + 'code', 'redeem_code_url', 'course_id', 'company_name', 'created_by', 'redeemed_by', 'invoice_id', 'purchaser', 'customer_reference_number', 'internal_reference' ] @@ -1267,8 +1267,11 @@ def generate_registration_codes(request, course_id): csv_file = StringIO.StringIO() csv_writer = csv.writer(csv_file) for registration_code in registration_codes: - csv_writer.writerow([registration_code.code]) - + full_redeem_code_url = 'http://{base_url}{redeem_code_url}'.format( + base_url=microsite.get_value('SITE_NAME', settings.SITE_NAME), + redeem_code_url=reverse('register_code_redemption', kwargs={'registration_code': registration_code.code}) + ) + csv_writer.writerow([registration_code.code, full_redeem_code_url]) finance_email = microsite.get_value('finance_email', settings.FINANCE_EMAIL) if finance_email: # append the finance email into the recipient_list diff --git a/lms/djangoapps/instructor_analytics/basic.py b/lms/djangoapps/instructor_analytics/basic.py index 7c9726cc90..7d8e45a5e6 100644 --- a/lms/djangoapps/instructor_analytics/basic.py +++ b/lms/djangoapps/instructor_analytics/basic.py @@ -9,9 +9,12 @@ from shoppingcart.models import ( OrderTypes, RegistrationCodeRedemption, CourseRegistrationCode ) from django.db.models import Q +from django.conf import settings from django.contrib.auth.models import User +from django.core.urlresolvers import reverse import xmodule.graders as xmgraders from django.core.exceptions import ObjectDoesNotExist +from microsite_configuration import microsite STUDENT_FEATURES = ('id', 'username', 'first_name', 'last_name', 'is_staff', 'email') @@ -251,6 +254,7 @@ def course_registration_features(features, registration_codes, csv_type): :param features: :param csv_type: """ + site_name = microsite.get_value('SITE_NAME', settings.SITE_NAME) registration_features = [x for x in COURSE_REGISTRATION_FEATURES if x in features] course_registration_dict = dict((feature, getattr(registration_code, feature)) for feature in registration_features) @@ -265,6 +269,11 @@ def course_registration_features(features, registration_codes, csv_type): course_registration_dict['customer_reference_number'] = sale_invoice.customer_reference_number course_registration_dict['internal_reference'] = sale_invoice.internal_reference + course_registration_dict['redeem_code_url'] = 'http://{base_url}{redeem_code_url}'.format( + base_url=site_name, + redeem_code_url=reverse('register_code_redemption', + kwargs={'registration_code': registration_code.code}) + ) # we have to capture the redeemed_by value in the case of the downloading and spent registration # codes csv. In the case of active and generated registration codes the redeemed_by value will be None. # They have not been redeemed yet diff --git a/lms/djangoapps/instructor_analytics/tests/test_basic.py b/lms/djangoapps/instructor_analytics/tests/test_basic.py index a532ccaa35..6d2a6ab905 100644 --- a/lms/djangoapps/instructor_analytics/tests/test_basic.py +++ b/lms/djangoapps/instructor_analytics/tests/test_basic.py @@ -284,7 +284,7 @@ class TestCourseRegistrationCodeAnalyticsBasic(ModuleStoreTestCase): def test_course_registration_features(self): query_features = [ - 'code', 'course_id', 'company_name', 'created_by', + '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')