HG-452: Implement ComputeGlobals and ComputePaymentRoutingRuleset (#466)

* HG-452: Update Varset

* HG-452: Add ComputeGlobals and ComputePaymentRoutingRuleset implementation

* HG-452: Fix tests

* HG-452: Fix test

* HG-452: Fix dominant config in party test

* HG-452: Fix lint

* HG-452: Fix xref and tests

* Update apps/party_management/src/pm_party_handler.erl

Co-authored-by: Andrey Fadeev <me@ciiol.net>

* HG-452: Review fix

* HG-452: Update damsel

* Update apps/party_management/test/pm_party_tests_SUITE.erl

Co-authored-by: Andrey Fadeev <me@ciiol.net>

* HG-452: Add WRONG_DMT_OBJ_ID macro to pm tests

* HG-452: Add tests

* HG-452: Fix order

Co-authored-by: Andrey Fadeev <me@ciiol.net>
This commit is contained in:
ndiezel0 2020-08-07 16:02:02 +03:00 committed by GitHub
parent 642a9b47fb
commit 118ff48698
8 changed files with 347 additions and 21 deletions

View File

@ -0,0 +1,17 @@
-module(pm_globals).
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
%% API
-export([reduce_globals/3]).
-type globals() :: dmsl_domain_thrift:'Globals'().
-type varset() :: pm_selector:varset().
-type domain_revision() :: pm_domain:revision().
-spec reduce_globals(globals(), varset(), domain_revision()) -> globals().
reduce_globals(Globals, VS, DomainRevision) ->
Globals#domain_Globals{
external_account_set = pm_selector:reduce(Globals#domain_Globals.external_account_set, VS, DomainRevision)
}.

View File

@ -172,6 +172,24 @@ handle_function_('ComputeProviderTerminalTerms', Args, _Opts) ->
VS = prepare_varset(Varset),
pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision);
%% Globals
handle_function_('ComputeGlobals', Args, _Opts) ->
[UserInfo, GlobalsRef, DomainRevision, Varset] = Args,
ok = assume_user_identity(UserInfo),
Globals = get_globals(GlobalsRef, DomainRevision),
VS = prepare_varset(Varset),
pm_globals:reduce_globals(Globals, VS, DomainRevision);
%% RuleSets
handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) ->
[UserInfo, RuleSetRef, DomainRevision, Varset] = Args,
ok = assume_user_identity(UserInfo),
RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision),
VS = prepare_varset(Varset),
pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision);
%% PartyMeta
handle_function_('GetMeta', [UserInfo, PartyID], _Opts) ->
@ -193,13 +211,13 @@ handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when
handle_function_(
'ComputePaymentInstitutionTerms',
[UserInfo, PartyID, PaymentInstitutionRef, Varset],
[UserInfo, PaymentInstitutionRef, Varset],
_Opts
) ->
ok = set_meta_and_check_access(UserInfo, PartyID),
ok = assume_user_identity(UserInfo),
Revision = pm_domain:head(),
PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision),
VS = prepare_varset(PartyID, Varset),
VS = prepare_varset(Varset),
ContractTemplate = get_default_contract_template(PaymentInstitution, VS, Revision),
Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision),
pm_party:reduce_terms(Terms, VS, Revision);
@ -323,6 +341,22 @@ get_terminal(TerminalRef, DomainRevision) ->
throw(#payproc_TerminalNotFound{})
end.
get_globals(GlobalsRef, DomainRevision) ->
try
pm_domain:get(DomainRevision, {globals, GlobalsRef})
catch
error:{object_not_found, {DomainRevision, {globals, GlobalsRef}}} ->
throw(#payproc_GlobalsNotFound{})
end.
get_payment_routing_ruleset(RuleSetRef, DomainRevision) ->
try
pm_domain:get(DomainRevision, {payment_routing_rules, RuleSetRef})
catch
error:{object_not_found, {DomainRevision, {payment_routing_rules, RuleSetRef}}} ->
throw(#payproc_RuleSetNotFound{})
end.
get_default_contract_template(#domain_PaymentInstitution{default_contract_template = ContractSelector}, VS, Revision) ->
ContractTemplateRef = pm_selector:reduce_to_value(ContractSelector, VS, Revision),
pm_domain:get(Revision, {contract_template, ContractTemplateRef}).
@ -364,21 +398,37 @@ prepare_varset(#payproc_Varset{} = V) ->
prepare_varset(PartyID, #payproc_Varset{} = V) ->
prepare_varset(PartyID, V, #{}).
prepare_varset(PartyID, #payproc_Varset{} = V, VS0) ->
prepare_varset(PartyID0, #payproc_Varset{} = V, VS0) ->
PartyID1 = get_party_id(V, PartyID0),
genlib_map:compact(VS0#{
party_id => PartyID,
party_id => PartyID1,
category => V#payproc_Varset.category,
currency => V#payproc_Varset.currency,
cost => V#payproc_Varset.amount,
payment_tool => prepare_payment_tool_var(V#payproc_Varset.payment_method),
payment_tool => prepare_payment_tool_var(V#payproc_Varset.payment_method, V#payproc_Varset.payment_tool),
payout_method => V#payproc_Varset.payout_method,
wallet_id => V#payproc_Varset.wallet_id,
p2p_tool => V#payproc_Varset.p2p_tool
p2p_tool => V#payproc_Varset.p2p_tool,
identification_level => V#payproc_Varset.identification_level
}).
prepare_payment_tool_var(PaymentMethodRef) when PaymentMethodRef /= undefined ->
get_party_id(V, undefined) ->
V#payproc_Varset.party_id;
get_party_id(#payproc_Varset{party_id = undefined}, PartyID) ->
PartyID;
get_party_id(#payproc_Varset{party_id = PartyID1}, PartyID2) when PartyID1 =:= PartyID2 ->
PartyID1;
get_party_id(#payproc_Varset{party_id = PartyID1}, PartyID2) when PartyID1 =/= PartyID2 ->
throw(#payproc_VarsetPartyNotMatch{
varset_party_id = PartyID1,
agrument_party_id = PartyID2
}).
prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined ->
PaymentTool;
prepare_payment_tool_var(PaymentMethodRef = #domain_PaymentMethodRef{}, _PaymentTool) ->
pm_payment_tool:create_from_method(PaymentMethodRef);
prepare_payment_tool_var(undefined) ->
prepare_payment_tool_var(undefined, undefined) ->
undefined.
get_identification_level(#domain_Contract{contractor_id = undefined, contractor = Contractor}, _) ->

View File

@ -0,0 +1,72 @@
-module(pm_ruleset).
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl").
%% API
-export([reduce_payment_routing_ruleset/3]).
-define(const(Bool), {constant, Bool}).
-type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRuleset'().
-type varset() :: pm_selector:varset().
-type domain_revision() :: pm_domain:revision().
-spec reduce_payment_routing_ruleset(payment_routing_ruleset(), varset(), domain_revision()) ->
payment_routing_ruleset().
reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision) ->
RuleSet#domain_PaymentRoutingRuleset{
decisions = reduce_payment_routing_decisions(RuleSet#domain_PaymentRoutingRuleset.decisions, VS, DomainRevision)
}.
reduce_payment_routing_decisions({Type, []}, _, _) ->
{Type, []};
reduce_payment_routing_decisions({delegates, Delegates}, VS, Rev) ->
reduce_payment_routing_delegates(Delegates, VS, Rev);
reduce_payment_routing_decisions({candidates, Candidates}, VS, Rev) ->
reduce_payment_routing_candidates(Candidates, VS, Rev).
reduce_payment_routing_delegates([D | Delegates], VS, Rev) ->
Predicate = D#domain_PaymentRoutingDelegate.allowed,
RuleSetRef = D#domain_PaymentRoutingDelegate.ruleset,
case pm_selector:reduce_predicate(Predicate, VS, Rev) of
?const(false) ->
reduce_payment_routing_delegates(Delegates, VS, Rev);
?const(true) ->
#domain_PaymentRoutingRuleset{
decisions = Decisions
} = get_payment_routing_ruleset(RuleSetRef, Rev),
reduce_payment_routing_decisions(Decisions, VS, Rev);
_ ->
logger:warning(
"Routing rule misconfiguration, can't reduce decision. Predicate: ~p~n Varset:~n~p",
[Predicate, VS]
),
{delegates, [D | Delegates]}
end.
reduce_payment_routing_candidates(Candidates, VS, Rev) ->
{candidates, lists:foldr(
fun(C, AccIn) ->
Predicate = C#domain_PaymentRoutingCandidate.allowed,
case pm_selector:reduce_predicate(Predicate, VS, Rev) of
?const(false) ->
AccIn;
?const(true) = ReducedPredicate ->
ReducedCandidate = C#domain_PaymentRoutingCandidate{
allowed = ReducedPredicate
},
[ReducedCandidate | AccIn];
_ ->
logger:warning(
"Routing rule misconfiguration, can't reduce decision. Predicate: ~p~nVarset:~n~p",
[Predicate, VS]
),
[C | AccIn]
end
end,
[], Candidates)}.
get_payment_routing_ruleset(RuleSetRef, DomainRevision) ->
pm_domain:get(DomainRevision, {payment_routing_rules, RuleSetRef}).

View File

@ -23,6 +23,7 @@
-define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}).
-define(bank(ID), #domain_BankRef{id = ID}).
-define(bussched(ID), #domain_BusinessScheduleRef{id = ID}).
-define(ruleset(ID), #domain_PaymentRoutingRulesetRef{id = ID}).
-define(p2pprov(ID), #domain_P2PProviderRef{id = ID}).
-define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}).
-define(crit(ID), #domain_CriterionRef{id = ID}).

View File

@ -26,6 +26,7 @@
-export([construct_business_schedule/1]).
-export([construct_criterion/3]).
-export([construct_term_set_hierarchy/3]).
-export([construct_payment_routing_ruleset/3]).
%%
@ -38,6 +39,8 @@
-type template() :: dmsl_domain_thrift:'ContractTemplateRef'().
-type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'().
-type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined.
-type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'().
-type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'().
-type external_account_set() :: dmsl_domain_thrift:'ExternalAccountSetRef'().
@ -309,3 +312,16 @@ construct_term_set_hierarchy(Ref, ParentRef, TermSet) ->
]
}
}}.
-spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) ->
dmsl_domain_thrift:'PaymentRoutingRulesetObject'().
construct_payment_routing_ruleset(Ref, Name, Decisions) ->
{payment_routing_rules, #domain_PaymentRoutingRulesObject{
ref = Ref,
data = #domain_PaymentRoutingRuleset{
name = Name,
decisions = Decisions
}
}}.

View File

@ -98,6 +98,10 @@
-export([compute_provider_not_found/1]).
-export([compute_provider_terminal_terms_ok/1]).
-export([compute_provider_terminal_terms_not_found/1]).
-export([compute_globals_ok/1]).
-export([compute_payment_routing_ruleset_ok/1]).
-export([compute_payment_routing_ruleset_unreducable/1]).
-export([compute_payment_routing_ruleset_not_found/1]).
-export([compute_pred_w_irreducible_criterion/1]).
-export([compute_terms_w_criteria/1]).
@ -127,7 +131,7 @@ all() ->
{group, contractor_management},
{group, claim_management},
{group, providers},
{group, compute},
{group, terms}
].
@ -247,11 +251,15 @@ groups() ->
complex_claim_acceptance,
no_pending_claims
]},
{providers, [parallel], [
{compute, [parallel], [
compute_provider_ok,
compute_provider_not_found,
compute_provider_terminal_terms_ok,
compute_provider_terminal_terms_not_found
compute_provider_terminal_terms_not_found,
compute_globals_ok,
compute_payment_routing_ruleset_ok,
compute_payment_routing_ruleset_unreducable,
compute_payment_routing_ruleset_not_found
]},
{terms, [sequence], [
party_creation,
@ -388,6 +396,8 @@ end_per_testcase(_Name, _C) ->
?pmt(bank_card_deprecated, visa)
]).
-define(WRONG_DMT_OBJ_ID, 99999).
-spec party_creation(config()) -> _ | no_return().
-spec party_not_found_on_retrieval(config()) -> _ | no_return().
-spec party_already_exists(config()) -> _ | no_return().
@ -470,6 +480,10 @@ end_per_testcase(_Name, _C) ->
-spec compute_provider_not_found(config()) -> _ | no_return().
-spec compute_provider_terminal_terms_ok(config()) -> _ | no_return().
-spec compute_provider_terminal_terms_not_found(config()) -> _ | no_return().
-spec compute_globals_ok(config()) -> _ | no_return().
-spec compute_payment_routing_ruleset_ok(config()) -> _ | no_return().
-spec compute_payment_routing_ruleset_unreducable(config()) -> _ | no_return().
-spec compute_payment_routing_ruleset_not_found(config()) -> _ | no_return().
-spec compute_pred_w_irreducible_criterion(config()) -> _ | no_return().
-spec compute_terms_w_criteria(config()) -> _ | no_return().
@ -1529,7 +1543,7 @@ compute_provider_not_found(C) ->
Client = cfg(client, C),
DomainRevision = pm_domain:head(),
{exception, #payproc_ProviderNotFound{}} =
(catch pm_client_party:compute_provider(?prv(2), DomainRevision, #payproc_Varset{}, Client)).
(catch pm_client_party:compute_provider(?prv(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client)).
compute_provider_terminal_terms_ok(C) ->
Client = cfg(client, C),
@ -1561,13 +1575,73 @@ compute_provider_terminal_terms_not_found(C) ->
DomainRevision = pm_domain:head(),
{exception, #payproc_TerminalNotFound{}} =
(catch pm_client_party:compute_provider_terminal_terms(
?prv(1), ?trm(2), DomainRevision, #payproc_Varset{}, Client)),
?prv(1), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client)),
{exception, #payproc_ProviderNotFound{}} =
(catch pm_client_party:compute_provider_terminal_terms(
?prv(2), ?trm(1), DomainRevision, #payproc_Varset{}, Client)),
?prv(?WRONG_DMT_OBJ_ID), ?trm(1), DomainRevision, #payproc_Varset{}, Client)),
{exception, #payproc_ProviderNotFound{}} =
(catch pm_client_party:compute_provider_terminal_terms(
?prv(2), ?trm(2), DomainRevision, #payproc_Varset{}, Client)).
?prv(?WRONG_DMT_OBJ_ID), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client)).
compute_globals_ok(C) ->
Client = cfg(client, C),
DomainRevision = pm_domain:head(),
Varset = #payproc_Varset{},
#domain_Globals{
external_account_set = {value, ?eas(1)}
} = pm_client_party:compute_globals(#domain_GlobalsRef{}, DomainRevision, Varset, Client).
compute_payment_routing_ruleset_ok(C) ->
Client = cfg(client, C),
DomainRevision = pm_domain:head(),
Varset = #payproc_Varset{
party_id = <<"67890">>
},
#domain_PaymentRoutingRuleset{
name = <<"Rule#1">>,
decisions = {candidates, [
#domain_PaymentRoutingCandidate{
terminal = ?trm(2),
allowed = {constant, true}
},
#domain_PaymentRoutingCandidate{
terminal = ?trm(3),
allowed = {constant, true}
},
#domain_PaymentRoutingCandidate{
terminal = ?trm(1),
allowed = {constant, true}
}
]}
} = pm_client_party:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client).
compute_payment_routing_ruleset_unreducable(C) ->
Client = cfg(client, C),
DomainRevision = pm_domain:head(),
Varset = #payproc_Varset{},
#domain_PaymentRoutingRuleset{
name = <<"Rule#1">>,
decisions = {delegates, [
#domain_PaymentRoutingDelegate{
allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}},
ruleset = ?ruleset(2)
},
#domain_PaymentRoutingDelegate{
allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}},
ruleset = ?ruleset(3)
},
#domain_PaymentRoutingDelegate{
allowed = {constant, true},
ruleset = ?ruleset(4)
}
]}
} = pm_client_party:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client).
compute_payment_routing_ruleset_not_found(C) ->
Client = cfg(client, C),
DomainRevision = pm_domain:head(),
{exception, #payproc_RuleSetNotFound{}} =
(catch pm_client_party:compute_payment_routing_ruleset(?ruleset(5), DomainRevision, #payproc_Varset{}, Client)).
%%
@ -2055,6 +2129,46 @@ construct_domain_fixture() ->
}
}
},
Decision1 = {delegates, [
#domain_PaymentRoutingDelegate{
allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}},
ruleset = ?ruleset(2)
},
#domain_PaymentRoutingDelegate{
allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}},
ruleset = ?ruleset(3)
},
#domain_PaymentRoutingDelegate{
allowed = {constant, true},
ruleset = ?ruleset(4)
}
]},
Decision2 = {candidates, [
#domain_PaymentRoutingCandidate{
allowed = {constant, true},
terminal = ?trm(1)
}
]},
Decision3 = {candidates, [
#domain_PaymentRoutingCandidate{
allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}},
terminal = ?trm(2)
},
#domain_PaymentRoutingCandidate{
allowed = {constant, true},
terminal = ?trm(3)
},
#domain_PaymentRoutingCandidate{
allowed = {constant, true},
terminal = ?trm(1)
}
]},
Decision4 = {candidates, [
#domain_PaymentRoutingCandidate{
allowed = {constant, true},
terminal = ?trm(3)
}
]},
[
pm_ct_fixture:construct_currency(?cur(<<"RUB">>)),
pm_ct_fixture:construct_currency(?cur(<<"USD">>)),
@ -2081,6 +2195,11 @@ construct_domain_fixture() ->
pm_ct_fixture:construct_business_schedule(?bussched(1)),
hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(1), <<"Rule#1">>, Decision1),
hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(2), <<"Rule#2">>, Decision2),
hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(3), <<"Rule#3">>, Decision3),
hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(4), <<"Rule#4">>, Decision4),
{payment_institution, #domain_PaymentInstitutionObject{
ref = ?pinst(1),
data = #domain_PaymentInstitution{
@ -2123,7 +2242,12 @@ construct_domain_fixture() ->
{globals, #domain_GlobalsObject{
ref = #domain_GlobalsRef{},
data = #domain_Globals{
external_account_set = {value, ?eas(1)},
external_account_set = {decisions, [
#domain_ExternalAccountSetDecision{
if_ = {constant, true},
then_ = {value, ?eas(1)}
}
]},
payment_institutions = ?ordset([?pinst(1), ?pinst(2)])
}
}},
@ -2371,5 +2495,33 @@ construct_domain_fixture() ->
}
}
}
}},
{terminal, #domain_TerminalObject{
ref = ?trm(2),
data = #domain_Terminal{
name = <<"Brominal 2">>,
description = <<"Brominal 2">>,
terms = #domain_ProvisionTermSet{
payments = #domain_PaymentsProvisionTerms{
payment_methods = {value, ?ordset([
?pmt(bank_card_deprecated, visa)
])}
}
}
}
}},
{terminal, #domain_TerminalObject{
ref = ?trm(3),
data = #domain_Terminal{
name = <<"Brominal 3">>,
description = <<"Brominal 3">>,
terms = #domain_ProvisionTermSet{
payments = #domain_PaymentsProvisionTerms{
payment_methods = {value, ?ordset([
?pmt(bank_card_deprecated, visa)
])}
}
}
}
}}
].

View File

@ -48,6 +48,8 @@
-export([compute_provider/4]).
-export([compute_provider_terminal_terms/5]).
-export([compute_globals/4]).
-export([compute_payment_routing_ruleset/4]).
%% GenServer
@ -81,8 +83,10 @@
-type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'().
-type varset() :: dmsl_payment_processing_thrift:'Varset'().
-type provider_ref() :: dmsl_domain_thrift:'ProviderRef'().
-type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'().
-type provider_ref() :: dmsl_domain_thrift:'ProviderRef'().
-type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'().
-type globals_ref() :: dmsl_domain_thrift:'GlobalsRef'().
-type payment_routring_ruleset_ref() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'().
-spec start(party_id(), pm_client_api:t()) -> pid().
@ -206,7 +210,7 @@ compute_contract_terms(ID, Timestamp, PartyRevision, DomainRevision, Varset, Cli
dmsl_domain_thrift:'TermSet'() | woody_error:business_error().
compute_payment_institution_terms(Ref, Varset, Client) ->
map_result_error(gen_server:call(Client, {call, 'ComputePaymentInstitutionTerms', [Ref, Varset]})).
map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentInstitutionTerms', [Ref, Varset]})).
-spec compute_payout_cash_flow(dmsl_payment_processing_thrift:'PayoutParams'(), pid()) ->
dmsl_domain_thrift:'FinalCashFlow'() | woody_error:business_error().
@ -323,6 +327,20 @@ compute_provider_terminal_terms(PaymentProviderRef, TerminalRef, Revision, Varse
map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProviderTerminalTerms',
[PaymentProviderRef, TerminalRef, Revision, Varset]})).
-spec compute_globals(globals_ref(), domain_revision(), varset(), pid()) ->
dmsl_domain_thrift:'Globals'() | woody_error:business_error().
compute_globals(GlobalsRef, Revision, Varset, Client) ->
map_result_error(gen_server:call(Client, {call_without_party, 'ComputeGlobals',
[GlobalsRef, Revision, Varset]})).
-spec compute_payment_routing_ruleset(payment_routring_ruleset_ref(), domain_revision(), varset(), pid()) ->
dmsl_domain_thrift:'PaymentRoutingRuleset'() | woody_error:business_error().
compute_payment_routing_ruleset(PaymentRoutingRuleSetRef, Revision, Varset, Client) ->
map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentRoutingRuleset',
[PaymentRoutingRuleSetRef, Revision, Varset]})).
-define(DEFAULT_NEXT_EVENT_TIMEOUT, 5000).
-spec pull_event(pid()) ->

View File

@ -10,7 +10,7 @@
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2},
{<<"damsel">>,
{git,"git@github.com:rbkmoney/damsel.git",
{ref,"735897b8b802e7d983bafada28cbc789049e7428"}},
{ref,"f816e8fc31830dc5247ff765a8672f3d1888a48b"}},
0},
{<<"dmt_client">>,
{git,"git@github.com:rbkmoney/dmt_client.git",