Skip to content

Commit

Permalink
Add connect customer updates
Browse files Browse the repository at this point in the history
  • Loading branch information
begedin committed Dec 5, 2016
1 parent ee1b803 commit 3beb43a
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 28 deletions.
46 changes: 41 additions & 5 deletions lib/code_corps/services/user_service.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ defmodule CodeCorps.Services.UserService do
"""

alias CodeCorps.{Repo, StripePlatformCustomer, User}
alias CodeCorps.StripeService.StripePlatformCustomerService
alias CodeCorps.{Repo, StripeConnectCustomer, StripePlatformCustomer, User}
alias CodeCorps.StripeService.{StripeConnectCustomerService,StripePlatformCustomerService}
alias Ecto.Changeset
alias Ecto.Multi

Expand All @@ -30,17 +30,32 @@ defmodule CodeCorps.Services.UserService do
Multi.new
|> Multi.update(:update_user, changeset)
|> Multi.run(:update_platform_customer, &update_platform_customer/1)
|> Multi.run(:update_connect_customers, &update_connect_customers/1)

case Repo.transaction(multi) do
{:ok, %{update_user: user, update_platform_customer: _}} ->
{:ok, user}
{:ok, %{
update_user: user,
update_platform_customer: update_platform_customer_result,
update_connect_customers: update_connect_customers_results
}} ->
{:ok, user, update_platform_customer_result, update_connect_customers_results}
{:error, :update_user, %Ecto.Changeset{} = changeset, %{}} ->
{:error, changeset}
{:error, _failed_operation, _failed_value, _changes_so_far} ->
{:error, :unhandled}
other ->
IO.inspect(other, pretty: true)
end
end

defp do_update(%Changeset{} = changeset) do
with {:ok, user} <- Repo.update(changeset) do
{:ok, user, :nothing_to_update, :nothing_to_update}
else
{:error, changeset} -> {:error, changeset}
_ -> {:error, :unhandled}
end
end
defp do_update(%Changeset{} = changeset), do: Repo.update(changeset)

defp update_platform_customer(%{update_user: %User{id: user_id, email: email}}) do
StripePlatformCustomer
Expand All @@ -52,4 +67,25 @@ defmodule CodeCorps.Services.UserService do
defp do_update_platform_customer(%StripePlatformCustomer{} = stripe_platform_customer, attributes) do
StripePlatformCustomerService.update(stripe_platform_customer, attributes)
end

defp update_connect_customers(%{update_platform_customer: :nothing_to_update}), do: {:ok, :nothing_to_update}

defp update_connect_customers(%{update_platform_customer: %StripePlatformCustomer{email: email} = stripe_platform_customer}) do
case do_update_connect_customers(stripe_platform_customer, %{email: email}) do
[_h | _t] = results -> {:ok, results}
[] -> {:ok, :nothing_to_update}
end
end

defp do_update_connect_customers(stripe_platform_customer, attributes) do
stripe_platform_customer
|> Repo.preload([stripe_connect_customers: :stripe_connect_account])
|> Map.get(:stripe_connect_customers)
|> Enum.map(&do_update_connect_customer(&1, attributes))
end

defp do_update_connect_customer(%StripeConnectCustomer{} = stripe_connect_customer, attributes) do
stripe_connect_customer
|> StripeConnectCustomerService.update(attributes)
end
end
4 changes: 4 additions & 0 deletions lib/code_corps/stripe_service/stripe_connect_customer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ defmodule CodeCorps.StripeService.StripeConnectCustomerService do
end
end

def update(%StripeConnectCustomer{stripe_connect_account: connect_account} = connect_customer, attributes) do
@api.Customer.update(connect_customer.id_from_stripe, attributes, connect_account: connect_account.id_from_stripe)
end

defp create(%StripePlatformCustomer{} = platform_customer, %StripeConnectAccount{} = connect_account) do
attributes = platform_customer |> create_non_stripe_attributes(connect_account)
stripe_attributes = create_stripe_attributes(platform_customer)
Expand Down
43 changes: 37 additions & 6 deletions test/lib/code_corps/services/user_service_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ defmodule CodeCorps.Services.UserServiceTest do
describe "update/1" do
test "it just updates the user if there is nothing associated to update" do
user = insert(:user, email: "mail@mail.com", first_name: "Joe")
{:ok, user} = UserService.update(user, %{email: "changed@mail.com"})

{:ok, user, :nothing_to_update, :nothing_to_update}
= UserService.update(user, %{email: "changed@mail.com"})

assert user.email == "changed@mail.com"
assert user.first_name == "Joe"
Expand All @@ -26,7 +28,8 @@ defmodule CodeCorps.Services.UserServiceTest do
user = insert(:user, email: "mail@mail.com")
stripe_platform_customer = insert(:stripe_platform_customer, email: "mail@mail.com", user: user)

{:ok, user} = UserService.update(user, %{first_name: "Mark"})
{:ok, user, :nothing_to_update, :nothing_to_update}
= UserService.update(user, %{first_name: "Mark"})

assert user.first_name == "Mark"
assert user.email == "mail@mail.com"
Expand All @@ -38,15 +41,43 @@ defmodule CodeCorps.Services.UserServiceTest do

test "it also updates the associated platform customer if there is one" do
user = insert(:user, email: "mail@mail.com")
stripe_platform_customer = insert(:stripe_platform_customer, user: user)
platform_customer = insert(:stripe_platform_customer, user: user)

{:ok, user} = UserService.update(user, %{email: "changed@mail.com"})
{:ok, user, %StripePlatformCustomer{}, :nothing_to_update}
= UserService.update(user, %{email: "changed@mail.com"})

assert user.email == "changed@mail.com"

stripe_platform_customer = Repo.get(StripePlatformCustomer, stripe_platform_customer.id)
platform_customer = Repo.get(StripePlatformCustomer, platform_customer.id)

assert platform_customer.email == "changed@mail.com"
end

test "it also updates the associated connect customers if there are any" do
user = insert(:user, email: "mail@mail.com")

platform_customer = %{id_from_stripe: platform_customer_id}
= insert(:stripe_platform_customer, user: user)

[connect_customer_1, connect_customer_2] =
insert_pair(:stripe_connect_customer, stripe_platform_customer: platform_customer)

{:ok, user, %StripePlatformCustomer{}, connect_updates} = UserService.update(user, %{email: "changed@mail.com"})

assert user.email == "changed@mail.com"

platform_customer = Repo.get_by(StripePlatformCustomer, id_from_stripe: platform_customer_id)
assert platform_customer.email == "changed@mail.com"

[
{:ok, %Stripe.Customer{} = stripe_record_1},
{:ok, %Stripe.Customer{} = stripe_record_2}
] = connect_updates

assert stripe_platform_customer.email == "changed@mail.com"
assert stripe_record_1.id == connect_customer_1.id_from_stripe
assert stripe_record_1.email == "changed@mail.com"
assert stripe_record_2.id == connect_customer_2.id_from_stripe
assert stripe_record_2.email == "changed@mail.com"
end
end
end
3 changes: 2 additions & 1 deletion test/support/factories.ex
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ defmodule CodeCorps.Factories do

def stripe_connect_customer_factory do
%CodeCorps.StripeConnectCustomer{
id_from_stripe: sequence(:id_from_stripe, &"stripe_id_#{&1}")
id_from_stripe: sequence(:id_from_stripe, &"stripe_id_#{&1}"),
stripe_connect_account: build(:stripe_connect_account)
}
end

Expand Down
32 changes: 16 additions & 16 deletions web/controllers/user_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,26 @@ defmodule CodeCorps.UserController do
end

def handle_create(conn, attributes) do
%User{}
|> User.registration_changeset(attributes)
|> Repo.insert
|> login(conn)
|> track_signup
with {:ok, user} <- %User{} |> User.registration_changeset(attributes) |> Repo.insert,
conn <- login(user, conn)
do
CodeCorps.Analytics.Segment.track({:ok, user}, :signed_up, conn)
else
{:error, changeset} -> changeset
_ -> conn
end
end

defp login({:error, changeset}, conn), do: {:error, changeset, conn}
defp login({:ok, model}, conn) do
{:ok, model, conn |> Plug.Conn.assign(:current_user, model)}
end

defp track_signup({status, model_or_changeset, conn}) do
CodeCorps.Analytics.Segment.track({status, model_or_changeset}, :signed_up, conn)
end
defp login(user, conn), do: Plug.Conn.assign(conn, :current_user, user)

def handle_update(conn, record, attributes) do
record
|>UserService.update(attributes)
|> CodeCorps.Analytics.Segment.track(:updated_profile, conn)
with {:ok, user, _platform_customer_updates, _connect_customer_updates} <- UserService.update(record, attributes)
do
{:ok, user} |> CodeCorps.Analytics.Segment.track(:updated_profile, conn)
else
{:error, changeset} -> changeset
{:error, :unhandled} -> conn
end
end

def email_available(conn, %{"email" => email}) do
Expand Down
2 changes: 2 additions & 0 deletions web/models/stripe_platform_customer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ defmodule CodeCorps.StripePlatformCustomer do

belongs_to :user, CodeCorps.User

has_many :stripe_connect_customers, CodeCorps.StripeConnectCustomer

timestamps()
end

Expand Down

0 comments on commit 3beb43a

Please sign in to comment.