parent
b231ac62fc
commit
1d7f22d123
@ -0,0 +1,21 @@ |
|||||||
|
.address { |
||||||
|
&__header { @extend %section-header; } |
||||||
|
&__heading { @extend %section-header__heading; } |
||||||
|
&__subheading { @extend %section-header__subheading; } |
||||||
|
&__attributes { |
||||||
|
@extend %paper; |
||||||
|
@include explorer-typography("body1"); |
||||||
|
padding: explorer-size(-1) explorer-size(1); |
||||||
|
} |
||||||
|
&__item { @extend %section-list__item; } |
||||||
|
&__item-key { @extend %section-list__item-key; } |
||||||
|
&__item-value { @extend %section-list__item-value; } |
||||||
|
} |
||||||
|
|
||||||
|
@media (min-width: $explorer-breakpoint-lg) { |
||||||
|
.address { |
||||||
|
&__container { |
||||||
|
max-width: explorer-size(6); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
defmodule Explorer.AddressForm do |
||||||
|
@moduledoc false |
||||||
|
alias Explorer.Address |
||||||
|
alias Explorer.FromAddress |
||||||
|
alias Explorer.Repo |
||||||
|
alias Explorer.ToAddress |
||||||
|
alias Explorer.Transaction |
||||||
|
import Ecto.Query |
||||||
|
|
||||||
|
def build(address) do |
||||||
|
address |
||||||
|
|> Map.merge(%{ |
||||||
|
balance: address |> calculate_balance, |
||||||
|
}) |
||||||
|
end |
||||||
|
|
||||||
|
def calculate_balance(address) do |
||||||
|
Decimal.sub(credits(address), debits(address)) |
||||||
|
end |
||||||
|
|
||||||
|
def credits(address) do |
||||||
|
query = from transaction in Transaction, |
||||||
|
join: to_address in ToAddress, |
||||||
|
where: to_address.transaction_id == transaction.id, |
||||||
|
join: address in Address, |
||||||
|
where: to_address.address_id == address.id, |
||||||
|
select: sum(transaction.value), |
||||||
|
where: address.id == ^address.id |
||||||
|
Repo.one(query) || Decimal.new(0) |
||||||
|
end |
||||||
|
|
||||||
|
def debits(address) do |
||||||
|
query = from transaction in Transaction, |
||||||
|
join: from_address in FromAddress, |
||||||
|
where: from_address.transaction_id == transaction.id, |
||||||
|
join: address in Address, |
||||||
|
where: from_address.address_id == address.id, |
||||||
|
select: sum(transaction.value), |
||||||
|
where: address.id == ^address.id |
||||||
|
Repo.one(query) || Decimal.new(0) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,72 @@ |
|||||||
|
defmodule Explorer.AddressFormTest do |
||||||
|
use Explorer.DataCase |
||||||
|
alias Explorer.AddressForm |
||||||
|
|
||||||
|
describe "build/1" do |
||||||
|
test "that it has a balance" do |
||||||
|
address = insert(:address, %{hash: "bert"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{to: "bert", from: "ernie"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{to: "bert", from: "kermit"}) |
||||||
|
|
||||||
|
assert AddressForm.build(address).balance == Decimal.new(10) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
describe "calculate_balance/1" do |
||||||
|
test "when there are more credits than debits it returns a positive value" do |
||||||
|
address = insert(:address, %{hash: "bert"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{to: "bert", from: "ernie"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{to: "bert", from: "kermit"}) |
||||||
|
|
||||||
|
assert AddressForm.calculate_balance(address) == Decimal.new(10) |
||||||
|
end |
||||||
|
|
||||||
|
test "when credits and debits are equal it returns zero" do |
||||||
|
address = insert(:address, %{hash: "bert"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{to: "bert", from: "ernie"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{to: "ernie", from: "bert"}) |
||||||
|
|
||||||
|
assert AddressForm.calculate_balance(address) == Decimal.new(0) |
||||||
|
end |
||||||
|
|
||||||
|
test "when there are more debits than credits it returns a negative value" do |
||||||
|
address = insert(:address, %{hash: "bert"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{to: "ernie", from: "bert"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{to: "ernie", from: "bert"}) |
||||||
|
|
||||||
|
assert AddressForm.calculate_balance(address) == Decimal.new(-10) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
describe "credits/1" do |
||||||
|
test "when there are no transactions" do |
||||||
|
address = insert(:address, %{hash: "bert"}) |
||||||
|
assert AddressForm.credits(address) == Decimal.new(0) |
||||||
|
end |
||||||
|
|
||||||
|
test "that it calculates credits" do |
||||||
|
address = insert(:address, %{hash: "bert"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{from: "ernie", to: "bert"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{from: "bert", to: "kermit"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{from: "janice", to: "bert"}) |
||||||
|
|
||||||
|
assert AddressForm.credits(address) == Decimal.new(10) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
describe "debits/1" do |
||||||
|
test "when there are no transactions" do |
||||||
|
address = insert(:address, %{hash: "bert"}) |
||||||
|
assert AddressForm.debits(address) == Decimal.new(0) |
||||||
|
end |
||||||
|
|
||||||
|
test "that it calculates debits" do |
||||||
|
address = insert(:address, %{hash: "ernie"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{from: "ernie", to: "bert"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{from: "ernie", to: "kermit"}) |
||||||
|
insert(:transaction, value: 5) |> with_addresses(%{from: "janice", to: "ernie"}) |
||||||
|
|
||||||
|
assert AddressForm.debits(address) == Decimal.new(10) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
Loading…
Reference in new issue