Skip to content

Commit 0d7ca83

Browse files
committed
clean up module
1 parent f49b9a6 commit 0d7ca83

File tree

1 file changed

+67
-41
lines changed

1 file changed

+67
-41
lines changed
Lines changed: 67 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
defmodule Algora.Payments.Jobs.ExecutePendingTransfers do
22
@moduledoc false
3-
use Oban.Worker, queue: :transfers
3+
use Oban.Worker,
4+
queue: :transfers,
5+
max_attempts: 1
46

57
import Ecto.Changeset
68
import Ecto.Query
@@ -15,6 +17,17 @@ defmodule Algora.Payments.Jobs.ExecutePendingTransfers do
1517

1618
@impl Oban.Worker
1719
def perform(%Oban.Job{args: %{user_id: user_id, group_id: group_id}}) do
20+
pending_amount = get_pending_amount(user_id)
21+
22+
with {:ok, account} <- Repo.fetch_by(Account, user_id: user_id, provider: :stripe, payouts_enabled: true),
23+
true <- Money.positive?(pending_amount) do
24+
initialize_and_execute_transfer(user_id, group_id, pending_amount, account)
25+
else
26+
_ -> :ok
27+
end
28+
end
29+
30+
defp get_pending_amount(user_id) do
1831
total_credits =
1932
Repo.one(
2033
from(t in Transaction,
@@ -35,50 +48,63 @@ defmodule Algora.Payments.Jobs.ExecutePendingTransfers do
3548
)
3649
) || Money.zero(:USD)
3750

38-
pending_amount = Money.sub!(total_credits, total_transfers)
51+
Money.sub!(total_credits, total_transfers)
52+
end
3953

40-
with {:ok, account} <- Repo.fetch_by(Account, user_id: user_id, provider: :stripe, payouts_enabled: true),
41-
true <- Money.positive?(pending_amount) do
42-
{:ok, transaction} =
43-
%Transaction{}
44-
|> change(%{
45-
provider: "stripe",
46-
type: :credit,
47-
status: :initialized,
48-
user_id: user_id,
49-
gross_amount: pending_amount,
50-
net_amount: pending_amount,
51-
total_fee: Money.zero(:USD),
52-
group_id: group_id
53-
})
54-
|> Algora.Validations.validate_positive(:gross_amount)
55-
|> Algora.Validations.validate_positive(:net_amount)
56-
|> foreign_key_constraint(:user_id)
57-
|> Repo.insert()
54+
defp initialize_and_execute_transfer(user_id, group_id, pending_amount, account) do
55+
with {:ok, transaction} <- initialize_transfer(user_id, group_id, pending_amount),
56+
{:ok, transfer} <- execute_transfer(transaction, account) do
57+
{:ok, transfer}
58+
else
59+
error ->
60+
Logger.error("Failed to execute transfer: #{inspect(error)}")
61+
error
62+
end
63+
end
5864

59-
Repo.transact(fn ->
60-
# TODO: set other params
61-
# TODO: provide idempotency key
62-
{:ok, transfer} =
63-
Stripe.Transfer.create(%{
64-
amount: MoneyUtils.to_minor_units(pending_amount),
65-
currency: to_string(pending_amount.currency),
66-
destination: account.stripe_account_id
67-
})
65+
defp initialize_transfer(user_id, group_id, pending_amount) do
66+
%Transaction{}
67+
|> change(%{
68+
provider: "stripe",
69+
type: :credit,
70+
status: :initialized,
71+
user_id: user_id,
72+
gross_amount: pending_amount,
73+
net_amount: pending_amount,
74+
total_fee: Money.zero(:USD),
75+
group_id: group_id
76+
})
77+
|> Algora.Validations.validate_positive(:gross_amount)
78+
|> Algora.Validations.validate_positive(:net_amount)
79+
|> foreign_key_constraint(:user_id)
80+
|> Repo.insert()
81+
end
6882

69-
{:ok, transaction} =
70-
transaction
71-
|> change(%{
72-
status: if(transfer.status == :succeeded, do: :succeeded, else: :failed),
73-
provider_id: transfer.id,
74-
provider_meta: Util.normalize_struct(transfer)
75-
})
76-
|> Repo.update()
83+
defp execute_transfer(transaction, account) do
84+
# TODO: set other params
85+
# TODO: provide idempotency key
86+
case Stripe.Transfer.create(%{
87+
amount: MoneyUtils.to_minor_units(transaction.net_amount),
88+
currency: to_string(transaction.net_amount.currency),
89+
destination: account.stripe_account_id
90+
}) do
91+
{:ok, transfer} ->
92+
# it's fine if this fails since we'll receive a webhook
93+
_result = try_update_transaction(transaction, transfer)
94+
{:ok, transfer}
7795

78-
{:ok, transaction}
79-
end)
80-
else
81-
_ -> :ok
96+
{:error, error} ->
97+
{:error, error}
8298
end
8399
end
100+
101+
defp try_update_transaction(transaction, transfer) do
102+
transaction
103+
|> change(%{
104+
status: if(transfer.status == :succeeded, do: :succeeded, else: :failed),
105+
provider_id: transfer.id,
106+
provider_meta: Util.normalize_struct(transfer)
107+
})
108+
|> Repo.update()
109+
end
84110
end

0 commit comments

Comments
 (0)