FF-208: Implement GetAccountBalance operation (#285)

* Implement GetAccountBalance

* Fix wrong currency_ref marshaling

* Get all events

* Test getting account balance

* Move getting account balance from handler, introduce relevant types

* Get wallet from machine in handler

* Remove redundant return type
This commit is contained in:
Toporkov Igor 2020-08-28 14:54:19 +03:00 committed by GitHub
parent 83208382e7
commit 8a942cc64e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 1 deletions

View File

@ -69,6 +69,15 @@ marshal(wallet, Wallet) ->
metadata = maybe_marshal(ctx, maps:get(metadata, Wallet, undefined))
};
marshal(wallet_account_balance, AccountBalance) ->
#account_AccountBalance{
id = marshal(id, maps:get(id, AccountBalance)),
currency = marshal(currency_ref, maps:get(currency, AccountBalance)),
expected_min = marshal(amount, maps:get(expected_min, AccountBalance)),
current = marshal(amount, maps:get(current, AccountBalance)),
expected_max = marshal(amount, maps:get(expected_max, AccountBalance))
};
marshal(ctx, Ctx) ->
marshal(context, Ctx);

View File

@ -61,4 +61,15 @@ handle_function_('GetContext', [ID], _Opts) ->
{ok, Response};
{error, notfound} ->
woody_error:raise(business, #fistful_WalletNotFound{})
end;
handle_function_('GetAccountBalance', [ID], _Opts) ->
case ff_wallet_machine:get(ID) of
{ok, Machine} ->
Wallet = ff_wallet_machine:wallet(Machine),
{ok, AccountBalance} = ff_wallet:get_account_balance(Wallet),
Response = ff_wallet_codec:marshal(wallet_account_balance, AccountBalance),
{ok, Response};
{error, notfound} ->
woody_error:raise(business, #fistful_WalletNotFound{})
end.

View File

@ -18,6 +18,7 @@
-export([create_error_currency_not_found/1]).
-export([create_error_party_blocked/1]).
-export([create_error_party_suspended/1]).
-export([get_account_balance/1]).
-type config() :: ct_helper:config().
-type test_case_name() :: ct_helper:test_case_name().
@ -38,7 +39,8 @@ groups() ->
create_error_identity_not_found,
create_error_currency_not_found,
create_error_party_blocked,
create_error_party_suspended
create_error_party_suspended,
get_account_balance
]}
].
@ -85,6 +87,7 @@ end_per_testcase(_Name, _C) ->
-spec create_error_currency_not_found(config()) -> test_return().
-spec create_error_party_blocked(config()) -> test_return().
-spec create_error_party_suspended(config()) -> test_return().
-spec get_account_balance(config()) -> test_return().
create_ok(C) ->
Party = create_party(C),
@ -147,6 +150,27 @@ create_error_party_suspended(C) ->
Result = call_service('Create', [Params, #{}]),
?assertMatch({exception, #fistful_PartyInaccessible{}}, Result).
get_account_balance(C) ->
Party = create_party(C),
Currency = <<"RUB">>,
ID = genlib:unique(),
ExternalID = genlib:unique(),
IdentityID = create_person_identity(Party, C),
Ctx = #{<<"TEST_NS">> => {obj, #{ {str, <<"KEY">>} => {b, true}}}},
Metadata = ff_entity_context_codec:marshal(#{<<"metadata">> => #{<<"some key">> => <<"some data">>}}),
Params = construct_wallet_params(ID, IdentityID, Currency, ExternalID, Metadata),
{ok, Wallet} = call_service('Create', [Params, Ctx]),
WalletID = Wallet#wlt_WalletState.id,
{ok, AccountBalance} = call_service('GetAccountBalance', [WalletID]),
CurrencyRef = AccountBalance#account_AccountBalance.currency,
Account = Wallet#wlt_WalletState.account,
AccountID = Account#account_Account.id,
?assertMatch(AccountID, AccountBalance#account_AccountBalance.id),
?assertMatch(Currency, CurrencyRef#'CurrencyRef'.symbolic_code),
?assertMatch(0, AccountBalance#account_AccountBalance.expected_min),
?assertMatch(0, AccountBalance#account_AccountBalance.current),
?assertMatch(0, AccountBalance#account_AccountBalance.expected_max).
%%-----------
%% Internal
%%-----------

View File

@ -20,6 +20,16 @@
accounter_account_id := accounter_account_id()
}.
-type amount() :: dmsl_domain_thrift:'Amount'().
-type account_balance() :: #{
id := id(),
currency := ff_currency:id(),
expected_min := amount(),
current := amount(),
expected_max := amount()
}.
-type event() ::
{created, account()}.
@ -32,6 +42,7 @@
-export_type([account/0]).
-export_type([event/0]).
-export_type([create_error/0]).
-export_type([account_balance/0]).
-export([id/1]).
-export([identity/1]).

View File

@ -70,6 +70,7 @@
-export([create/1]).
-export([is_accessible/1]).
-export([close/1]).
-export([get_account_balance/1]).
-export([apply_event/2]).
@ -204,3 +205,18 @@ check_accessible(Wallet) ->
blocked ->
{error, blocked}
end.
-spec get_account_balance(wallet_state()) ->
{ok, ff_account:account_balance()}.
get_account_balance(Wallet) ->
Account = ff_wallet:account(Wallet),
{ok, {Amounts, Currency}} = ff_transaction:balance(Account, ff_clock:latest_clock()),
AccountBalance = #{
id => ff_account:id(Account),
currency => Currency,
expected_min => ff_indef:expmin(Amounts),
current => ff_indef:current(Amounts),
expected_max => ff_indef:expmax(Amounts)
},
{ok, AccountBalance}.