mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Update subscription form to use new card validations for Stripe payment method
This commit is contained in:
committed by
Maikel Linke
parent
a03dd1e10c
commit
c71a5ec0df
@@ -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
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
angular.module("admin.subscriptions").factory 'CreditCardResource', ($resource) ->
|
||||
resource = $resource '/admin/customers/:customer_id/cards.json', {},
|
||||
'index':
|
||||
method: 'GET'
|
||||
isArray: true
|
||||
@@ -0,0 +1,2 @@
|
||||
angular.module("admin.subscriptions").factory 'CustomerResource', ($resource) ->
|
||||
$resource '/admin/customers/:id.json'
|
||||
@@ -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')
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user