195 lines
8.9 KiB
Python
195 lines
8.9 KiB
Python
"""
|
|
Defines concrete class for cybersource Enrollment Report.
|
|
|
|
"""
|
|
import collections
|
|
|
|
from django.conf import settings
|
|
from django.utils.translation import ugettext as _
|
|
|
|
from courseware.access import has_access
|
|
from 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 = _('{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 = _(
|
|
'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("%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
|