Merge branch 'master' into TD-291/move_tests

This commit is contained in:
ndiezel0 2022-10-13 04:52:15 +05:00 committed by GitHub
commit 6ddd47d140
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 94 additions and 177 deletions

View File

@ -2915,7 +2915,7 @@ get_limit_overflow_routes(Routes, VS, St, RejectedRoutes) ->
PaymentRoute = hg_routing:to_payment_route(Route),
ProviderTerms = hg_routing:get_payment_terms(PaymentRoute, VS, Revision),
TurnoverLimits = get_turnover_limits(ProviderTerms),
case hg_limiter:check_limits(TurnoverLimits, Invoice, Payment) of
case hg_limiter:check_limits(TurnoverLimits, Invoice, Payment, PaymentRoute) of
{ok, _} ->
{[Route | RoutesNoOverflowIn], RejectedIn};
{error, {limit_overflow, IDs}} ->
@ -2986,7 +2986,8 @@ hold_refund_limits(RefundSt, St) ->
Refund = get_refund(RefundSt),
ProviderTerms = get_provider_terms(St, get_refund_revision(RefundSt)),
TurnoverLimits = get_turnover_limits(ProviderTerms),
hg_limiter:hold_refund_limits(TurnoverLimits, Invoice, Payment, Refund).
Route = get_route(St),
hg_limiter:hold_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route).
commit_refund_limits(RefundSt, St) ->
Revision = get_refund_revision(RefundSt),
@ -2995,7 +2996,8 @@ commit_refund_limits(RefundSt, St) ->
Payment = get_payment(St),
ProviderTerms = get_provider_terms(St, Revision),
TurnoverLimits = get_turnover_limits(ProviderTerms),
hg_limiter:commit_refund_limits(TurnoverLimits, Invoice, Payment, Refund).
Route = get_route(St),
hg_limiter:commit_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route).
rollback_refund_limits(RefundSt, St) ->
Revision = get_refund_revision(RefundSt),
@ -3004,7 +3006,8 @@ rollback_refund_limits(RefundSt, St) ->
Payment = get_payment(St),
ProviderTerms = get_provider_terms(St, Revision),
TurnoverLimits = get_turnover_limits(ProviderTerms),
hg_limiter:rollback_refund_limits(TurnoverLimits, Invoice, Payment, Refund).
Route = get_route(St),
hg_limiter:rollback_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route).
commit_payment_cashflow(St) ->
hg_accounting:commit(construct_payment_plan_id(St), get_cashflow_plan(St)).

View File

@ -1,8 +1,8 @@
-module(hg_limiter).
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("limiter_proto/include/limproto_base_thrift.hrl").
-include_lib("limiter_proto/include/limproto_limiter_thrift.hrl").
-include_lib("limiter_proto/include/limproto_context_limiter_thrift.hrl").
-include_lib("limiter_proto/include/limproto_context_payproc_thrift.hrl").
-type turnover_selector() :: dmsl_domain_thrift:'TurnoverLimitSelector'().
@ -14,13 +14,13 @@
-type cash() :: dmsl_domain_thrift:'Cash'().
-export([get_turnover_limits/1]).
-export([check_limits/3]).
-export([check_limits/4]).
-export([hold_payment_limits/4]).
-export([hold_refund_limits/4]).
-export([hold_refund_limits/5]).
-export([commit_payment_limits/5]).
-export([commit_refund_limits/4]).
-export([commit_refund_limits/5]).
-export([rollback_payment_limits/4]).
-export([rollback_refund_limits/4]).
-export([rollback_refund_limits/5]).
-define(route(ProviderRef, TerminalRef), #domain_PaymentRoute{
provider = ProviderRef,
@ -36,11 +36,11 @@ get_turnover_limits({value, Limits}) ->
get_turnover_limits(Ambiguous) ->
error({misconfiguration, {'Could not reduce selector to a value', Ambiguous}}).
-spec check_limits([turnover_limit()], invoice(), payment()) ->
-spec check_limits([turnover_limit()], invoice(), payment(), route()) ->
{ok, [hg_limiter_client:limit()]}
| {error, {limit_overflow, [binary()]}}.
check_limits(TurnoverLimits, Invoice, Payment) ->
Context = gen_limit_context(Invoice, Payment),
check_limits(TurnoverLimits, Invoice, Payment, Route) ->
Context = gen_limit_context(Invoice, Payment, Route),
try
check_limits_(TurnoverLimits, Context, [])
catch
@ -59,7 +59,7 @@ check_limits_([T | TurnoverLimits], Context, Acc) ->
amount = LimiterAmount
} = Limit,
UpperBoundary = T#domain_TurnoverLimit.upper_boundary,
case LimiterAmount < UpperBoundary of
case LimiterAmount =< UpperBoundary of
true ->
check_limits_(TurnoverLimits, Context, [Limit | Acc]);
false ->
@ -73,73 +73,75 @@ check_limits_([T | TurnoverLimits], Context, Acc) ->
-spec hold_payment_limits([turnover_limit()], route(), invoice(), payment()) -> ok.
hold_payment_limits(TurnoverLimits, Route, Invoice, Payment) ->
IDs = [T#domain_TurnoverLimit.id || T <- TurnoverLimits],
LimitChanges = gen_limit_payment_changes(IDs, Route, Invoice, Payment),
Context = gen_limit_context(Invoice, Payment),
ChangeID = construct_payment_change_id(Route, Invoice, Payment),
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeID),
Context = gen_limit_context(Invoice, Payment, Route),
hold(LimitChanges, get_latest_clock(), Context).
-spec hold_refund_limits([turnover_limit()], invoice(), payment(), refund()) -> ok.
hold_refund_limits(TurnoverLimits, Invoice, Payment, Refund) ->
IDs = [T#domain_TurnoverLimit.id || T <- TurnoverLimits],
LimitChanges = gen_limit_refund_changes(IDs, Invoice, Payment, Refund),
Context = gen_limit_refund_context(Invoice, Payment, Refund),
-spec hold_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok.
hold_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
ChangeID = construct_refund_change_id(Invoice, Payment, Refund),
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeID),
Context = gen_limit_refund_context(Invoice, Payment, Refund, Route),
hold(LimitChanges, get_latest_clock(), Context).
-spec commit_payment_limits([turnover_limit()], route(), invoice(), payment(), cash() | undefined) -> ok.
commit_payment_limits(TurnoverLimits, Route, Invoice, Payment, CapturedCash) ->
IDs = [T#domain_TurnoverLimit.id || T <- TurnoverLimits],
LimitChanges = gen_limit_payment_changes(IDs, Route, Invoice, Payment),
Context = gen_limit_context(Invoice, Payment, CapturedCash),
ChangeID = construct_payment_change_id(Route, Invoice, Payment),
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeID),
Context = gen_limit_context(Invoice, Payment, Route, CapturedCash),
commit(LimitChanges, get_latest_clock(), Context).
-spec commit_refund_limits([turnover_limit()], invoice(), payment(), refund()) -> ok.
commit_refund_limits(TurnoverLimits, Invoice, Payment, Refund) ->
IDs = [T#domain_TurnoverLimit.id || T <- TurnoverLimits],
LimitChanges = gen_limit_refund_changes(IDs, Invoice, Payment, Refund),
Context = gen_limit_refund_context(Invoice, Payment, Refund),
-spec commit_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok.
commit_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
ChangeID = construct_refund_change_id(Invoice, Payment, Refund),
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeID),
Context = gen_limit_refund_context(Invoice, Payment, Refund, Route),
commit(LimitChanges, get_latest_clock(), Context).
-spec rollback_payment_limits([turnover_limit()], route(), invoice(), payment()) -> ok.
rollback_payment_limits(TurnoverLimits, Route, Invoice, Payment) ->
#domain_InvoicePayment{cost = Cash} = Payment,
CapturedCash = Cash#domain_Cash{
amount = 0
},
commit_payment_limits(TurnoverLimits, Route, Invoice, Payment, CapturedCash).
ChangeID = construct_payment_change_id(Route, Invoice, Payment),
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeID),
Context = gen_limit_context(Invoice, Payment, Route),
rollback(LimitChanges, get_latest_clock(), Context).
-spec rollback_refund_limits([turnover_limit()], invoice(), payment(), refund()) -> ok.
rollback_refund_limits(TurnoverLimits, Invoice, Payment, Refund0) ->
Refund1 = set_refund_amount(0, Refund0),
commit_refund_limits(TurnoverLimits, Invoice, Payment, Refund1).
-spec rollback_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok.
rollback_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
ChangeID = construct_refund_change_id(Invoice, Payment, Refund),
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeID),
Context = gen_limit_refund_context(Invoice, Payment, Refund, Route),
rollback(LimitChanges, get_latest_clock(), Context).
-spec hold([hg_limiter_client:limit_change()], hg_limiter_client:clock(), hg_limiter_client:context()) -> ok.
hold(LimitChanges, Clock, Context) ->
lists:foreach(
fun(LimitChange) ->
hg_limiter_client:hold(LimitChange, Clock, Context)
end,
LimitChanges
).
process_changes(LimitChanges, fun hg_limiter_client:hold/3, Clock, Context).
-spec commit([hg_limiter_client:limit_change()], hg_limiter_client:clock(), hg_limiter_client:context()) -> ok.
commit(LimitChanges, Clock, Context) ->
process_changes(LimitChanges, fun hg_limiter_client:commit/3, Clock, Context).
-spec rollback([hg_limiter_client:limit_change()], hg_limiter_client:clock(), hg_limiter_client:context()) -> ok.
rollback(LimitChanges, Clock, Context) ->
process_changes(LimitChanges, fun hg_limiter_client:rollback/3, Clock, Context).
process_changes(LimitChanges, WithFun, Clock, Context) ->
lists:foreach(
fun(LimitChange) ->
hg_limiter_client:commit(LimitChange, Clock, Context)
end,
fun(LimitChange) -> WithFun(LimitChange, Clock, Context) end,
LimitChanges
).
gen_limit_context(Invoice, Payment) ->
gen_limit_context(Invoice, Payment, undefined).
gen_limit_context(Invoice, Payment, Route) ->
gen_limit_context(Invoice, Payment, Route, undefined).
gen_limit_context(Invoice, Payment, CapturedCash) ->
gen_limit_context(Invoice, Payment, Route, CapturedCash) ->
PaymentCtx = #context_payproc_InvoicePayment{
payment = Payment#domain_InvoicePayment{
status = {captured, #domain_InvoicePaymentCaptured{cost = CapturedCash}}
}
},
#context_limiter_LimitContext{
route = convert_to_limit_route(Route)
},
#limiter_LimitContext{
payment_processing = #context_payproc_Context{
op = {invoice_payment, #context_payproc_OperationInvoicePayment{}},
invoice = #context_payproc_Invoice{
@ -149,12 +151,13 @@ gen_limit_context(Invoice, Payment, CapturedCash) ->
}
}.
gen_limit_refund_context(Invoice, Payment, Refund) ->
gen_limit_refund_context(Invoice, Payment, Refund, Route) ->
PaymentCtx = #context_payproc_InvoicePayment{
payment = Payment,
refund = Refund
refund = Refund,
route = convert_to_limit_route(Route)
},
#context_limiter_LimitContext{
#limiter_LimitContext{
payment_processing = #context_payproc_Context{
op = {invoice_payment_refund, #context_payproc_OperationInvoicePaymentRefund{}},
invoice = #context_payproc_Invoice{
@ -164,43 +167,29 @@ gen_limit_refund_context(Invoice, Payment, Refund) ->
}
}.
gen_limit_payment_changes(LimitIDs, Route, Invoice, Payment) ->
gen_limit_changes(Limits, ChangeID) ->
[
#limiter_LimitChange{
id = ID,
change_id = construct_limit_change_id(ID, Route, Invoice, Payment)
change_id = hg_utils:construct_complex_id([<<"limiter">>, ID, ChangeID])
}
|| ID <- LimitIDs
|| #domain_TurnoverLimit{id = ID} <- Limits
].
gen_limit_refund_changes(LimitIDs, Invoice, Payment, Refund) ->
[
#limiter_LimitChange{
id = ID,
change_id = construct_limit_refund_change_id(ID, Invoice, Payment, Refund)
}
|| ID <- LimitIDs
].
construct_limit_change_id(LimitID, Route, Invoice, Payment) ->
?route(ProviderRef, TerminalRef) = Route,
ComplexID = hg_utils:construct_complex_id([
LimitID,
construct_payment_change_id(?route(ProviderRef, TerminalRef), Invoice, Payment) ->
hg_utils:construct_complex_id([
genlib:to_binary(get_provider_id(ProviderRef)),
genlib:to_binary(get_terminal_id(TerminalRef)),
get_invoice_id(Invoice),
get_payment_id(Payment)
]),
genlib_string:join($., [<<"limiter">>, ComplexID]).
]).
construct_limit_refund_change_id(LimitID, Invoice, Payment, Refund) ->
ComplexID = hg_utils:construct_complex_id([
LimitID,
construct_refund_change_id(Invoice, Payment, Refund) ->
hg_utils:construct_complex_id([
get_invoice_id(Invoice),
get_payment_id(Payment),
{refund_session, get_refund_id(Refund)}
]),
genlib_string:join($., [<<"limiter">>, ComplexID]).
]).
get_provider_id(#domain_ProviderRef{id = ID}) ->
ID.
@ -220,34 +209,8 @@ get_refund_id(#domain_InvoicePaymentRefund{id = ID}) ->
get_latest_clock() ->
{latest, #limiter_LatestClock{}}.
set_refund_amount(Amount, Refund) ->
IFDefined = fun
(undefined, _) ->
undefined;
(Value, Fun) ->
Fun(Value)
end,
#domain_InvoicePaymentRefund{
cash = Cash,
cart = InvoiceCart
} = Refund,
Refund#domain_InvoicePaymentRefund{
cash = IFDefined(Cash, fun(C) -> set_cash_amount(Amount, C) end),
cart = IFDefined(InvoiceCart, fun(Cart) ->
#domain_InvoiceCart{lines = Lines} = Cart,
lists:foldl(
fun(Line, Acc) ->
#domain_InvoiceLine{price = Price} = Line,
Line1 = Line#domain_InvoiceLine{
price = set_cash_amount(Amount, Price)
},
[Line1 | Acc]
end,
[],
Lines
)
end)
convert_to_limit_route(#domain_PaymentRoute{provider = Provider, terminal = Terminal}) ->
#base_Route{
provider = Provider,
terminal = Terminal
}.
set_cash_amount(Amount, Cash) ->
Cash#domain_Cash{amount = Amount}.

View File

@ -6,6 +6,7 @@
-export([get/3]).
-export([hold/3]).
-export([commit/3]).
-export([rollback/3]).
-type limit() :: limproto_limiter_thrift:'Limit'().
-type limit_id() :: limproto_limiter_thrift:'LimitID'().
@ -34,17 +35,13 @@ get(LimitID, Clock, Context) ->
-spec hold(limit_change(), clock(), context()) -> clock() | no_return().
hold(LimitChange, Clock, Context) ->
LimitID = LimitChange#limiter_LimitChange.id,
Opts = hg_woody_wrapper:get_service_options(limiter),
Args = {LimitChange, Clock, Context},
case hg_woody_wrapper:call(limiter, 'Hold', Args, Opts) of
{ok, ClockUpdated} ->
ClockUpdated;
{exception, #limiter_LimitNotFound{}} ->
error({not_found, LimitID});
{exception, #base_InvalidRequest{errors = Errors}} ->
error({invalid_request, Errors})
{exception, Exception} ->
error(Exception)
end.
-spec commit(limit_change(), clock(), context()) -> clock() | no_return().
@ -54,14 +51,17 @@ commit(LimitChange, Clock, Context) ->
case hg_woody_wrapper:call(limiter, 'Commit', Args, Opts) of
{ok, ClockUpdated} ->
ClockUpdated;
{exception, #limiter_LimitNotFound{}} ->
error({not_found, LimitChange#limiter_LimitChange.id});
{exception, #limiter_LimitChangeNotFound{}} ->
error({not_found, {limit_change, LimitChange#limiter_LimitChange.change_id}});
{exception, #base_InvalidRequest{errors = Errors}} ->
error({invalid_request, Errors});
{exception, #limiter_ForbiddenOperationAmount{} = Ex} ->
Amount = Ex#limiter_ForbiddenOperationAmount.amount,
CashRange = Ex#limiter_ForbiddenOperationAmount.allowed_range,
error({forbidden_op_amount, {Amount, CashRange}})
{exception, Exception} ->
error(Exception)
end.
-spec rollback(limit_change(), clock(), context()) -> clock() | no_return().
rollback(LimitChange, Clock, Context) ->
Opts = hg_woody_wrapper:get_service_options(limiter),
Args = {LimitChange, Clock, Context},
case hg_woody_wrapper:call(limiter, 'Rollback', Args, Opts) of
{ok, ClockUpdated} ->
ClockUpdated;
{exception, Exception} ->
error(Exception)
end.

View File

@ -702,15 +702,6 @@ construct_domain_fixture(TermSet) ->
}}
}}}},
then_ = {value, ?hold_lifetime(12)}
},
#domain_HoldLifetimeDecision{
if_ =
{condition,
{payment_tool,
{bank_card, #domain_BankCardCondition{
definition = {payment_system_is, visa}
}}}},
then_ = {value, ?hold_lifetime(12)}
}
]}
}

View File

@ -662,27 +662,6 @@ construct_domain_fixture() ->
?share(18, 1000, operation_amount)
)
]}
},
#domain_CashFlowDecision{
if_ =
{condition,
{payment_tool,
{bank_card, #domain_BankCardCondition{
definition = {payment_system_is, visa}
}}}},
then_ =
{value, [
?cfpost(
{provider, settlement},
{merchant, settlement},
?share(1, 1, operation_amount)
),
?cfpost(
{system, settlement},
{provider, settlement},
?share(18, 1000, operation_amount)
)
]}
}
]},
holds = #domain_PaymentHoldsProvisionTerms{
@ -699,15 +678,6 @@ construct_domain_fixture() ->
}}
}}}},
then_ = {value, ?hold_lifetime(12)}
},
#domain_HoldLifetimeDecision{
if_ =
{condition,
{payment_tool,
{bank_card, #domain_BankCardCondition{
definition = {payment_system_is, visa}
}}}},
then_ = {value, ?hold_lifetime(12)}
}
]}
},

View File

@ -6394,15 +6394,6 @@ construct_domain_fixture() ->
])},
lifetime =
{decisions, [
#domain_HoldLifetimeDecision{
if_ =
{condition,
{payment_tool,
{bank_card, #domain_BankCardCondition{
definition = {payment_system_is, mastercard}
}}}},
then_ = {value, ?hold_lifetime(120)}
},
#domain_HoldLifetimeDecision{
if_ =
{condition,

View File

@ -1,7 +1,6 @@
-module(hg_limiter_helper).
-include_lib("limiter_proto/include/limproto_limiter_thrift.hrl").
-include_lib("limiter_proto/include/limproto_context_limiter_thrift.hrl").
-include_lib("limiter_proto/include/limproto_context_payproc_thrift.hrl").
-include_lib("limiter_proto/include/limproto_config_thrift.hrl").
-include_lib("limiter_proto/include/limproto_configurator_thrift.hrl").
@ -40,7 +39,7 @@ assert_payment_limit_amount(AssertAmount, Payment, Invoice) ->
-spec get_payment_limit_amount(_, _, _) -> _.
get_payment_limit_amount(LimitId, Payment, Invoice) ->
Context = #context_limiter_LimitContext{
Context = #limiter_LimitContext{
payment_processing = #context_payproc_Context{
op = {invoice_payment, #context_payproc_OperationInvoicePayment{}},
invoice = #context_payproc_Invoice{

View File

@ -63,7 +63,7 @@ services:
retries: 10
limiter:
image: ghcr.io/valitydev/limiter:sha-2dff7b5
image: ghcr.io/valitydev/limiter:sha-cd37acd
command: /opt/limiter/bin/limiter foreground
depends_on:
machinegun:

View File

@ -17,7 +17,7 @@
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2},
{<<"damsel">>,
{git,"https://github.com/valitydev/damsel.git",
{ref,"53dab99962edf2dd0102a54e41133d91ccbcbef5"}},
{ref,"60474970af1d5e58752f4e5680e67c65ff64dda9"}},
0},
{<<"dmt_client">>,
{git,"https://github.com/valitydev/dmt-client.git",
@ -45,7 +45,7 @@
{<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1},
{<<"limiter_proto">>,
{git,"https://github.com/valitydev/limiter-proto.git",
{ref,"c5dfe39a0024da82f5a7458005a337f266e1e19d"}},
{ref,"31de59b17ad20e426b158ace6097e35330926bea"}},
0},
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2},
{<<"mg_proto">>,