Skip to content

Commit

Permalink
chore(balance, members): split members balance in two fields
Browse files Browse the repository at this point in the history
  • Loading branch information
Gladear committed Jan 15, 2025
1 parent 8e20026 commit 6283ec0
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 40 deletions.
27 changes: 9 additions & 18 deletions apps/app/lib/app/balance.ex
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ defmodule App.Balance do

Enum.map(members, fn
# If a member's balance has already been corrupted, it cannot be computed correctly
%{balance: {:error, _}} = member ->
%{balance_errors: [_ | _]} = member ->
member

%{id: ^member_id} = member ->
Expand Down Expand Up @@ -252,30 +252,18 @@ defmodule App.Balance do
end

# add reasons to the balance error reason list, or initialize the list
defp add_balance_errors(member, new_reasons) do
reasons =
case member.balance do
{:error, old_reasons} -> Enum.uniq_by(new_reasons ++ old_reasons, & &1.uniq_hash)
_ -> new_reasons
end
defp add_balance_errors(member, new_errors) do
errors = Enum.uniq_by(member.balance_errors ++ new_errors, & &1.uniq_hash)

%{member | balance: {:error, reasons}}
%{member | balance_errors: errors}
end

@doc """
Checks if the computed balance of the member has an error.
"""
@spec has_balance_error?(BookMember.t()) :: boolean()
def has_balance_error?(member) do
match?({:error, _reasons}, member.balance)
end

@spec member_balance_error_reasons(BookMember.t()) :: error_reasons() | nil
defp member_balance_error_reasons(member) do
case member.balance do
{:error, reasons} -> reasons
_ -> nil
end
member.balance_errors != []
end

@typedoc """
Expand All @@ -300,7 +288,10 @@ defmodule App.Balance do
"""
@spec transactions([BookMember.t()]) :: {:ok, [transaction()]} | {:error, error_reasons()}
def transactions(members) do
error_reasons = Enum.find_value(members, &member_balance_error_reasons/1)
error_reasons =
Enum.find_value(members, fn member ->
if has_balance_error?(member), do: member.balance_errors
end)

if error_reasons do
{:error, error_reasons}
Expand Down
9 changes: 5 additions & 4 deletions apps/app/lib/app/books/book_member.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ defmodule App.Books.BookMember do
import Ecto.Query

alias App.Accounts.User
alias App.Balance
alias App.Balance.BalanceConfig
alias App.Books.Book

Expand All @@ -26,7 +25,8 @@ defmodule App.Books.BookMember do
email: String.t() | nil,
balance_config_id: BalanceConfig.id() | nil,
balance_config: BalanceConfig.t() | Ecto.Association.NotLoaded.t() | nil,
balance: Money.t() | {:error, Balance.error_reasons()} | nil,
balance: Money.t() | nil,
balance_errors: [String.t()],
inserted_at: NaiveDateTime.t() | nil,
updated_at: NaiveDateTime.t() | nil
}
Expand All @@ -48,9 +48,10 @@ defmodule App.Books.BookMember do

# the current balance configuration for this member
belongs_to :balance_config, BalanceConfig
# Filled by the `Balance` context. Maybe be set to `{:error, reasons}` if the
# balance cannot be computed.
# Filled by the `Balance` context. If the `:balance_errors` is set, the balance
# was not computed correctly.
field :balance, Money.Ecto.Composite.Type, virtual: true
field :balance_errors, {:array, :string}, virtual: true, default: []

timestamps()
end
Expand Down
39 changes: 21 additions & 18 deletions apps/app/test/app/balance_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -298,23 +298,21 @@ defmodule App.BalanceTest do
member1_id = member1.id
expected_hash = "revenues_missing_#{member1_id}"

assert {:error,
[
%{
kind: :revenues_missing,
uniq_hash: ^expected_hash,
extra: %{member: %{id: ^member1_id}}
}
]} = member1.balance

assert {:error,
[
%{
kind: :revenues_missing,
uniq_hash: ^expected_hash,
extra: %{member: %{id: ^member1_id}}
}
]} = member2.balance
assert [
%{
kind: :revenues_missing,
uniq_hash: ^expected_hash,
extra: %{member: %{id: ^member1_id}}
}
] = member1.balance_errors

assert [
%{
kind: :revenues_missing,
uniq_hash: ^expected_hash,
extra: %{member: %{id: ^member1_id}}
}
] = member2.balance_errors

assert Money.equal?(member3.balance, Money.new!(:EUR, -20))
end
Expand Down Expand Up @@ -425,7 +423,12 @@ defmodule App.BalanceTest do

test "returns :error when the balance of a member is corrupted", %{book: book} do
member1 = book_member_fixture(book, balance: Money.new!(:EUR, 10))
member2 = book_member_fixture(book, balance: {:error, ["could not compute balance"]})

member2 =
book_member_fixture(book,
balance: Money.new!(:EUR, 10),
balance_errors: ["could not compute balance"]
)

assert Balance.transactions([member1, member2]) == {:error, ["could not compute balance"]}
end
Expand Down

0 comments on commit 6283ec0

Please sign in to comment.