Use order date_placed enrollment attribute for refund.
Use order date_placed enrollment attribute for refund if exist otherwise fetch it from ecommerce. PROD-454
This commit is contained in:
@@ -1765,8 +1765,45 @@ class CourseEnrollment(models.Model):
|
||||
# NOTE: This is here to avoid circular references
|
||||
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client, ECOMMERCE_DATE_FORMAT
|
||||
|
||||
date_placed = self.get_order_attribute_value('date_placed')
|
||||
|
||||
if not date_placed:
|
||||
order_number = self.get_order_attribute_value('order_number')
|
||||
if not order_number:
|
||||
return None
|
||||
|
||||
try:
|
||||
order = ecommerce_api_client(self.user).orders(order_number).get()
|
||||
date_placed = order['date_placed']
|
||||
except HttpClientError:
|
||||
log.warning(
|
||||
u"Encountered HttpClientError while getting order details from ecommerce. "
|
||||
u"Order={number} and user {user}".format(number=order_number, user=self.user.id))
|
||||
return None
|
||||
|
||||
except HttpServerError:
|
||||
log.warning(
|
||||
u"Encountered HttpServerError while getting order details from ecommerce. "
|
||||
u"Order={number} and user {user}".format(number=order_number, user=self.user.id))
|
||||
return None
|
||||
|
||||
except SlumberBaseException:
|
||||
log.warning(
|
||||
u"Encountered an error while getting order details from ecommerce. "
|
||||
u"Order={number} and user {user}".format(number=order_number, user=self.user.id))
|
||||
return None
|
||||
|
||||
refund_window_start_date = max(
|
||||
datetime.strptime(date_placed, ECOMMERCE_DATE_FORMAT),
|
||||
self.course_overview.start.replace(tzinfo=None)
|
||||
)
|
||||
|
||||
return refund_window_start_date.replace(tzinfo=UTC) + EnrollmentRefundConfiguration.current().refund_window
|
||||
|
||||
def get_order_attribute_value(self, attr_name):
|
||||
""" Get and return course enrollment order attribute's value."""
|
||||
try:
|
||||
attribute = self.attributes.get(namespace='order', name='order_number')
|
||||
attribute = self.attributes.get(namespace='order', name=attr_name)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
except MultipleObjectsReturned:
|
||||
@@ -1777,36 +1814,9 @@ class CourseEnrollment(models.Model):
|
||||
self.user.id,
|
||||
enrollment_id
|
||||
)
|
||||
attribute = self.attributes.filter(namespace='order', name='order_number').last()
|
||||
attribute = self.attributes.filter(namespace='order', name=attr_name).last()
|
||||
|
||||
order_number = attribute.value
|
||||
try:
|
||||
order = ecommerce_api_client(self.user).orders(order_number).get()
|
||||
|
||||
except HttpClientError:
|
||||
log.warning(
|
||||
u"Encountered HttpClientError while getting order details from ecommerce. "
|
||||
u"Order={number} and user {user}".format(number=order_number, user=self.user.id))
|
||||
return None
|
||||
|
||||
except HttpServerError:
|
||||
log.warning(
|
||||
u"Encountered HttpServerError while getting order details from ecommerce. "
|
||||
u"Order={number} and user {user}".format(number=order_number, user=self.user.id))
|
||||
return None
|
||||
|
||||
except SlumberBaseException:
|
||||
log.warning(
|
||||
u"Encountered an error while getting order details from ecommerce. "
|
||||
u"Order={number} and user {user}".format(number=order_number, user=self.user.id))
|
||||
return None
|
||||
|
||||
refund_window_start_date = max(
|
||||
datetime.strptime(order['date_placed'], ECOMMERCE_DATE_FORMAT),
|
||||
self.course_overview.start.replace(tzinfo=None)
|
||||
)
|
||||
|
||||
return refund_window_start_date.replace(tzinfo=UTC) + EnrollmentRefundConfiguration.current().refund_window
|
||||
return attribute.value
|
||||
|
||||
@property
|
||||
def username(self):
|
||||
|
||||
@@ -22,10 +22,11 @@ from six.moves import range
|
||||
# These imports refer to lms djangoapps.
|
||||
# Their testcases are only run under lms.
|
||||
from course_modes.tests.factories import CourseModeFactory
|
||||
|
||||
from lms.djangoapps.certificates.models import CertificateStatuses, GeneratedCertificate
|
||||
from lms.djangoapps.certificates.tests.factories import GeneratedCertificateFactory
|
||||
from openedx.core.djangoapps.commerce.utils import ECOMMERCE_DATE_FORMAT
|
||||
from student.models import CourseEnrollment
|
||||
from student.models import CourseEnrollment, EnrollmentRefundConfiguration
|
||||
from student.tests.factories import UserFactory
|
||||
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
@@ -169,6 +170,31 @@ class RefundableTest(SharedModuleStoreTestCase):
|
||||
""" Assert that the None is returned when no order number attribute is found."""
|
||||
self.assertIsNone(self.enrollment.refund_cutoff_date())
|
||||
|
||||
@patch('openedx.core.djangoapps.commerce.utils.ecommerce_api_client')
|
||||
def test_refund_cutoff_date_with_date_placed_attr(self, mock_ecommerce_api_client):
|
||||
"""
|
||||
Assert that the refund_cutoff_date returns order placement date if order:date_placed
|
||||
attribute exist without calling ecommerce.
|
||||
"""
|
||||
now = datetime.now(pytz.UTC).replace(microsecond=0)
|
||||
order_date = now + timedelta(days=2)
|
||||
course_start = now + timedelta(days=1)
|
||||
|
||||
self.enrollment.course_overview.start = course_start
|
||||
self.enrollment.attributes.create(
|
||||
enrollment=self.enrollment,
|
||||
namespace='order',
|
||||
name='date_placed',
|
||||
value=order_date.strftime(ECOMMERCE_DATE_FORMAT)
|
||||
)
|
||||
|
||||
refund_config = EnrollmentRefundConfiguration.current()
|
||||
self.assertEqual(
|
||||
self.enrollment.refund_cutoff_date(),
|
||||
order_date + refund_config.refund_window
|
||||
)
|
||||
mock_ecommerce_api_client.assert_not_called()
|
||||
|
||||
@httpretty.activate
|
||||
@override_settings(ECOMMERCE_API_URL=TEST_API_URL)
|
||||
def test_multiple_refunds_dashbaord_page_error(self):
|
||||
|
||||
Reference in New Issue
Block a user