diff --git a/ecommerce/extensions/dashboard/orders/tests.py b/ecommerce/extensions/dashboard/orders/tests.py index cfd96bcc429..8e8aea0b0eb 100644 --- a/ecommerce/extensions/dashboard/orders/tests.py +++ b/ecommerce/extensions/dashboard/orders/tests.py @@ -1,5 +1,5 @@ - +import json import os from unittest import SkipTest, skipIf @@ -16,6 +16,8 @@ from ecommerce.extensions.dashboard.tests import DashboardViewTestMixin from ecommerce.extensions.fulfillment.signals import SHIPPING_EVENT_NAME from ecommerce.extensions.fulfillment.status import LINE, ORDER +from ecommerce.extensions.iap.constants import MOBILE_PAYMENT_PROCESSORS +from ecommerce.extensions.payment.models import PaymentProcessorResponse from ecommerce.extensions.refund.tests.mixins import RefundTestMixin from ecommerce.extensions.test.factories import create_order from ecommerce.tests.factories import UserFactory @@ -240,6 +242,24 @@ def test_create_refund_error(self): 'A refund cannot be created for these lines. They may have already been refunded.', MSG.ERROR) + def test_mobile_refund_error(self): + """Verify the view creates a Refund for the Order and selected Lines.""" + # Create Order and Lines + order = self.create_order(user=self.user) + PaymentProcessorResponse.objects.create(basket=order.basket, + transaction_id="test-transaction", + processor_name=MOBILE_PAYMENT_PROCESSORS[0], + response=json.dumps({'state': 'approved'})) + + self.assertFalse(order.refunds.exists()) + # Validate the Refund + response = self._request_refund(order) + self.assertFalse(order.refunds.exists()) + + self.assert_message_equals(response, + "Mobile payment refunds aren't allowed in ecommerce.", + MSG.ERROR) + class OrderDetailViewBrowserTests(OrderViewTestsMixin, RefundTestMixin, OrderViewBrowserTestBase): diff --git a/ecommerce/extensions/dashboard/orders/views.py b/ecommerce/extensions/dashboard/orders/views.py index 55113e198ab..2b4e00323a8 100644 --- a/ecommerce/extensions/dashboard/orders/views.py +++ b/ecommerce/extensions/dashboard/orders/views.py @@ -9,6 +9,7 @@ from oscar.core.loading import get_model from ecommerce.extensions.dashboard.views import FilterFieldsMixin +from ecommerce.extensions.iap.constants import MOBILE_PAYMENT_PROCESSORS Order = get_model('order', 'Order') Partner = get_model('partner', 'Partner') @@ -62,20 +63,30 @@ class OrderDetailView(CoreOrderDetailView): line_actions = ('change_line_statuses', 'create_shipping_event', 'create_payment_event', 'create_refund') def create_refund(self, request, order, lines, _quantities): # pylint: disable=unused-argument - refund = Refund.create_with_lines(order, lines) - - if refund: - data = { - 'link_start': ''.format( - reverse('dashboard:refunds-detail', kwargs={'pk': refund.pk})), - 'link_end': '', - 'refund_id': refund.pk - } - message = _('{link_start}Refund #{refund_id}{link_end} created! ' - 'Click {link_start}here{link_end} to view it.').format(**data) - messages.success(request, mark_safe(message)) - else: - message = _('A refund cannot be created for these lines. They may have already been refunded.') + if self._is_order_from_mobile(order): + message = _("Mobile payment refunds aren't allowed in ecommerce.") messages.error(request, message) + else: + refund = Refund.create_with_lines(order, lines) + + if refund: + data = { + 'link_start': ''.format( + reverse('dashboard:refunds-detail', kwargs={'pk': refund.pk})), + 'link_end': '', + 'refund_id': refund.pk + } + message = _('{link_start}Refund #{refund_id}{link_end} created! ' + 'Click {link_start}here{link_end} to view it.').format(**data) + messages.success(request, mark_safe(message)) + else: + message = _('A refund cannot be created for these lines. They may have already been refunded.') + messages.error(request, message) + return self.reload_page() + + def _is_order_from_mobile(self, order): + processor_responses = order.basket.paymentprocessorresponse_set.all() + return any(response.processor_name in MOBILE_PAYMENT_PROCESSORS + for response in processor_responses) diff --git a/ecommerce/extensions/iap/constants.py b/ecommerce/extensions/iap/constants.py index 1efcd8d319d..2847da95e90 100644 --- a/ecommerce/extensions/iap/constants.py +++ b/ecommerce/extensions/iap/constants.py @@ -1,3 +1,4 @@ +MOBILE_PAYMENT_PROCESSORS = ['android-iap', 'ios-iap'] ANDROID_SKU_PREFIX = 'android' IOS_SKU_PREFIX = 'ios' MISSING_WEB_SEAT_ERROR = "Couldn't find existing web seat for course [%s]"