Skip to content

Commit 19e3d48

Browse files
committed
display transactions on contract page
1 parent c79abba commit 19e3d48

File tree

2 files changed

+118
-10
lines changed

2 files changed

+118
-10
lines changed

lib/algora/bounties/bounties.ex

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,7 @@ defmodule Algora.Bounties do
868868
initialize_charge(%{
869869
id: Nanoid.generate(),
870870
user_id: owner.id,
871+
bounty_id: opts[:bounty_id],
871872
gross_amount: gross_amount,
872873
net_amount: amount,
873874
total_fee: Money.sub!(gross_amount, amount),
@@ -967,23 +968,26 @@ defmodule Algora.Bounties do
967968
end)
968969
end
969970

970-
defp initialize_charge(%{
971-
id: id,
972-
user_id: user_id,
973-
gross_amount: gross_amount,
974-
net_amount: net_amount,
975-
total_fee: total_fee,
976-
line_items: line_items,
977-
group_id: group_id,
978-
idempotency_key: idempotency_key
979-
}) do
971+
defp initialize_charge(
972+
%{
973+
id: id,
974+
user_id: user_id,
975+
gross_amount: gross_amount,
976+
net_amount: net_amount,
977+
total_fee: total_fee,
978+
line_items: line_items,
979+
group_id: group_id,
980+
idempotency_key: idempotency_key
981+
} = params
982+
) do
980983
%Transaction{}
981984
|> change(%{
982985
id: id,
983986
provider: "stripe",
984987
type: :charge,
985988
status: :initialized,
986989
user_id: user_id,
990+
bounty_id: params[:bounty_id],
987991
gross_amount: gross_amount,
988992
net_amount: net_amount,
989993
total_fee: total_fee,

lib/algora_web/live/contract_live.ex

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ defmodule AlgoraWeb.ContractLive do
1111
alias Algora.Bounties.LineItem
1212
alias Algora.Chat
1313
alias Algora.Organizations.Member
14+
alias Algora.Payments
1415
alias Algora.Repo
1516
alias Algora.Util
1617
alias Algora.Workspace
@@ -47,6 +48,8 @@ defmodule AlgoraWeb.ContractLive do
4748
|> Repo.get!(bounty_id)
4849
|> Repo.preload([:owner, :creator, :transactions, ticket: [repository: [:user]]])
4950

51+
timezone = if(params = get_connect_params(socket), do: params["timezone"])
52+
5053
{host, ticket_ref} =
5154
if bounty.ticket.repository do
5255
{bounty.ticket.repository.user,
@@ -63,6 +66,7 @@ defmodule AlgoraWeb.ContractLive do
6366
|> assign(:bounty, bounty)
6467
|> assign(:ticket_ref, ticket_ref)
6568
|> assign(:host, host)
69+
|> assign(:timezone, timezone)
6670
|> on_mount(bounty)
6771
end
6872

@@ -140,6 +144,7 @@ defmodule AlgoraWeb.ContractLive do
140144
|> assign(:participants, participants)
141145
|> assign(:reward_form, to_form(reward_changeset))
142146
|> assign_contractor(bounty.shared_with)
147+
|> assign_transactions()
143148
|> assign_line_items()}
144149
end
145150

@@ -302,6 +307,51 @@ defmodule AlgoraWeb.ContractLive do
302307
</div>
303308
</.card_content>
304309
</.card>
310+
<.card :if={length(@transactions) > 0}>
311+
<.card_content>
312+
<div class="-mx-6 overflow-x-auto">
313+
<div class="inline-block min-w-full py-2 align-middle">
314+
<table class="min-w-full divide-y divide-border">
315+
<thead>
316+
<tr>
317+
<th scope="col" class="px-6 py-3.5 text-left text-sm font-semibold">Date</th>
318+
<th scope="col" class="px-6 py-3.5 text-left text-sm font-semibold">
319+
Description
320+
</th>
321+
<th scope="col" class="px-6 py-3.5 text-right text-sm font-semibold">
322+
Amount
323+
</th>
324+
</tr>
325+
</thead>
326+
<tbody class="divide-y divide-border">
327+
<%= for transaction <- @transactions do %>
328+
<tr class="hover:bg-muted/50">
329+
<td class="whitespace-nowrap px-6 py-4 text-sm">
330+
{Util.timestamp(transaction.inserted_at, @timezone)}
331+
</td>
332+
<td class="whitespace-nowrap px-6 py-4 text-sm">
333+
{description(transaction)}
334+
</td>
335+
<td class="font-display whitespace-nowrap px-6 py-4 text-right font-medium tabular-nums">
336+
<%= case transaction_direction(transaction.type) do %>
337+
<% :plus -> %>
338+
<span class="text-emerald-400">
339+
{Money.to_string!(transaction.net_amount)}
340+
</span>
341+
<% :minus -> %>
342+
<span class="text-foreground">
343+
{Money.to_string!(transaction.net_amount)}
344+
</span>
345+
<% end %>
346+
</td>
347+
</tr>
348+
<% end %>
349+
</tbody>
350+
</table>
351+
</div>
352+
</div>
353+
</.card_content>
354+
</.card>
305355
</div>
306356
</.scroll_area>
307357
@@ -556,4 +606,58 @@ defmodule AlgoraWeb.ContractLive do
556606

557607
assign(socket, :contractor, contractor)
558608
end
609+
610+
defp assign_transactions(socket) do
611+
transactions =
612+
Payments.list_transactions(
613+
user_id: socket.assigns.bounty.owner.id,
614+
status: :succeeded,
615+
bounty_id: socket.assigns.bounty.id
616+
)
617+
618+
balance = calculate_balance(transactions)
619+
volume = calculate_volume(transactions)
620+
621+
socket
622+
|> assign(:transactions, transactions)
623+
|> assign(:total_balance, balance)
624+
|> assign(:total_volume, volume)
625+
end
626+
627+
defp calculate_balance(transactions) do
628+
Enum.reduce(transactions, Money.new!(0, :USD), fn transaction, acc ->
629+
case transaction.type do
630+
type when type in [:charge, :deposit, :credit] ->
631+
Money.add!(acc, transaction.net_amount)
632+
633+
type when type in [:debit, :withdrawal, :transfer] ->
634+
Money.sub!(acc, transaction.net_amount)
635+
636+
_ ->
637+
acc
638+
end
639+
end)
640+
end
641+
642+
defp calculate_volume(transactions) do
643+
Enum.reduce(transactions, Money.new!(0, :USD), fn transaction, acc ->
644+
case transaction.type do
645+
type when type in [:charge, :credit] -> Money.add!(acc, transaction.net_amount)
646+
_ -> acc
647+
end
648+
end)
649+
end
650+
651+
defp transaction_direction(type) do
652+
case type do
653+
t when t in [:charge, :credit, :deposit] -> :minus
654+
t when t in [:debit, :withdrawal, :transfer] -> :plus
655+
end
656+
end
657+
658+
defp description(%{type: :charge}), do: "Escrowed"
659+
660+
defp description(%{type: :debit}), do: "Released"
661+
662+
defp description(%{type: _type}), do: nil
559663
end

0 commit comments

Comments
 (0)