You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

views.py 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. from django.template.response import TemplateResponse
  2. from oscar.apps.checkout.views import (PaymentMethodView as CorePaymentMethodView,
  3. PaymentDetailsView as CorePaymentDetailsView,
  4. OrderPreviewView as CoreOrderPreviewView)
  5. from oscar.apps.payment.forms import BankcardForm, BillingAddressForm
  6. from oscar.apps.shipping.methods import ShippingMethod
  7. from oscar.core.loading import import_module
  8. import_module('payment.models', ['Source', 'SourceType'], locals())
  9. import_module('payment.exceptions', ['TransactionDeclinedException'], locals())
  10. import_module('payment.utils', ['Bankcard'], locals())
  11. import_module('payment.datacash.utils', ['Gateway', 'Facade'], locals())
  12. import_module('order.models', ['PaymentEvent', 'PaymentEventType', 'PaymentEventQuantity'], locals())
  13. class PaymentMethodView(CorePaymentMethodView):
  14. template_file = 'checkout/payment_method.html'
  15. def handle_GET(self):
  16. return TemplateResponse(self.request, self.template_file, self.context)
  17. def handle_POST(self):
  18. method = self.request.POST['method_code']
  19. self.co_data.pay_by(method)
  20. return self.get_success_response()
  21. class OrderPreviewView(CoreOrderPreviewView):
  22. u"""View a preview of the order before submitting."""
  23. def handle_GET(self):
  24. # Forward straight onto the payment details - no need for preview
  25. return self.get_success_response()
  26. class PaymentDetailsView(CorePaymentDetailsView):
  27. template_file = 'checkout/payment_details.html'
  28. def handle_GET(self):
  29. if self.is_cheque_payment():
  30. self.template_file = 'checkout/payment_details_cheque.html'
  31. else:
  32. shipping_addr = self.get_shipping_address()
  33. card_values = {'name': shipping_addr.name()}
  34. self.context['bankcard_form'] = BankcardForm(initial=card_values)
  35. addr_values = {'first_name': shipping_addr.first_name,
  36. 'last_name': shipping_addr.last_name,}
  37. self.context['billing_address_form'] = BillingAddressForm(initial=addr_values)
  38. return TemplateResponse(self.request, self.template_file, self.context)
  39. def handle_POST(self):
  40. if self.is_cheque_payment():
  41. return self.submit()
  42. try:
  43. self.bankcard_form = BankcardForm(self.request.POST)
  44. self.billing_addr_form = BillingAddressForm(self.request.POST)
  45. if self.bankcard_form.is_valid() and self.billing_addr_form.is_valid():
  46. return self.submit()
  47. except TransactionDeclinedException, e:
  48. self.context['payment_error'] = str(e)
  49. self.context['bankcard_form'] = self.bankcard_form
  50. self.context['billing_address_form'] = self.billing_addr_form
  51. return TemplateResponse(self.request, self.template_file, self.context)
  52. def handle_payment(self, order_number, total):
  53. if self.is_cheque_payment():
  54. self.handle_cheque_payment(total)
  55. else:
  56. self.handle_bankcard_payment(order_number, total)
  57. def is_cheque_payment(self):
  58. payment_method = self.co_data.payment_method()
  59. return payment_method == 'cheque'
  60. def handle_cheque_payment(self, total):
  61. # Nothing to do except create a payment source
  62. type,_ = SourceType.objects.get_or_create(name="Cheque")
  63. source = Source(type=type, allocation=total)
  64. self.payment_sources.append(source)
  65. def handle_bankcard_payment(self, order_number, total):
  66. # Handle payment problems with an exception
  67. # Make payment submission - handle response from DC
  68. # - could be an iframe open
  69. # - could be failure
  70. # - could be redirect
  71. # Create bankcard object
  72. bankcard = self.bankcard_form.get_bankcard_obj()
  73. # Handle new card submission
  74. dc_facade = Facade()
  75. reference = dc_facade.debit(order_number, total, bankcard, self.basket)
  76. # Create payment source (but don't save just yet)
  77. type,_ = SourceType.objects.get_or_create(name='DataCash', code='datacash')
  78. source = Source(type=type,
  79. allocation=total,
  80. amount_debited=total,
  81. reference=reference)
  82. self.payment_sources.append(source)
  83. def place_order(self, basket, order_number, total_incl_tax, total_excl_tax):
  84. order = super(PaymentDetailsView, self).place_order(basket, order_number, total_incl_tax, total_excl_tax)
  85. if self.is_cheque_payment():
  86. order.status = "Awaiting cheque"
  87. order.save()
  88. return order
  89. def create_billing_address(self):
  90. if not hasattr(self, 'billing_addr_form'):
  91. return None
  92. return self.billing_addr_form.save()
  93. def save_payment_events(self, order):
  94. event_type,_ = PaymentEventType.objects.get_or_create(code="paid-for")
  95. event = PaymentEvent.objects.create(order=order, event_type=event_type)
  96. for line in order.lines.all():
  97. line_qty = PaymentEventQuantity.objects.create(event=event,
  98. line=line,
  99. quantity=line.quantity)