paidcourse_enrollment_report.py 8.73 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 10
from django.utils.translation import ugettext as _
from courseware.courses import get_course_by_id
from instructor.enrollment_report import BaseAbstractEnrollmentReportProvider
11
from microsite_configuration import microsite
12 13
from shoppingcart.models import RegistrationCodeRedemption, PaidCourseRegistration, CouponRedemption, OrderItem, \
    InvoiceTransaction
14
from student.models import CourseEnrollment, ManualEnrollmentAudit
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30


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 = has_access(user, 'staff', course)

        # check the user enrollment role
        if user.is_staff:
31 32
            platform_name = microsite.get_value('platform_name', settings.PLATFORM_NAME)
            enrollment_role = _('{platform_name} Staff').format(platform_name=platform_name)
33 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
        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:
59 60 61 62 63 64 65
                manual_enrollment = ManualEnrollmentAudit.get_manual_enrollment(course_enrollment)
                if manual_enrollment is not None:
                    enrollment_source = _(
                        'manually enrolled by user_id {user_id}, enrollment state transition: {transition}'
                    ).format(user_id=manual_enrollment.enrolled_by_id, transition=manual_enrollment.state_transition)
                else:
                    enrollment_source = _('Manually Enrolled')
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96

        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['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'

97
            list_price = paid_course_reg_item.get_list_price()
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 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
            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 getattr(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 getattr(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)

155
        list_price = order_item.get_list_price()
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
        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 = getattr(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