Skip to content

Commit

Permalink
deposit flow
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiobarboza7 committed Feb 28, 2021
1 parent 7aefa05 commit 9641d01
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 4 deletions.
4 changes: 4 additions & 0 deletions lib/rocketpay.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
defmodule Rocketpay do
alias Rocketpay.Users.Create, as: UserCreate

alias Rocketpay.Accouns.Deposit

defdelegate create_user(params), to: UserCreate, as: :call

defdelegate deposit(params), to: Deposit, as: :call
end
45 changes: 45 additions & 0 deletions lib/rocketpay/accounts/deposit.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
defmodule Rocketpay.Accounts.Deposit do
alias Ecto.Multi

alias Rocketpay.{Account, Repo}

def call(%{"id" => id, "value" => value}) do
Multi.new()
|> Multi.run(:account, fn repo, _changes -> get_account(repo, id) end)
|> Multi.run(:update_balance, fn repo, %{account: account} ->
update_balance(repo, account, value)
end)
end

defp get_account(repo, id) do
case repo.get(Account, id) do
nil -> {:error, "Account, not found!"}
account -> {:ok, account}
end
end

defp update_balance(repo, account, value) do
account
|> sum_values(value)
|> update_account(repo)
end

defp sum_values(%Account{balance: balance}, value) do
value
|>Decimal.cast()
|> handle_cast(balance)
end

defp handle_cast({:ok, value}, balance), do: Decimal.add(value, balance)
defp handle_cast(:error, _balanace), do: {:error, "Invalid deposit value!"}

defp update_account({:error, _reason} = error, _repo), do: error

defp update_account(value, repo) do
params = %{balance: value}

params
|> Account.changeset()
|> repo.update()
end
end
16 changes: 15 additions & 1 deletion lib/rocketpay/users/create.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Rocketpay.Users.Create do
alias Rocketpay.{User, Account}
alias Rocketpay.{User, Repo, Account}
alias Ecto.Multi

def call(params) do
Expand All @@ -8,6 +8,10 @@ defmodule Rocketpay.Users.Create do
|> Multi.run(:create_account, fn repo, %{create_user: user} ->
insert_account(repo, user)
end)
|> Multi.run(:preload_data, fn repo, %{create_user: user} ->
preload_data(repo, user)
end)
|> run_transaction()
end

defp insert_account(repo, user) do
Expand All @@ -20,6 +24,16 @@ defmodule Rocketpay.Users.Create do
params = %{user_id: user_id, balance: "0.00"}

Account.changeset(params)
end

defp preload_data(repo, user) do
{:ok, repo.preload(user, :account)}
end

defp run_transaction(multi) do
case Repo.transaction(multi) do
{:error, _operation, reason, _changes} -> {:error, reason}
{:ok, %{preload_data: user}} -> {:ok, user}
end
end
end
19 changes: 19 additions & 0 deletions lib/rocketpay_web/controllers/accounts_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule RocketpayWeb.AccountsController do
use RocketpayWeb, :controller

alias Rocketpay.Account

action_fallback RocketpayWeb.FallbackController

def deposit(conn, params) do
with {:ok, %Account{} = account} <- Rocketpay.deposit(params) do
conn
|> put_status(:ok)
|> render("update.json", account: account)
end
end

def withdraw(conn, params) do

end
end
3 changes: 3 additions & 0 deletions lib/rocketpay_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ defmodule RocketpayWeb.Router do

get "/:filename", WelcomeController, :index
post "/users", UsersController, :create

post "/accounts/:id/deposit", AccountsController, :deposit
post "/accounts/:id/withdraw", AccountsController, :withdraw
end

# Enables LiveDashboard only for development
Expand Down
17 changes: 14 additions & 3 deletions lib/rocketpay_web/views/users_view.ex
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
defmodule RocketpayWeb.UsersView do
alias Rocketpay.User
alias Rocketpay.{Account, User}

def render("create.json", %{user: %User{id: id, name: name, nickname: nickname}}) do
def render("create.json", %{
user: %User{
account: %Account{id: account_id, balance: balance},
id: id,
name: name,
nickname: nickname
}
}) do
%{
message: "User created",
user: %{
id: id,
name: name,
nickname: nickname
nickname: nickname,
account: %{
id: account_id,
balance: balance
}
}
}
end
Expand Down

0 comments on commit 9641d01

Please sign in to comment.