Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 32 additions & 17 deletions apps/hellgate/src/hg_cashflow.erl
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
-type shop_config_ref() :: dmsl_domain_thrift:'ShopConfigRef'().
-type party_config_ref() :: dmsl_domain_thrift:'PartyConfigRef'().
-type route() :: hg_route:payment_route().
-type exchange_context() :: hg_invoice_payment:exchange_context().
-type options() :: #{
exchange_context => hg_invoice_payment:exchange_context()
exchange_context => exchange_context()
}.

%%
Expand All @@ -43,6 +44,7 @@
-export([revert/1]).

-export([compute_volume/2]).
-export([compute_volume/3]).

-export([get_partial_remainders/1]).

Expand Down Expand Up @@ -85,7 +87,7 @@ compute_postings(CF, Context, AccountMap, Opts) ->
?final_posting(
construct_final_account(Source, AccountMap),
construct_final_account(Destination, AccountMap),
hg_currency_converter:maybe_reverse_convert_cash(ExchangeContext, compute_volume(Volume, Context)),
compute_volume(Volume, Context, ExchangeContext),
Details,
ExchangeContext
)
Expand Down Expand Up @@ -172,14 +174,20 @@ revert_details(Details) ->
-define(rational(P, Q), #base_Rational{p = P, q = Q}).

-spec compute_volume(cash_volume(), context()) -> cash() | no_return().
compute_volume(?fixed(Cash), _Context) ->
Cash;
compute_volume(?share(P, Q, Of, RoundingMethod), Context) ->
compute_volume(Volume, Context) ->
Comment thread
ttt161 marked this conversation as resolved.
compute_volume(Volume, Context, undefined).

-spec compute_volume(cash_volume(), context(), exchange_context() | undefined) -> cash() | no_return().
compute_volume(?fixed(Cash), _Context, ExchangeContext) ->
%% if posting currency differs from payment currency
%% needs re-convert it into payment currency
hg_currency_converter:maybe_reverse_convert_cash(ExchangeContext, Cash);
compute_volume(?share(P, Q, Of, RoundingMethod), Context, _ExchangeContext) ->
compute_parts_of(P, Q, resolve_constant(Of, Context), RoundingMethod);
compute_volume(?product(Fun, CVs) = CV0, Context) ->
compute_volume(?product(Fun, CVs) = CV0, Context, ExchangeContext) ->
case ordsets:size(CVs) of
N when N > 0 ->
compute_product(Fun, ordsets:to_list(CVs), CV0, Context);
compute_product(Fun, ordsets:to_list(CVs), CV0, Context, ExchangeContext);
0 ->
error({misconfiguration, {'Cash volume product over empty set', CV0}})
end.
Expand All @@ -195,15 +203,22 @@ compute_parts_of(P, Q, #domain_Cash{amount = Amount} = Cash, RoundingMethod) ->
)
}.

compute_product(Fun, [CV | CVRest], CV0, Context) ->
compute_product(Fun, [CV | CVRest], CV0, Context, ExchangeContext) ->
lists:foldl(
fun(CVN, CVMin) -> compute_product(Fun, CVN, CVMin, CV0, Context) end,
compute_volume(CV, Context),
fun(CVN, CVMin) -> compute_product(Fun, CVN, CVMin, CV0, Context, ExchangeContext) end,
compute_volume(CV, Context, ExchangeContext),
CVRest
).

compute_product(Fun, CV, #domain_Cash{amount = AmountMin, currency = Currency} = CVMin, CV0, Context) ->
case compute_volume(CV, Context) of
compute_product(
Fun,
CV,
#domain_Cash{amount = AmountMin, currency = Currency} = CVMin,
CV0,
Context,
ExchangeContext
) ->
case compute_volume(CV, Context, ExchangeContext) of
#domain_Cash{amount = Amount, currency = Currency} ->
CVMin#domain_Cash{amount = compute_product_fun(Fun, AmountMin, Amount)};
_ ->
Expand Down Expand Up @@ -273,22 +288,22 @@ modify_remainder(#domain_FinalCashFlowAccount{account_type = AccountType}, ?cash

compute_volume_test() ->
Cash = ?cash(100, <<"RUB">>),
?assertEqual(Cash, compute_volume(?fixed(Cash), #{})),
?assertEqual(Cash, compute_volume(?fixed(Cash), #{}, undefined)),
?assertEqual(
?cash(1, <<"RUB">>),
compute_volume(?share(1, 100, operation_amount, undefined), #{operation_amount => Cash})
compute_volume(?share(1, 100, operation_amount, undefined), #{operation_amount => Cash}, undefined)
),
?assertEqual(
Cash,
compute_volume(?product(min_of, [?fixed(Cash), ?fixed(?cash(200, <<"RUB">>))]), #{})
compute_volume(?product(min_of, [?fixed(Cash), ?fixed(?cash(200, <<"RUB">>))]), #{}, undefined)
),
?assertEqual(
Cash,
compute_volume(?product(max_of, [?fixed(Cash), ?fixed(?cash(50, <<"RUB">>))]), #{})
compute_volume(?product(max_of, [?fixed(Cash), ?fixed(?cash(50, <<"RUB">>))]), #{}, undefined)
),
?assertEqual(
?cash(200, <<"RUB">>),
compute_volume(?product(sum_of, [?fixed(Cash), ?fixed(Cash)]), #{})
compute_volume(?product(sum_of, [?fixed(Cash), ?fixed(Cash)]), #{}, undefined)
).

-endif.
6 changes: 3 additions & 3 deletions apps/hellgate/src/hg_invoice_payment_chargeback.erl
Original file line number Diff line number Diff line change
Expand Up @@ -449,17 +449,17 @@ build_chargeback_final_cash_flow(State, Opts) ->
},
AccountMap = hg_accounting:collect_account_map(CollectAccountContext),
ServiceContext = build_service_cash_flow_context(State),
ProviderContext = build_provider_cash_flow_context(State, ProviderFees),
ProviderContext = build_provider_cash_flow_context(State, ProviderFees, ExchangeContext),
ServiceFinalCF = hg_cashflow:finalize(ServiceCashFlow, ServiceContext, AccountMap),
ProviderFinalCF = hg_cashflow:finalize(ProviderCashFlow, ProviderContext, AccountMap, ProviderOpts),
ServiceFinalCF ++ ProviderFinalCF.

build_service_cash_flow_context(State) ->
#{operation_amount => get_body(State), surplus => get_levy(State)}.

build_provider_cash_flow_context(State, Fees) ->
build_provider_cash_flow_context(State, Fees, ExchangeContext) ->
FeesContext = #{operation_amount => get_body(State)},
ComputedFees = maps:map(fun(_K, V) -> hg_cashflow:compute_volume(V, FeesContext) end, Fees),
ComputedFees = maps:map(fun(_K, V) -> hg_cashflow:compute_volume(V, FeesContext, ExchangeContext) end, Fees),
case get_target_status(State) of
?chargeback_status_rejected() ->
?cash(_Amount, SymCode) = get_body(State),
Expand Down
7 changes: 6 additions & 1 deletion apps/hellgate/test/hg_invoice_dummy_data.erl
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,12 @@ payment_provision_terms(Currency, Category) ->
?cfpost(
{system, settlement},
{provider, settlement},
?fixed(10, Currency)
{product,
{min_of,
?ordset([
?share(60, 1000, operation_amount),
?fixed(10, Currency)
])}}
)
]
},
Expand Down
Loading