paidcourse_enrollment_report.py 8.89 KB
Newer Older
1 2 3 4 5 6
"""
Defines concrete class for cybersource  Enrollment Report.

"""
from courseware.access import has_access
import collections
7
from django.conf import settings
8 9
from django.utils.translation import ugettext as _
from courseware.courses import get_course_by_id
10
from lms.djangoapps.instructor.enrollment_report import BaseAbstractEnrollmentReportProvider
11 12
from shoppingcart.models import RegistrationCodeRedemption, PaidCourseRegistration, CouponRedemption, OrderItem, \
    InvoiceTransaction
13
from student.models import CourseEnrollment, ManualEnrollmentAudit
14
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
15 16 17 18 19 20 21 22 23 24 25 26


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)
27
        is_course_staff = bool(has_access(user, 'staff', course))
28
        manual_enrollment_reason = 'N/A'
29 30 31

        # check the user enrollment role
        if user.is_staff:
32
            platform_name = configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME)
33
            enrollment_role = _('{platform_name} Staff').format(platform_name=platform_name)
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
        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:
60 61 62
                manual_enrollment = ManualEnrollmentAudit.get_manual_enrollment(course_enrollment)
                if manual_enrollment is not None:
                    enrollment_source = _(
63 64 65 66
                        'manually enrolled by username: {username}'
                    ).format(username=manual_enrollment.enrolled_by.username)

                    manual_enrollment_reason = manual_enrollment.reason
67 68
                else:
                    enrollment_source = _('Manually Enrolled')
69 70 71 72 73 74 75 76

        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
77
        course_enrollment_data['Manual (Un)Enrollment Reason'] = manual_enrollment_reason
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
        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'

101
            list_price = paid_course_reg_item.get_list_price()
102 103 104 105 106 107 108 109 110 111 112 113
            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
114
                if registration_code.invoice_item_id:
115 116 117 118
                    list_price, payment_amount, payment_status, transaction_reference_number =\
                        self._get_invoice_data(registration_code_redemption)
                    coupon_codes_used = 'N/A'

119
                elif registration_code_redemption.registration_code.order_id:
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
                    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)

159
        list_price = order_item.get_list_price()
160 161 162 163 164 165 166 167 168 169 170
        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
171
        list_price = registration_code.invoice_item.unit_price
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
        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