TD-820: Fixes limits rollback for route candidates (#110)

* TD-820: Fixes limits rollback for route candidates

* Fixes limit-hold routes stash
This commit is contained in:
Aleksey Kashapov 2023-12-20 16:19:35 +03:00 committed by GitHub
parent f48b9607b6
commit 70ee54ae6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 7 deletions

View File

@ -1988,7 +1988,8 @@ produce_routing_events(Ctx = #{error := Error}, _Revision, St) when Error =/= un
produce_routing_events(Ctx, Revision, _St) ->
ok = log_route_choice_meta(Ctx, Revision),
Route = hg_route:to_payment_route(hg_routing_ctx:choosen_route(Ctx)),
Candidates = ordsets:from_list([hg_route:to_payment_route(R) || R <- hg_routing_ctx:candidates(Ctx)]),
Candidates =
ordsets:from_list([hg_route:to_payment_route(R) || R <- hg_routing_ctx:considered_candidates(Ctx)]),
[?route_changed(Route, Candidates)].
route_args(St) ->
@ -2475,9 +2476,10 @@ get_provider_terms(St, Revision) ->
VS1 = collect_validation_varset(get_party(Opts), get_shop(Opts), Payment, VS0),
hg_routing:get_payment_terms(Route, VS1, Revision).
filter_routes_with_limit_hold(Ctx, VS, Iter, St) ->
{_Routes, RejectedRoutes} = hold_limit_routes(hg_routing_ctx:candidates(Ctx), VS, Iter, St),
reject_routes(limit_misconfiguration, RejectedRoutes, Ctx).
filter_routes_with_limit_hold(Ctx0, VS, Iter, St) ->
{_Routes, RejectedRoutes} = hold_limit_routes(hg_routing_ctx:candidates(Ctx0), VS, Iter, St),
Ctx1 = reject_routes(limit_misconfiguration, RejectedRoutes, Ctx0),
hg_routing_ctx:stash_current_candidates(Ctx1).
filter_routes_by_limit_overflow(Ctx, VS, St) ->
{_Routes, RejectedRoutes} = get_limit_overflow_routes(hg_routing_ctx:candidates(Ctx), VS, St),
@ -3362,7 +3364,7 @@ get_limit_values(St) ->
Acc#{PaymentRoute => TurnoverLimitValues}
end,
#{},
hg_routing_ctx:candidates(Ctx)
hg_routing_ctx:considered_candidates(Ctx)
).
-spec get_limit_values(st(), opts()) -> route_limit_context().

View File

@ -275,7 +275,7 @@ init(EncodedParams, #{id := RecPaymentToolID}) ->
gather_routes(PaymentInstitution, VS, Revision, Ctx) ->
Predestination = recurrent_paytool,
RoutingCtx = hg_routing:gather_routes(Predestination, PaymentInstitution, VS, Revision, Ctx),
case {hg_routing_ctx:candidates(RoutingCtx), hg_routing_ctx:error(RoutingCtx)} of
case {hg_routing_ctx:considered_candidates(RoutingCtx), hg_routing_ctx:error(RoutingCtx)} of
{[], undefined} ->
throw({no_route_found, {unknown, hg_routing_ctx:rejected_routes(RoutingCtx)}});
{Routes, undefined} ->

View File

@ -11,6 +11,8 @@
-export([rejections/1]).
-export([candidates/1]).
-export([initial_candidates/1]).
-export([stash_current_candidates/1]).
-export([considered_candidates/1]).
-export([choosen_route/1]).
-export([process/2]).
-export([with_guard/1]).
@ -27,6 +29,7 @@
error := error() | undefined,
choosen_route := hg_route:t() | undefined,
choice_meta := hg_routing:route_choice_context() | undefined,
stashed_candidates => [hg_route:t()],
fail_rates => [hg_routing:fail_rated_route()]
}.
@ -102,14 +105,32 @@ rejected_routes(#{rejections := Rejections}) ->
{_, RejectedRoutes} = lists:unzip(maps:to_list(Rejections)),
lists:flatten(RejectedRoutes).
%% @doc List of currently considering candidates.
%% Route will be choosen among these.
-spec candidates(t()) -> [hg_route:t()].
candidates(#{candidates := Candidates}) ->
Candidates.
%% @doc Lists candidates provided at very start of routing context formation.
-spec initial_candidates(t()) -> [hg_route:t()].
initial_candidates(#{initial_candidates := InitialCandidates}) ->
InitialCandidates.
%% @doc Lists candidates (same as 'candidates/1') with only difference that list
%% includes previously considered candidates that were stashed to be
%% accounted for later.
%%
%% For __example__, it may consist of routes that were successfully staged
%% by limits accountant and thus stashed to be optionally rolled back
%% later.
-spec considered_candidates(t()) -> [hg_route:t()].
considered_candidates(Ctx) ->
maps:get(stashed_candidates, Ctx, candidates(Ctx)).
-spec stash_current_candidates(t()) -> t().
stash_current_candidates(Ctx) ->
Ctx#{stashed_candidates => candidates(Ctx)}.
-spec choosen_route(t()) -> hg_route:t() | undefined.
choosen_route(#{choosen_route := ChoosenRoute}) ->
ChoosenRoute.

View File

@ -928,4 +928,4 @@ maybe_set_risk_coverage(true, V) ->
{value, V}.
unwrap_routing_context(RoutingCtx) ->
{ok, {hg_routing_ctx:candidates(RoutingCtx), hg_routing_ctx:rejected_routes(RoutingCtx)}}.
{ok, {hg_routing_ctx:considered_candidates(RoutingCtx), hg_routing_ctx:rejected_routes(RoutingCtx)}}.