mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-04 02:31:33 +00:00
Adding live stripe account status display to payment method create/edit interface
This commit is contained in:
@@ -1,2 +1,18 @@
|
||||
angular.module("admin.paymentMethods").controller "StripeController", ($scope, shops) ->
|
||||
angular.module("admin.paymentMethods").controller "StripeController", ($scope, $http, shops) ->
|
||||
$scope.shops = shops
|
||||
$scope.stripe_account = {}
|
||||
|
||||
$scope.$watch "paymentMethod.preferred_enterprise_id", (newID, oldID) ->
|
||||
return unless newID?
|
||||
$scope.stripe_account = {}
|
||||
$http.get("/admin/enterprises/#{newID}/stripe_account.json").success (data) ->
|
||||
angular.extend($scope.stripe_account, data)
|
||||
.error (response) ->
|
||||
$scope.stripe_account.status = "request_failed"
|
||||
|
||||
$scope.current_enterprise_stripe_path = ->
|
||||
return unless $scope.paymentMethod.preferred_enterprise_id?
|
||||
permalink = shops.filter((shop) ->
|
||||
shop.id == $scope.paymentMethod.preferred_enterprise_id
|
||||
)[0].permalink
|
||||
"/admin/enterprises/#{permalink}/edit#stripe"
|
||||
|
||||
80
app/assets/stylesheets/admin/components/alert-box.css.scss
Normal file
80
app/assets/stylesheets/admin/components/alert-box.css.scss
Normal file
@@ -0,0 +1,80 @@
|
||||
@import "../../darkswarm/mixins";
|
||||
|
||||
.alert-box {
|
||||
position: relative;
|
||||
display: block;
|
||||
background-color: #eff5dc;
|
||||
border: 1px solid #9fc820;
|
||||
color: #666;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
@include border-radius(3px);
|
||||
|
||||
transition: opacity 300ms ease-out;
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
a.close {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
&.ok {
|
||||
border: 1px solid #9fc820;
|
||||
background-color: #fbffee;
|
||||
color: #9fc820;
|
||||
font-weight: bold;
|
||||
|
||||
a.button {
|
||||
padding: 3px 10px;
|
||||
background-color: #a7c44d;
|
||||
&:hover {
|
||||
background-color: #9fc820;
|
||||
}
|
||||
}
|
||||
|
||||
a.close {
|
||||
color: #9fc820;
|
||||
}
|
||||
}
|
||||
|
||||
&.error {
|
||||
border: 1px solid #c82020;
|
||||
background-color: #f5dcdc;
|
||||
color: #c82020;
|
||||
font-weight: bold;
|
||||
|
||||
a.button {
|
||||
padding: 3px 10px;
|
||||
background-color: #c85252;
|
||||
&:hover {
|
||||
background-color: #c82020;
|
||||
}
|
||||
}
|
||||
|
||||
a.close {
|
||||
color: #c82020;
|
||||
}
|
||||
}
|
||||
|
||||
&.warning {
|
||||
border: 1px solid #e6912e;
|
||||
background-color: #fff4e6;
|
||||
color: #e6912e;
|
||||
font-weight: bold;
|
||||
|
||||
a.button {
|
||||
padding: 3px 10px;
|
||||
background-color: #db9350;
|
||||
&:hover {
|
||||
background-color: #e6912e;
|
||||
}
|
||||
}
|
||||
|
||||
a.close {
|
||||
color: #e6912e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,5 @@
|
||||
@import "../darkswarm/mixins";
|
||||
|
||||
.alert-box {
|
||||
position: relative;
|
||||
display: block;
|
||||
background-color: #eff5dc;
|
||||
border: 1px solid #9fc820;
|
||||
color: #666;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
@include border-radius(3px);
|
||||
|
||||
transition: opacity 300ms ease-out;
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
a.close {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 0px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard_item.single-ent {
|
||||
.header {
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/ replace "div[data-hook='admin_payment_method_form_fields']"
|
||||
|
||||
= admin_inject_payment_method
|
||||
= admin_inject_json_ams_array "admin.paymentMethods", "shops", @hubs, Api::Admin::IdNameSerializer
|
||||
= admin_inject_json_ams_array "admin.paymentMethods", "shops", @hubs, Api::Admin::BasicEnterpriseSerializer
|
||||
%div.alpha.eleven.columns{ "ng-app" => "admin.paymentMethods", "ng-controller" => "paymentMethodCtrl" }
|
||||
.row
|
||||
.alpha.three.columns
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class Api::Admin::BasicEnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category, :payment_method_ids, :shipping_method_ids
|
||||
attributes :producer_profile_only
|
||||
attributes :producer_profile_only, :permalink
|
||||
end
|
||||
|
||||
@@ -5,7 +5,38 @@
|
||||
= fields_for :payment_method, @payment_method do |payment_method_form|
|
||||
= payment_method_form.label :stripe_account_owner
|
||||
%br
|
||||
-# = payment_method_form.collection_select(:preferred_enterprise_id, @hubs, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"})
|
||||
%input.ofn-select2.fullwidth#payment_method_preferred_enterprise_id{ type: 'number',
|
||||
name: 'payment_method[preferred_enterprise_id]',
|
||||
placeholder: t(".enterprise_select_placeholder"),
|
||||
data: 'shops', ng: { model: 'paymentMethod.preferred_enterprise_id' } }
|
||||
|
||||
#stripe-account-status{ ng: { show: "paymentMethod.preferred_enterprise_id" } }
|
||||
.alert-box.warning{ ng: { hide: "stripe_account.status" } }
|
||||
= t(".loading_account_information_msg")
|
||||
|
||||
.alert-box.error{ ng: { show: "stripe_account.status == 'request_failed'" } }
|
||||
= t(".request_failed_msg")
|
||||
|
||||
.alert-box.error{ ng: { show: "stripe_account.status == 'account_missing'" } }
|
||||
= t(".account_missing_msg")
|
||||
%a.button{ ng: { href: "{{current_enterprise_stripe_path()}}" }, target: 'blank' }
|
||||
= t(".connect_one")
|
||||
%i.icon-chevron-right
|
||||
|
||||
.alert-box.error{ ng: { show: "stripe_account.status == 'access_revoked'" } }
|
||||
= t(".access_revoked_msg")
|
||||
|
||||
.alert-box.ok{ ng: { show: "stripe_account.status == 'connected'" } }
|
||||
.status
|
||||
%strong= t(".status") + ":"
|
||||
= t(".connected")
|
||||
%i.icon-ok
|
||||
.account_id
|
||||
%strong= t(".account_id") + ":"
|
||||
{{ stripe_account.id }}
|
||||
.business_name
|
||||
%strong= t(".business_name") + ":"
|
||||
{{ stripe_account.business_name }}
|
||||
.charges_enabled
|
||||
%strong= t(".charges_enabled") + ":"
|
||||
{{ stripe_account.charges_enabled ? "say_yes" : "say_no" | t }}
|
||||
|
||||
@@ -657,6 +657,7 @@ en:
|
||||
producer_properties:
|
||||
index:
|
||||
title: Producer Properties
|
||||
|
||||
shared:
|
||||
user_guide_link:
|
||||
user_guide: User Guide
|
||||
@@ -2060,6 +2061,19 @@ Please follow the instructions there to make your enterprise visible on the Open
|
||||
one: "You have one active order cycle."
|
||||
other: "You have %{count} active order cycles."
|
||||
manage_order_cycles: "MANAGE ORDER CYCLES"
|
||||
payment_methods:
|
||||
stripe_connect:
|
||||
enterprise_select_placeholder: Choose...
|
||||
loading_account_information_msg: Loading account information from stripe, please wait...
|
||||
request_failed_msg: Sorry. Something went wrong when trying to verify account details with Stripe...
|
||||
account_missing_msg: No Stripe account exists for this enterprise.
|
||||
connect_one: Connect One
|
||||
access_revoked_msg: Access to this Stripe account has been revoked, please reconnect your account.
|
||||
status: Status
|
||||
connected: Connected
|
||||
account_id: Account ID
|
||||
business_name: Business Name
|
||||
charges_enabled: Charges Enabled
|
||||
products:
|
||||
new:
|
||||
title: 'New Product'
|
||||
|
||||
@@ -29,6 +29,41 @@ feature %q{
|
||||
payment_method = Spree::PaymentMethod.find_by_name('Cheque payment method')
|
||||
payment_method.distributors.should == [@distributors[0]]
|
||||
end
|
||||
|
||||
context "using stripe connect" do
|
||||
let(:user) { create(:user, enterprise_limit: 5) }
|
||||
let!(:connected_enterprise) { create(:distributor_enterprise, name: "Connected", owner: user) }
|
||||
let!(:revoked_account_enterprise) { create(:distributor_enterprise, name: "Revoked", owner: user) }
|
||||
let!(:missing_account_enterprise) { create(:distributor_enterprise, name: "Missing", owner: user) }
|
||||
let!(:valid_stripe_account) { create(:stripe_account, enterprise: connected_enterprise, stripe_user_id: "acc_connected123") }
|
||||
let!(:disconnected_stripe_account) { create(:stripe_account, enterprise: revoked_account_enterprise, stripe_user_id: "acc_revoked123") }
|
||||
let!(:stripe_account_mock) { { id: "acc_connected123", business_name: "My Org", charges_enabled: true } }
|
||||
|
||||
before do
|
||||
Stripe.api_key = "sk_test_12345"
|
||||
stub_request(:get, "https://api.stripe.com/v1/accounts/acc_connected123").to_return(body: JSON.generate(stripe_account_mock))
|
||||
stub_request(:get, "https://api.stripe.com/v1/accounts/acc_revoked123").to_return(status: 404)
|
||||
end
|
||||
|
||||
it "communicates the status of the stripe connection to the user" do
|
||||
login_as user
|
||||
visit spree.new_admin_payment_method_path
|
||||
|
||||
select2_select "Stripe", from: "payment_method_type"
|
||||
|
||||
select2_select "Missing", from: "payment_method_preferred_enterprise_id"
|
||||
expect(page).to have_selector "#stripe-account-status .alert-box.error", text: I18n.t("spree.admin.payment_methods.stripe_connect.account_missing_msg")
|
||||
|
||||
select2_select "Revoked", from: "payment_method_preferred_enterprise_id"
|
||||
expect(page).to have_selector "#stripe-account-status .alert-box.error", text: I18n.t("spree.admin.payment_methods.stripe_connect.access_revoked_msg")
|
||||
|
||||
select2_select "Connected", from: "payment_method_preferred_enterprise_id"
|
||||
expect(page).to have_selector "#stripe-account-status .status", text: "Status: Connected"
|
||||
expect(page).to have_selector "#stripe-account-status .account_id", text: "Account ID: acc_connected123"
|
||||
expect(page).to have_selector "#stripe-account-status .business_name", text: "Business Name: My Org"
|
||||
expect(page).to have_selector "#stripe-account-status .charges_enabled", text: "Charges Enabled: Yes"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
scenario "updating a payment method", js: true do
|
||||
|
||||
Reference in New Issue
Block a user