Update subscription form to use new card validations for Stripe payment method

This commit is contained in:
Rob Harrington
2018-05-09 11:39:56 +10:00
committed by Maikel Linke
parent a03dd1e10c
commit c71a5ec0df
6 changed files with 50 additions and 52 deletions

View File

@@ -1,38 +1,42 @@
angular.module("admin.subscriptions").controller "DetailsController", ($scope, $http, CreditCardResource, StatusMessage) ->
angular.module("admin.subscriptions").controller "DetailsController", ($scope, $http, CustomerResource, StatusMessage) ->
$scope.cardRequired = false
$scope.registerNextCallback 'details', ->
$scope.subscription_form.$submitted = true
if $scope.subscription_details_form.$valid
$scope.subscription_form.$setPristine()
StatusMessage.clear()
$scope.setView('address')
else
StatusMessage.display 'failure', t('admin.subscriptions.details.invalid_error')
return unless $scope.validate()
$scope.subscription_form.$setPristine()
StatusMessage.clear()
$scope.setView('address')
$scope.$watch "subscription.customer_id", (newValue, oldValue) ->
return if !newValue?
$scope.loadAddresses(newValue) unless $scope.subscription.id?
$scope.loadCreditCards(newValue)
$scope.loadCustomer(newValue) unless $scope.subscription.id?
$scope.$watch "subscription.payment_method_id", (newValue, oldValue) ->
return if !newValue?
paymentMethod = ($scope.paymentMethods.filter (pm) -> pm.id == newValue)[0]
return unless paymentMethod?
if paymentMethod.type == "Spree::Gateway::StripeConnect"
$scope.cardRequired = true
else
$scope.cardRequired = false
$scope.subscription.credit_card_id = null
$scope.cardRequired = (paymentMethod.type == "Spree::Gateway::StripeConnect")
$scope.loadCustomer() if $scope.cardRequired && !$scope.customer
$scope.loadAddresses = (customer_id) ->
$http.get("/admin/customers/#{customer_id}/addresses")
.success (response) =>
delete response.bill_address.id
delete response.ship_address.id
angular.extend($scope.subscription.bill_address, response.bill_address)
angular.extend($scope.subscription.ship_address, response.ship_address)
$scope.shipAddressFromBilling() unless response.ship_address.address1?
$scope.loadCustomer = ->
params = { id: $scope.subscription.customer_id }
$scope.customer = CustomerResource.get params, (response) ->
for address in ['bill_address','ship_address']
return unless response[address]
delete response[address].id
return if $scope.subscription[address].address1?
angular.extend($scope.subscription[address], response[address])
$scope.shipAddressFromBilling() unless response.ship_address?.address1?
$scope.loadCreditCards = (customer_id) ->
$scope.creditCards = CreditCardResource.index(customer_id: customer_id)
$scope.validate = ->
return true if $scope.subscription_details_form.$valid && $scope.creditCardOk()
StatusMessage.display 'failure', t('admin.subscriptions.details.invalid_error')
false
$scope.creditCardOk = ->
return true unless $scope.cardRequired
return false unless $scope.customer
return false unless $scope.customer.allow_charges
return false unless $scope.customer.default_card_present
true

View File

@@ -1,5 +0,0 @@
angular.module("admin.subscriptions").factory 'CreditCardResource', ($resource) ->
resource = $resource '/admin/customers/:customer_id/cards.json', {},
'index':
method: 'GET'
isArray: true

View File

@@ -0,0 +1,2 @@
angular.module("admin.subscriptions").factory 'CustomerResource', ($resource) ->
$resource '/admin/customers/:id.json'

View File

@@ -14,19 +14,16 @@
.error{ ng: { repeat: 'error in errors.schedule', show: 'subscription_details_form.schedule_id.$pristine'} } {{ error }}
.row
.columns.alpha.field{ ng: { class: '{four: cardRequired, seven: !cardRequired}' } }
.seven.columns.alpha.field
%label{ for: 'payment_method_id'}
= t('admin.payment_method')
%span.with-tip.icon-question-sign{ data: { powertip: "#{t('.allowed_payment_method_types_tip')}" } }
%input.ofn-select2.fullwidth#payment_method_id{ name: 'payment_method_id', type: 'number', data: 'paymentMethods', required: true, placeholder: t('admin.choose'), ng: { model: 'subscription.payment_method_id' } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_details_form.payment_method_id.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.payment_method', show: 'subscription_details_form.payment_method_id.$pristine' } } {{ error }}
.three.columns.field{ ng: { show: 'cardRequired' } }
%label{ for: 'credit_card_id'}= t('.credit_card')
%input.ofn-select2.fullwidth#credit_card_id{ name: 'credit_card_id', type: 'number', data: 'creditCards', text: 'formatted', placeholder: t('admin.choose'), ng: { model: 'subscription.credit_card_id', required: "cardRequired" } }
.error{ ng: { show: 'creditCards.$promise && creditCards.$resolved && creditCards.length == 0' } }= t('.no_cards_available')
.error{ ng: { show: 'subscription_form.$submitted && subscription_details_form.credit_card_id.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.credit_card', show: 'subscription_details_form.credit_card_id.$pristine' } } {{ error }}
.error{ ng: { show: 'cardRequired && customer.$promise && customer.$resolved && !customer.allow_charges' } }= t('.charges_not_allowed')
.error{ ng: { show: 'cardRequired && customer.$promise && customer.$resolved && customer.allow_charges && !customer.default_card_present' } }= t('.no_default_card')
.error{ ng: { repeat: 'error in errors.credit_card', show: 'subscription_details_form.payment_method_id.$pristine' } } {{ error }}
.two.columns  
.seven.columns.omega.field
%label{ for: 'shipping_method_id'}= t('admin.shipping_method')

View File

@@ -100,8 +100,8 @@ en:
shipping_method:
not_available_to_shop: "is not available to %{shop}"
credit_card:
not_available: "is not available"
blank: "is required"
charges_not_allowed: "charges are not allowed by this customer"
no_default_card: "not available for this customer"
devise:
confirmations:
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
@@ -1025,7 +1025,9 @@ en:
invalid_error: Oops! Please fill in all of the required fields...
allowed_payment_method_types_tip: Only Cash and Stripe payment methods may be used at the moment
credit_card: Credit Card
no_cards_available: No cards available
charges_not_allowed: Charges are not allowed by this customer
no_default_card: Customer has no cards available to charge
card_ok: Customer has a card available to charge
loading_flash:
loading: LOADING SUBSCRIPTIONS
review:

View File

@@ -124,9 +124,7 @@ feature 'Subscriptions' do
let(:address) { create(:address) }
let!(:customer_user) { create(:user) }
let!(:credit_card1) { create(:credit_card, user: customer_user, cc_type: 'visa', last_digits: 1111, month: 10, year: 2030) }
let!(:credit_card2) { create(:credit_card, user: customer_user, cc_type: 'master', last_digits: 9999, month: 2, year: 2044) }
let!(:credit_card3) { create(:credit_card, cc_type: 'visa', last_digits: 5555, month: 6, year: 2066) }
let!(:customer) { create(:customer, enterprise: shop, bill_address: address, user: customer_user) }
let!(:customer) { create(:customer, enterprise: shop, bill_address: address, user: customer_user, allow_charges: true) }
let!(:product1) { create(:product, supplier: shop) }
let!(:product2) { create(:product, supplier: shop) }
let!(:variant1) { create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: []) }
@@ -149,21 +147,14 @@ feature 'Subscriptions' do
select2_select payment_method.name, from: 'payment_method_id'
select2_select shipping_method.name, from: 'shipping_method_id'
# Credit card
card1_option = "Visa x-1111 #{I18n.t(:card_expiry_abbreviation)}:10/2030"
card2_option = "Master x-9999 #{I18n.t(:card_expiry_abbreviation)}:02/2044"
card3_option = "Visa x-5555 #{I18n.t(:card_expiry_abbreviation)}:06/2066"
expect(page).to have_select2 'credit_card_id', with_options: [card1_option, card2_option], without_options: [card3_option]
# No date or credit card filled out, so error returned
# No date, so error returned
click_button('Next')
expect(page).to have_content 'can\'t be blank', count: 2
expect(page).to have_content 'can\'t be blank', count: 1
expect(page).to have_content 'Oops! Please fill in all of the required fields...'
find_field('begins_at').click
within(".ui-datepicker-calendar") do
find('.ui-datepicker-today').click
end
select2_select card2_option, from: 'credit_card_id'
click_button('Next')
expect(page).to have_content 'BILLING ADDRESS'
@@ -263,7 +254,6 @@ feature 'Subscriptions' do
expect(subscription.shipping_method).to eq shipping_method
expect(subscription.bill_address.firstname).to eq 'Freda'
expect(subscription.ship_address.firstname).to eq 'Freda'
expect(subscription.credit_card_id).to eq credit_card2.id
# Standing Line Items are created
expect(subscription.subscription_line_items.count).to eq 1
@@ -287,6 +277,7 @@ feature 'Subscriptions' do
let!(:variant3_oc) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.from_now, orders_close_at: 7.days.from_now) }
let!(:variant3_ex) { variant3_oc.exchanges.create(sender: shop, receiver: shop, variants: [variant3]) }
let!(:payment_method) { create(:payment_method, distributors: [shop]) }
let!(:stripe_payment_method) { create(:stripe_payment_method, name: 'Credit Card', distributors: [shop], preferred_enterprise_id: shop.id) }
let!(:shipping_method) { create(:shipping_method, distributors: [shop]) }
let!(:subscription) {
create(:subscription,
@@ -306,6 +297,13 @@ feature 'Subscriptions' do
click_button 'edit-details'
expect(page).to have_selector '#s2id_customer_id.select2-container-disabled'
expect(page).to have_selector '#s2id_schedule_id.select2-container-disabled'
# Can't use a Stripe payment method because customer does not allow it
select2_select stripe_payment_method.name, from: 'payment_method_id'
expect(page).to have_content I18n.t('admin.subscriptions.details.charges_not_allowed')
click_button 'Save Changes'
expect(page).to have_content 'Credit card charges are not allowed by this customer'
select2_select payment_method.name, from: 'payment_method_id'
click_button 'Review'
# Existing products should be visible