CM-25: Adds limit changes queue for id BC (#63)

This commit is contained in:
Aleksey Kashapov 2023-03-28 13:59:47 +03:00 committed by GitHub
parent d128e196be
commit de0c01cfe4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,6 +1,7 @@
-module(hg_limiter).
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_base_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_payproc_thrift.hrl").
@ -13,6 +14,8 @@
-type refund() :: hg_invoice_payment:domain_refund().
-type cash() :: dmsl_domain_thrift:'Cash'().
-type change_queue() :: [hg_limiter_client:limit_change()].
-export([get_turnover_limits/1]).
-export([check_limits/4]).
-export([hold_payment_limits/5]).
@ -72,64 +75,84 @@ check_limits_([T | TurnoverLimits], Context, Acc) ->
-spec hold_payment_limits([turnover_limit()], route(), pos_integer(), invoice(), payment()) -> ok.
hold_payment_limits(TurnoverLimits, Route, Iter, Invoice, Payment) ->
ChangeID = construct_payment_change_id(Route, Iter, Invoice, Payment),
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeID),
ChangeIDs = [construct_payment_change_id(Route, Iter, Invoice, Payment)],
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs),
Context = gen_limit_context(Invoice, Payment, Route),
hold(LimitChanges, get_latest_clock(), Context).
-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),
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs),
Context = gen_limit_refund_context(Invoice, Payment, Refund, Route),
hold(LimitChanges, get_latest_clock(), Context).
-spec commit_payment_limits([turnover_limit()], route(), pos_integer(), invoice(), payment(), cash() | undefined) -> ok.
commit_payment_limits(TurnoverLimits, Route, Iter, Invoice, Payment, CapturedCash) ->
ChangeID = construct_payment_change_id(Route, Iter, Invoice, Payment),
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeID),
ChangeIDs = [
construct_payment_change_id(Route, Iter, Invoice, Payment),
construct_payment_change_id(Route, Iter, Invoice, Payment, legacy)
],
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs),
Context = gen_limit_context(Invoice, Payment, Route, CapturedCash),
commit(LimitChanges, get_latest_clock(), Context).
-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),
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs),
Context = gen_limit_refund_context(Invoice, Payment, Refund, Route),
commit(LimitChanges, get_latest_clock(), Context).
-spec rollback_payment_limits([turnover_limit()], route(), pos_integer(), invoice(), payment()) -> ok.
rollback_payment_limits(TurnoverLimits, Route, Iter, Invoice, Payment) ->
ChangeID = construct_payment_change_id(Route, Iter, Invoice, Payment),
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeID),
ChangeIDs = [
construct_payment_change_id(Route, Iter, Invoice, Payment),
construct_payment_change_id(Route, Iter, Invoice, Payment, legacy)
],
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs),
Context = gen_limit_context(Invoice, Payment, Route),
rollback(LimitChanges, get_latest_clock(), Context).
-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),
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs),
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.
-spec hold([change_queue()], hg_limiter_client:clock(), hg_limiter_client:context()) -> ok.
hold(LimitChanges, Clock, Context) ->
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.
-spec commit([change_queue()], 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.
-spec rollback([change_queue()], 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) ->
process_changes(LimitChangesQueues, WithFun, Clock, Context) ->
lists:foreach(
fun(LimitChange) -> WithFun(LimitChange, Clock, Context) end,
LimitChanges
fun(LimitChangesQueue) ->
process_changes_try_wrap(LimitChangesQueue, WithFun, Clock, Context)
end,
LimitChangesQueues
).
process_changes_try_wrap([LimitChange], WithFun, Clock, Context) ->
WithFun(LimitChange, Clock, Context);
process_changes_try_wrap([LimitChange | OtherLimitChanges], WithFun, Clock, Context) ->
#limiter_LimitChange{change_id = ChangeID} = LimitChange,
try
WithFun(LimitChange, Clock, Context)
catch
%% Very specific error to crutch around
error:#base_InvalidRequest{errors = [<<"Posting plan not found: ", ChangeID/binary>>]} ->
process_changes_try_wrap(OtherLimitChanges, WithFun, Clock, Context)
end.
gen_limit_context(Invoice, Payment, Route) ->
gen_limit_context(Invoice, Payment, Route, undefined).
@ -166,17 +189,34 @@ gen_limit_refund_context(Invoice, Payment, Refund, Route) ->
}
}.
gen_limit_changes(Limits, ChangeID) ->
[
#limiter_LimitChange{
id = ID,
change_id = hg_utils:construct_complex_id([<<"limiter">>, ID, ChangeID]),
version = Version
}
|| #domain_TurnoverLimit{id = ID, domain_revision = Version} <- Limits
].
-spec gen_limit_changes([turnover_limit()], [binary()]) -> [change_queue()].
gen_limit_changes(Limits, ChangeIDs) ->
%% It produces lists like
%% [
%% [#limiter_LimitChange{...}, #limiter_LimitChange{...}],
%% [#limiter_LimitChange{...}],
%% ...
%% ]
[[gen_limit_change(Limit, ChangeID) || ChangeID <- ChangeIDs] || Limit <- Limits].
construct_payment_change_id(?route(ProviderRef, TerminalRef), Iter, Invoice, Payment) ->
gen_limit_change(#domain_TurnoverLimit{id = ID, domain_revision = Version}, ChangeID) ->
#limiter_LimitChange{
id = ID,
change_id = hg_utils:construct_complex_id([<<"limiter">>, ID, ChangeID]),
version = Version
}.
construct_payment_change_id(Route, Iter, Invoice, Payment) ->
construct_payment_change_id(Route, Iter, Invoice, Payment, normal).
construct_payment_change_id(?route(ProviderRef, TerminalRef), _Iter, Invoice, Payment, legacy) ->
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)
]);
construct_payment_change_id(?route(ProviderRef, TerminalRef), Iter, Invoice, Payment, normal) ->
hg_utils:construct_complex_id([
genlib:to_binary(get_provider_id(ProviderRef)),
genlib:to_binary(get_terminal_id(TerminalRef)),