Remove final shoppingcart references from instructor.

This commit is contained in:
Diana Huang
2020-07-07 16:19:39 -04:00
parent e8a7529243
commit 1655ecd063
12 changed files with 0 additions and 633 deletions

View File

@@ -1,102 +0,0 @@
"""
Defines abstract class for the Enrollment Reports.
"""
import abc
import collections
import json
import six
from django.contrib.auth.models import User
from student.models import UserProfile
class AbstractEnrollmentReportProvider(six.with_metaclass(abc.ABCMeta, object)):
"""
Abstract interface for Detailed Enrollment Report Provider
"""
@abc.abstractmethod
def get_enrollment_info(self, user, course_id):
"""
Returns the User Enrollment information.
"""
raise NotImplementedError()
@abc.abstractmethod
def get_user_profile(self, user_id):
"""
Returns the UserProfile information.
"""
raise NotImplementedError()
@abc.abstractmethod
def get_payment_info(self, user, course_id):
"""
Returns the User Payment information.
"""
raise NotImplementedError()
class BaseAbstractEnrollmentReportProvider(AbstractEnrollmentReportProvider):
"""
The base abstract class for all Enrollment Reports that can support multiple
backend such as MySQL/Django-ORM.
# don't allow instantiation of this class, it must be subclassed
"""
def get_user_profile(self, user_id):
"""
Returns the UserProfile information.
"""
user_info = User.objects.select_related('profile').get(id=user_id)
# extended user profile fields are stored in the user_profile meta column
meta = {}
if user_info.profile.meta:
meta = json.loads(user_info.profile.meta)
user_data = collections.OrderedDict()
user_data['User ID'] = user_info.id
user_data['Username'] = user_info.username
user_data['Email'] = user_info.email
user_data['Full Name'] = user_info.profile.name
user_data['First Name'] = meta.get('first-name', '')
user_data['Last Name'] = meta.get('last-name', '')
user_data['Company Name'] = meta.get('company', '')
user_data['Title'] = meta.get('title', '')
user_data['Language'] = user_info.profile.language
user_data['Country'] = user_info.profile.country
user_data['Year of Birth'] = user_info.profile.year_of_birth
user_data['Gender'] = None
gender = user_info.profile.gender
for _gender in UserProfile.GENDER_CHOICES:
if gender == _gender[0]:
user_data['Gender'] = _gender[1]
break
user_data['Level of Education'] = None
level_of_education = user_info.profile.level_of_education
for _loe in UserProfile.LEVEL_OF_EDUCATION_CHOICES:
if level_of_education == _loe[0]:
user_data['Level of Education'] = _loe[1]
user_data['Mailing Address'] = user_info.profile.mailing_address
user_data['Goals'] = user_info.profile.goals
user_data['City'] = user_info.profile.city
user_data['Country'] = user_info.profile.country
return user_data
def get_enrollment_info(self, user, course_id):
"""
Returns the User Enrollment information.
"""
raise NotImplementedError()
def get_payment_info(self, user, course_id):
"""
Returns the User Payment information.
"""
raise NotImplementedError()

View File

@@ -1,196 +0,0 @@
"""
Defines concrete class for cybersource Enrollment Report.
"""
import collections
from django.conf import settings
from django.utils.translation import ugettext as _
from lms.djangoapps.courseware.access import has_access
from lms.djangoapps.courseware.courses import get_course_by_id
from lms.djangoapps.instructor.enrollment_report import BaseAbstractEnrollmentReportProvider
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from shoppingcart.models import (
CouponRedemption,
InvoiceTransaction,
OrderItem,
PaidCourseRegistration,
RegistrationCodeRedemption
)
from student.models import CourseEnrollment, ManualEnrollmentAudit
class PaidCourseEnrollmentReportProvider(BaseAbstractEnrollmentReportProvider):
"""
The concrete class for all CyberSource Enrollment Reports.
"""
def get_enrollment_info(self, user, course_id):
"""
Returns the User Enrollment information.
"""
course = get_course_by_id(course_id, depth=0)
is_course_staff = bool(has_access(user, 'staff', course))
manual_enrollment_reason = 'N/A'
# check the user enrollment role
if user.is_staff:
platform_name = configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME)
enrollment_role = _(u'{platform_name} Staff').format(platform_name=platform_name)
elif is_course_staff:
enrollment_role = _('Course Staff')
else:
enrollment_role = _('Student')
course_enrollment = CourseEnrollment.get_enrollment(user=user, course_key=course_id)
if is_course_staff:
enrollment_source = _('Staff')
else:
# get the registration_code_redemption object if exists
registration_code_redemption = RegistrationCodeRedemption.registration_code_used_for_enrollment(
course_enrollment)
# get the paid_course registration item if exists
paid_course_reg_item = PaidCourseRegistration.get_course_item_for_user_enrollment(
user=user,
course_id=course_id,
course_enrollment=course_enrollment
)
# from where the user get here
if registration_code_redemption is not None:
enrollment_source = _('Used Registration Code')
elif paid_course_reg_item is not None:
enrollment_source = _('Credit Card - Individual')
else:
manual_enrollment = ManualEnrollmentAudit.get_manual_enrollment(course_enrollment)
if manual_enrollment is not None:
enrollment_source = _(
u'manually enrolled by username: {username}'
).format(username=manual_enrollment.enrolled_by.username)
manual_enrollment_reason = manual_enrollment.reason
else:
enrollment_source = _('Manually Enrolled')
enrollment_date = course_enrollment.created.strftime(u"%B %d, %Y")
currently_enrolled = course_enrollment.is_active
course_enrollment_data = collections.OrderedDict()
course_enrollment_data['Enrollment Date'] = enrollment_date
course_enrollment_data['Currently Enrolled'] = currently_enrolled
course_enrollment_data['Enrollment Source'] = enrollment_source
course_enrollment_data['Manual (Un)Enrollment Reason'] = manual_enrollment_reason
course_enrollment_data['Enrollment Role'] = enrollment_role
return course_enrollment_data
def get_payment_info(self, user, course_id):
"""
Returns the User Payment information.
"""
course_enrollment = CourseEnrollment.get_enrollment(user=user, course_key=course_id)
paid_course_reg_item = PaidCourseRegistration.get_course_item_for_user_enrollment(
user=user,
course_id=course_id,
course_enrollment=course_enrollment
)
payment_data = collections.OrderedDict()
# check if the user made a single self purchase scenario
# for enrollment in the course.
if paid_course_reg_item is not None:
coupon_redemption = CouponRedemption.objects.select_related('coupon').filter(
order_id=paid_course_reg_item.order_id)
coupon_codes = [redemption.coupon.code for redemption in coupon_redemption]
coupon_codes = ", ".join(coupon_codes)
registration_code_used = 'N/A'
list_price = paid_course_reg_item.get_list_price()
payment_amount = paid_course_reg_item.unit_cost
coupon_codes_used = coupon_codes
payment_status = paid_course_reg_item.status
transaction_reference_number = paid_course_reg_item.order_id
else:
# check if the user used a registration code for the enrollment.
registration_code_redemption = RegistrationCodeRedemption.registration_code_used_for_enrollment(
course_enrollment)
if registration_code_redemption is not None:
registration_code = registration_code_redemption.registration_code
registration_code_used = registration_code.code
if registration_code.invoice_item_id:
list_price, payment_amount, payment_status, transaction_reference_number =\
self._get_invoice_data(registration_code_redemption)
coupon_codes_used = 'N/A'
elif registration_code_redemption.registration_code.order_id:
list_price, payment_amount, coupon_codes_used, payment_status, transaction_reference_number = \
self._get_order_data(registration_code_redemption, course_id)
else:
# this happens when the registration code is not created via invoice or bulk purchase
# scenario.
list_price = 'N/A'
payment_amount = 'N/A'
coupon_codes_used = 'N/A'
registration_code_used = 'N/A'
payment_status = _('Data Integrity Error')
transaction_reference_number = 'N/A'
else:
list_price = 'N/A'
payment_amount = 'N/A'
coupon_codes_used = 'N/A'
registration_code_used = 'N/A'
payment_status = _('TBD')
transaction_reference_number = 'N/A'
payment_data['List Price'] = list_price
payment_data['Payment Amount'] = payment_amount
payment_data['Coupon Codes Used'] = coupon_codes_used
payment_data['Registration Code Used'] = registration_code_used
payment_data['Payment Status'] = payment_status
payment_data['Transaction Reference Number'] = transaction_reference_number
return payment_data
def _get_order_data(self, registration_code_redemption, course_id):
"""
Returns the order data
"""
order_item = OrderItem.objects.get(order=registration_code_redemption.registration_code.order,
courseregcodeitem__course_id=course_id)
coupon_redemption = CouponRedemption.objects.select_related('coupon').filter(
order_id=registration_code_redemption.registration_code.order)
coupon_codes = [redemption.coupon.code for redemption in coupon_redemption]
coupon_codes = ", ".join(coupon_codes)
list_price = order_item.get_list_price()
payment_amount = order_item.unit_cost
coupon_codes_used = coupon_codes
payment_status = order_item.status
transaction_reference_number = order_item.order_id
return list_price, payment_amount, coupon_codes_used, payment_status, transaction_reference_number
def _get_invoice_data(self, registration_code_redemption):
"""
Returns the Invoice data
"""
registration_code = registration_code_redemption.registration_code
list_price = registration_code.invoice_item.unit_price
total_amount = registration_code_redemption.registration_code.invoice.total_amount
qty = registration_code_redemption.registration_code.invoice_item.qty
payment_amount = total_amount / qty
invoice_transaction = InvoiceTransaction.get_invoice_transaction(
invoice_id=registration_code_redemption.registration_code.invoice.id)
if invoice_transaction is not None:
# amount greater than 0 is invoice has bee paid
if invoice_transaction.amount > 0:
payment_status = 'Invoice Paid'
else:
# amount less than 0 is invoice has been refunded
payment_status = 'Refunded'
else:
payment_status = 'Invoice Outstanding'
transaction_reference_number = registration_code_redemption.registration_code.invoice_id
return list_price, payment_amount, payment_status, transaction_reference_number

View File

@@ -118,12 +118,6 @@ REPORTS_DATA = (
'task_api_endpoint': 'lms.djangoapps.instructor_task.api.submit_calculate_students_features_csv',
'extra_instructor_api_kwargs': {'csv': '/csv'}
},
{
'report_type': 'detailed enrollment',
'instructor_api_endpoint': 'get_enrollment_report',
'task_api_endpoint': 'lms.djangoapps.instructor_task.api.submit_detailed_enrollment_features_csv',
'extra_instructor_api_kwargs': {}
},
{
'report_type': 'enrollment',
'instructor_api_endpoint': 'get_students_who_may_enroll',
@@ -155,7 +149,6 @@ INSTRUCTOR_POST_ENDPOINTS = set([
'calculate_grades_csv',
'change_due_date',
'export_ora2_data',
'get_enrollment_report',
'get_grading_config',
'get_problem_responses',
'get_proctored_exam_results',
@@ -431,7 +424,6 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
('list_report_downloads', {}),
('calculate_grades_csv', {}),
('get_students_features', {}),
('get_enrollment_report', {}),
('get_students_who_may_enroll', {}),
('get_proctored_exam_results', {}),
('get_problem_responses', {}),

View File

@@ -1,77 +0,0 @@
"""
Exercises tests on the base_store_provider file
"""
from django.test import TestCase
from lms.djangoapps.instructor.enrollment_report import AbstractEnrollmentReportProvider
from lms.djangoapps.instructor.paidcourse_enrollment_report import PaidCourseEnrollmentReportProvider
class BadImplementationAbstractEnrollmentReportProvider(AbstractEnrollmentReportProvider):
"""
Test implementation of EnrollmentProvider to assert that non-implementations of methods
raises the correct methods
"""
def get_user_profile(self, user_id):
"""
Fake implementation of method which calls base class, which should throw NotImplementedError
"""
super(BadImplementationAbstractEnrollmentReportProvider, self).get_user_profile(user_id)
def get_enrollment_info(self, user, course_id):
"""
Fake implementation of method which calls base class, which should throw NotImplementedError
"""
super(BadImplementationAbstractEnrollmentReportProvider, self).get_enrollment_info(user, course_id)
def get_payment_info(self, user, course_id):
"""
Fake implementation of method which calls base class, which should throw NotImplementedError
"""
super(BadImplementationAbstractEnrollmentReportProvider, self).get_payment_info(user, course_id)
class TestBaseNotificationDataProvider(TestCase):
"""
Cover the EnrollmentReportProvider class
"""
def test_cannot_create_instance(self):
"""
EnrollmentReportProvider is an abstract class and we should not be able
to create an instance of it
"""
with self.assertRaises(TypeError):
# parent of the BaseEnrollmentReportProvider is EnrollmentReportProvider
super(BadImplementationAbstractEnrollmentReportProvider, self)
def test_get_provider(self):
"""
Makes sure we get an instance of the registered enrollment provider
"""
provider = PaidCourseEnrollmentReportProvider()
self.assertIsNotNone(provider)
self.assertTrue(isinstance(provider, PaidCourseEnrollmentReportProvider))
def test_base_methods_exceptions(self):
"""
Asserts that all base-methods on the EnrollmentProvider interface will throw
an NotImplementedError
"""
bad_provider = BadImplementationAbstractEnrollmentReportProvider()
with self.assertRaises(NotImplementedError):
bad_provider.get_enrollment_info(None, None)
with self.assertRaises(NotImplementedError):
bad_provider.get_payment_info(None, None)
with self.assertRaises(NotImplementedError):
bad_provider.get_user_profile(None)

View File

@@ -1312,25 +1312,6 @@ class CohortCSV(DeveloperErrorViewMixin, APIView):
return Response(status=status.HTTP_204_NO_CONTENT)
@transaction.non_atomic_requests
@require_POST
@ensure_csrf_cookie
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@require_course_permission(permissions.ENROLLMENT_REPORT)
@require_finance_admin
@common_exceptions_400
def get_enrollment_report(request, course_id):
"""
get the enrollment report for the particular course.
"""
course_key = CourseKey.from_string(course_id)
report_type = _('detailed enrollment')
task_api.submit_detailed_enrollment_features_csv(request, course_key)
success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type)
return JsonResponse({"status": success_status})
@transaction.non_atomic_requests
@require_POST
@ensure_csrf_cookie

View File

@@ -51,7 +51,6 @@ urlpatterns = [
url(r'^problem_grade_report$', api.problem_grade_report, name='problem_grade_report'),
# Reports..
url(r'^get_enrollment_report$', api.get_enrollment_report, name='get_enrollment_report'),
url(r'^get_course_survey_results$', api.get_course_survey_results, name='get_course_survey_results'),
url(r'^export_ora2_data', api.export_ora2_data, name='export_ora2_data'),

View File

@@ -55,7 +55,6 @@ from openedx.core.djangoapps.verified_track_content.models import VerifiedTrackC
from openedx.core.djangolib.markup import HTML, Text
from openedx.core.lib.url_utils import quote_slashes
from openedx.core.lib.xblock_utils import wrap_xblock
from shoppingcart.models import Coupon, CourseRegCodeItem, PaidCourseRegistration
from student.models import CourseEnrollment
from student.roles import (
CourseFinanceAdminRole, CourseInstructorRole,
@@ -182,10 +181,6 @@ def instructor_dashboard_2(request, course_id):
if is_bulk_email_feature_enabled(course_key) and (access['staff'] or access['instructor']):
sections.append(_section_send_email(course, access))
# Gate access to Ecommerce tab
if course_mode_has_price and (access['finance_admin'] or access['sales_admin']):
sections.append(_section_e_commerce(course, access, paid_modes[0], is_white_label, reports_enabled))
# Gate access to Special Exam tab depending if either timed exams or proctored exams
# are enabled in the course
@@ -280,74 +275,6 @@ def instructor_dashboard_2(request, course_id):
## section_key will be used as a css attribute, javascript tie-in, and template import filename.
## section_display_name will be used to generate link titles in the nav bar.
def _section_e_commerce(course, access, paid_mode, coupons_enabled, reports_enabled):
""" Provide data for the corresponding dashboard section """
course_key = course.id
coupons = Coupon.objects.filter(course_id=course_key).order_by('-is_active')
course_price = paid_mode.min_price
total_amount = None
if access['finance_admin']:
single_purchase_total = PaidCourseRegistration.get_total_amount_of_purchased_item(course_key)
bulk_purchase_total = CourseRegCodeItem.get_total_amount_of_purchased_item(course_key)
total_amount = single_purchase_total + bulk_purchase_total
section_data = {
'section_key': 'e-commerce',
'section_display_name': _('E-Commerce'),
'access': access,
'course_id': six.text_type(course_key),
'currency_symbol': settings.PAID_COURSE_REGISTRATION_CURRENCY[1],
'ajax_remove_coupon_url': reverse('remove_coupon', kwargs={'course_id': six.text_type(course_key)}),
'ajax_get_coupon_info': reverse('get_coupon_info', kwargs={'course_id': six.text_type(course_key)}),
'get_user_invoice_preference_url': reverse(
'get_user_invoice_preference',
kwargs={'course_id': six.text_type(course_key)}
),
'sale_validation_url': reverse('sale_validation', kwargs={'course_id': six.text_type(course_key)}),
'ajax_update_coupon': reverse('update_coupon', kwargs={'course_id': six.text_type(course_key)}),
'ajax_add_coupon': reverse('add_coupon', kwargs={'course_id': six.text_type(course_key)}),
'instructor_url': reverse('instructor_dashboard', kwargs={'course_id': six.text_type(course_key)}),
'get_registration_code_csv_url': reverse(
'get_registration_codes',
kwargs={'course_id': six.text_type(course_key)}
),
'generate_registration_code_csv_url': reverse(
'generate_registration_codes',
kwargs={'course_id': six.text_type(course_key)}
),
'active_registration_code_csv_url': reverse(
'active_registration_codes',
kwargs={'course_id': six.text_type(course_key)}
),
'spent_registration_code_csv_url': reverse(
'spent_registration_codes',
kwargs={'course_id': six.text_type(course_key)}
),
'set_course_mode_url': reverse('set_course_mode_price', kwargs={'course_id': six.text_type(course_key)}),
'download_coupon_codes_url': reverse('get_coupon_codes', kwargs={'course_id': six.text_type(course_key)}),
'enrollment_report_url': reverse('get_enrollment_report', kwargs={'course_id': six.text_type(course_key)}),
'list_financial_report_downloads_url': reverse(
'list_financial_report_downloads',
kwargs={'course_id': six.text_type(course_key)}
),
'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': six.text_type(course_key)}),
'look_up_registration_code': reverse(
'look_up_registration_code',
kwargs={'course_id': six.text_type(course_key)}
),
'coupons': coupons,
'sales_admin': access['sales_admin'],
'coupons_enabled': coupons_enabled,
'reports_enabled': reports_enabled,
'course_price': course_price,
'total_amount': total_amount,
'is_ecommerce_course': is_ecommerce_course(course_key)
}
return section_data
def _section_special_exams(course, access):
""" Provide data for the corresponding dashboard section """
course_key = six.text_type(course.id)

View File

@@ -34,7 +34,6 @@ from lms.djangoapps.instructor_task.tasks import (
cohort_students,
course_survey_report_csv,
delete_problem_state,
enrollment_report_features_csv,
export_ora2_data,
generate_certificates,
override_problem_score,
@@ -376,20 +375,6 @@ def submit_calculate_students_features_csv(request, course_key, features):
return submit_task(request, task_type, task_class, course_key, task_input, task_key)
def submit_detailed_enrollment_features_csv(request, course_key):
"""
Submits a task to generate a CSV containing detailed enrollment info.
Raises AlreadyRunningError if said CSV is already being updated.
"""
task_type = 'detailed_enrollment_report'
task_class = enrollment_report_features_csv
task_input = {}
task_key = ""
return submit_task(request, task_type, task_class, course_key, task_input, task_key)
def submit_calculate_may_enroll_csv(request, course_key, features):
"""
Submits a task to generate a CSV file containing information about

View File

@@ -32,7 +32,6 @@ from bulk_email.tasks import perform_delegate_email_batches
from lms.djangoapps.instructor_task.tasks_base import BaseInstructorTask
from lms.djangoapps.instructor_task.tasks_helper.certs import generate_students_certificates
from lms.djangoapps.instructor_task.tasks_helper.enrollments import (
upload_enrollment_report,
upload_may_enroll_csv,
upload_students_csv
)
@@ -217,18 +216,6 @@ def calculate_students_features_csv(entry_id, xmodule_instance_args):
return run_main_task(entry_id, task_fn, action_name)
@task(base=BaseInstructorTask)
def enrollment_report_features_csv(entry_id, xmodule_instance_args):
"""
Compute student profile information for a course and upload the
CSV to an S3 bucket for download.
"""
# Translators: This is a past-tense verb that is inserted into task progress messages as {action}.
action_name = ugettext_noop('generating_enrollment_report')
task_fn = partial(upload_enrollment_report, xmodule_instance_args)
return run_main_task(entry_id, task_fn, action_name)
@task(base=BaseInstructorTask)
def course_survey_report_csv(entry_id, xmodule_instance_args):
"""

View File

@@ -14,7 +14,6 @@ from six import StringIO
from edxmako.shortcuts import render_to_string
from lms.djangoapps.courseware.courses import get_course_by_id
from lms.djangoapps.instructor.paidcourse_enrollment_report import PaidCourseEnrollmentReportProvider
from lms.djangoapps.instructor_analytics.basic import enrolled_students_features, list_may_enroll
from lms.djangoapps.instructor_analytics.csvs import format_dictlist
from lms.djangoapps.instructor_task.models import ReportStore
@@ -28,127 +27,6 @@ TASK_LOG = logging.getLogger('edx.celery.task')
FILTERED_OUT_ROLES = ['staff', 'instructor', 'finance_admin', 'sales_admin']
def upload_enrollment_report(_xmodule_instance_args, _entry_id, course_id, _task_input, action_name):
"""
For a given `course_id`, generate a CSV file containing profile
information for all students that are enrolled, and store using a
`ReportStore`.
"""
start_time = time()
start_date = datetime.now(UTC)
status_interval = 100
students_in_course = CourseEnrollment.objects.enrolled_and_dropped_out_users(course_id)
task_progress = TaskProgress(action_name, students_in_course.count(), start_time)
fmt = u'Task: {task_id}, InstructorTask ID: {entry_id}, Course: {course_id}, Input: {task_input}'
task_info_string = fmt.format(
task_id=_xmodule_instance_args.get('task_id') if _xmodule_instance_args is not None else None,
entry_id=_entry_id,
course_id=course_id,
task_input=_task_input
)
TASK_LOG.info(u'%s, Task type: %s, Starting task execution', task_info_string, action_name)
# Loop over all our students and build our CSV lists in memory
rows = []
header = None
current_step = {'step': 'Gathering Profile Information'}
enrollment_report_provider = PaidCourseEnrollmentReportProvider()
total_students = students_in_course.count()
student_counter = 0
TASK_LOG.info(
u'%s, Task type: %s, Current step: %s, generating detailed enrollment report for total students: %s',
task_info_string,
action_name,
current_step,
total_students
)
for student in students_in_course:
# Periodically update task status (this is a cache write)
if task_progress.attempted % status_interval == 0:
task_progress.update_task_state(extra_meta=current_step)
task_progress.attempted += 1
# Now add a log entry after certain intervals to get a hint that task is in progress
student_counter += 1
if student_counter % 100 == 0:
TASK_LOG.info(
u'%s, Task type: %s, Current step: %s, gathering enrollment profile for students in progress: %s/%s',
task_info_string,
action_name,
current_step,
student_counter,
total_students
)
user_data = enrollment_report_provider.get_user_profile(student.id)
course_enrollment_data = enrollment_report_provider.get_enrollment_info(student, course_id)
payment_data = enrollment_report_provider.get_payment_info(student, course_id)
# display name map for the column headers
enrollment_report_headers = {
'User ID': _('User ID'),
'Username': _('Username'),
'Full Name': _('Full Name'),
'First Name': _('First Name'),
'Last Name': _('Last Name'),
'Company Name': _('Company Name'),
'Title': _('Title'),
'Language': _('Language'),
'Year of Birth': _('Year of Birth'),
'Gender': _('Gender'),
'Level of Education': _('Level of Education'),
'Mailing Address': _('Mailing Address'),
'Goals': _('Goals'),
'City': _('City'),
'Country': _('Country'),
'Enrollment Date': _('Enrollment Date'),
'Currently Enrolled': _('Currently Enrolled'),
'Enrollment Source': _('Enrollment Source'),
'Manual (Un)Enrollment Reason': _('Manual (Un)Enrollment Reason'),
'Enrollment Role': _('Enrollment Role'),
'List Price': _('List Price'),
'Payment Amount': _('Payment Amount'),
'Coupon Codes Used': _('Coupon Codes Used'),
'Registration Code Used': _('Registration Code Used'),
'Payment Status': _('Payment Status'),
'Transaction Reference Number': _('Transaction Reference Number')
}
if not header:
header = list(user_data.keys()) + list(course_enrollment_data.keys()) + list(payment_data.keys())
display_headers = []
for header_element in header:
# translate header into a localizable display string
display_headers.append(enrollment_report_headers.get(header_element, header_element))
rows.append(display_headers)
rows.append(list(user_data.values()) + list(course_enrollment_data.values()) + list(payment_data.values()))
task_progress.succeeded += 1
TASK_LOG.info(
u'%s, Task type: %s, Current step: %s, Detailed enrollment report generated for students: %s/%s',
task_info_string,
action_name,
current_step,
student_counter,
total_students
)
# By this point, we've got the rows we're going to stuff into our CSV files.
current_step = {'step': 'Uploading CSVs'}
task_progress.update_task_state(extra_meta=current_step)
TASK_LOG.info(u'%s, Task type: %s, Current step: %s', task_info_string, action_name, current_step)
# Perform the actual upload
upload_csv_to_report_store(rows, 'enrollment_report', course_id, start_date, config_name='FINANCIAL_REPORTS')
# One last update before we close out...
TASK_LOG.info(u'%s, Task type: %s, Finalizing detailed enrollment task', task_info_string, action_name)
return task_progress.update_task_state(extra_meta=current_step)
def upload_may_enroll_csv(_xmodule_instance_args, _entry_id, course_id, task_input, action_name):
"""
For a given `course_id`, generate a CSV file containing

View File

@@ -26,7 +26,6 @@ from lms.djangoapps.instructor_task.api import (
submit_course_survey_report,
submit_delete_entrance_exam_state_for_student,
submit_delete_problem_state_for_all_students,
submit_detailed_enrollment_features_csv,
submit_export_ora2_data,
submit_override_score,
submit_rescore_entrance_exam_for_student,
@@ -251,11 +250,6 @@ class InstructorTaskCourseSubmitTest(TestReportMixin, InstructorTaskCourseTestCa
)
self._test_resubmission(api_call)
def test_submit_enrollment_report_features_csv(self):
api_call = lambda: submit_detailed_enrollment_features_csv(self.create_task_request(self.instructor),
self.course.id)
self._test_resubmission(api_call)
def test_submit_course_survey_report(self):
api_call = lambda: submit_course_survey_report(
self.create_task_request(self.instructor), self.course.id

View File

@@ -43,7 +43,6 @@ from lms.djangoapps.grades.transformer import GradesTransformer
from lms.djangoapps.instructor_analytics.basic import UNAVAILABLE, list_problem_responses
from lms.djangoapps.instructor_task.tasks_helper.certs import generate_students_certificates
from lms.djangoapps.instructor_task.tasks_helper.enrollments import (
upload_enrollment_report,
upload_may_enroll_csv,
upload_students_csv
)