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:
Waheed Ahmed
2019-09-26 15:20:00 +05:00
parent e7a509faf0
commit 551f690ade
2 changed files with 67 additions and 31 deletions

View File

@@ -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):

View File

@@ -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):