diff --git a/apps/capi/src/capi_cash_limits.erl b/apps/capi/src/capi_cash_limits.erl index b625f7f..d77154e 100644 --- a/apps/capi/src/capi_cash_limits.erl +++ b/apps/capi/src/capi_cash_limits.erl @@ -7,6 +7,7 @@ % - при отсутствии payment_methods ответ пустой, даже если лимит посчитан -include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -export([get_shop_limits/3]). -type processing_context() :: capi_handler:processing_context(). @@ -22,7 +23,13 @@ get_shop_limits(PartyID, ShopID, Context) -> ShopTerms = get_shop_terms(Shop#domain_ShopConfig.terms, Revision, Context), ShopMethods = extract_payment_methods(ShopTerms), ShopLimit = extract_shop_limit(ShopTerms, Currency), - TerminalRefs = get_payment_terminal_refs(Shop#domain_ShopConfig.payment_institution, Context), + TerminalRefs = + get_payment_terminal_refs( + Shop#domain_ShopConfig.payment_institution, + PartyID, + ShopID, + Context + ), TermLimit = aggregate_terminal_limits(TerminalRefs, Currency, Context), EffectiveLimit = intersect_optional(ShopLimit, TermLimit), Limits = lists:flatmap( @@ -68,43 +75,34 @@ extract_shop_limit(#domain_TermSet{payments = Payments}, Currency) -> PartialRefund = range_from_selector(PartialRefundSelector, Currency), pick_refund_limit(Payment, PartialRefund). -get_payment_terminal_refs(PiRef, Context) -> +get_payment_terminal_refs(PiRef, PartyID, ShopID, Context) -> case capi_domain:get_payment_institution(PiRef, Context) of {ok, #domain_PaymentInstitution{payment_routing_rules = Rules}} -> - lists:usort(collect_ruleset_terminals(Rules, Context)); + case compute_routing_ruleset(Rules, PartyID, ShopID, Context) of + {ok, #domain_RoutingRuleset{decisions = {candidates, Candidates}}} -> + lists:usort([C#domain_RoutingCandidate.terminal || C <- Candidates]); + _ -> + [] + end; _ -> [] end. -collect_ruleset_terminals(undefined, _Context) -> - []; -collect_ruleset_terminals(#domain_RoutingRules{policies = PoliciesRef}, Context) -> - collect_ruleset_terminals(PoliciesRef, Context, sets:new()). - -collect_ruleset_terminals(#domain_RoutingRulesetRef{} = Ref, Context, Seen) -> - case sets:is_element(Ref, Seen) of - true -> - []; - false -> - Seen1 = sets:add_element(Ref, Seen), - case capi_domain:get({routing_rules, Ref}, Context) of - {ok, #domain_RoutingRulesObject{data = Ruleset}} -> - collect_ruleset_terminals(Ruleset, Context, Seen1); - _ -> - [] - end - end; -collect_ruleset_terminals(#domain_RoutingRuleset{decisions = Decisions}, Context, Seen) -> - collect_terminals_from_decisions(Decisions, Context, Seen). - -collect_terminals_from_decisions({candidates, Candidates}, _Context, _Seen) -> - [C#domain_RoutingCandidate.terminal || C <- Candidates]; -collect_terminals_from_decisions({delegates, Delegates}, Context, Seen) -> - lists:flatmap( - fun(#domain_RoutingDelegate{ruleset = Ref}) -> - collect_ruleset_terminals(Ref, Context, Seen) - end, - Delegates +compute_routing_ruleset(undefined, _PartyID, _ShopID, _Context) -> + undefined; +compute_routing_ruleset(#domain_RoutingRules{policies = RulesetRef}, PartyID, ShopID, Context) -> + Revision = capi_domain:head(), + Varset = #payproc_Varset{ + party_ref = #domain_PartyConfigRef{id = PartyID}, + shop_id = ShopID + }, + #{party_client := Client, party_client_context := PartyClientContext} = Context, + party_client_thrift:compute_routing_ruleset( + RulesetRef, + Revision, + Varset, + Client, + PartyClientContext ). aggregate_terminal_limits([], _Currency, _Context) -> @@ -146,12 +144,11 @@ get_terminal_limit(TerminalRef, Currency, Context) -> get_and_check_terminal(TerminalRef, Context) -> case capi_domain:get({terminal, TerminalRef}, Context) of {ok, #domain_TerminalObject{data = #domain_Terminal{terms = Terms} = Terminal}} -> - #domain_ProvisionTermSet{payments = #domain_PaymentsProvisionTerms{cash_limit = CashLimit}} = Terms, - case CashLimit of - {decisions, _} -> - undefined; + case Terms of + #domain_ProvisionTermSet{payments = #domain_PaymentsProvisionTerms{cash_limit = {value, _}}} -> + {ok, Terminal}; _ -> - {ok, Terminal} + undefined end; _ -> undefined @@ -276,7 +273,10 @@ encode_bound(Amount) -> }. encode_payment_method(bank_card) -> - #{<<"method">> => <<"BankCard">>}; + #{ + <<"method">> => <<"BankCard">>, + <<"paymentSystems">> => [] + }; encode_payment_method(payment_terminal) -> #{<<"method">> => <<"PaymentTerminal">>}; encode_payment_method(digital_wallet) -> diff --git a/apps/capi/test/capi_base_api_token_tests_SUITE.erl b/apps/capi/test/capi_base_api_token_tests_SUITE.erl index b2ebcb4..b565983 100644 --- a/apps/capi/test/capi_base_api_token_tests_SUITE.erl +++ b/apps/capi/test/capi_base_api_token_tests_SUITE.erl @@ -64,7 +64,7 @@ get_shops_for_party_restricted_ok_test/1, get_shop_by_id_for_party_error_test/1, get_shops_for_party_error_test/1, - real_config_limits_test/1, + get_shop_limits_for_party_ok_test/1, create_webhook_ok_test/1, create_webhook_limit_exceeded_test/1, get_webhooks/1, @@ -144,7 +144,7 @@ groups() -> get_shops_for_party_ok_test, get_shops_for_party_restricted_ok_test, get_shops_for_party_error_test, - real_config_limits_test, + get_shop_limits_for_party_ok_test, create_payment_ok_test, create_payment_with_changed_cost_ok_test, @@ -1231,11 +1231,42 @@ get_shops_for_party_error_test(Config) -> capi_client_shops:get_shops_for_party(?config(context, Config), <<"WrongPartyID">>) ). --spec real_config_limits_test(config()) -> ok. -real_config_limits_test(Config) -> +-spec get_shop_limits_for_party_ok_test(config()) -> ok. +get_shop_limits_for_party_ok_test(Config) -> Context = ?config(context, Config), - {ok, [Result]} = capi_cash_limits:get_shop_limits(?KZT_PARTY_ID, ?KZT_SHOP_ID, Context), - ?assertEqual(#{<<"method">> => <<"BankCard">>}, maps:get(<<"paymentMethod">>, Result)), + TestRuleset = #domain_RoutingRuleset{ + name = <<"mock-ruleset">>, + description = <<"mocked for cash limits test">>, + decisions = + {candidates, [ + #domain_RoutingCandidate{ + allowed = {constant, true}, + terminal = #domain_TerminalRef{id = ?KZT_TERMINAL_15_ID} + }, + #domain_RoutingCandidate{ + allowed = {constant, true}, + terminal = #domain_TerminalRef{id = ?KZT_TERMINAL_16_ID} + } + ]} + }, + _ = capi_ct_helper:mock_services( + [ + {party_management, fun('ComputeRoutingRuleset', _) -> + {ok, TestRuleset} + end} + ], + Config + ), + _ = capi_ct_helper_bouncer:mock_assert_shop_op_ctx( + <<"GetShopCashLimitsForParty">>, + ?KZT_PARTY_ID, + ?KZT_SHOP_ID, + Config + ), + {ok, [Result]} = capi_client_shops:get_shop_cash_limits_for_party(Context, ?KZT_PARTY_ID, ?KZT_SHOP_ID), + PaymentMethod = maps:get(<<"paymentMethod">>, Result), + ?assertEqual(<<"BankCard">>, maps:get(<<"method">>, PaymentMethod)), + ?assertEqual([], maps:get(<<"paymentSystems">>, PaymentMethod)), ?assertEqual(<<"KZT">>, maps:get(<<"currency">>, Result)), ?assertEqual(#{<<"amount">> => 10000, <<"inclusive">> => true}, maps:get(<<"lowerBound">>, Result)), ?assertEqual(#{<<"amount">> => 120000000, <<"inclusive">> => true}, maps:get(<<"upperBound">>, Result)). diff --git a/apps/capi_client/src/capi_client_shops.erl b/apps/capi_client/src/capi_client_shops.erl index 449e967..a70c3c1 100644 --- a/apps/capi_client/src/capi_client_shops.erl +++ b/apps/capi_client/src/capi_client_shops.erl @@ -2,6 +2,7 @@ -export([get_shops_for_party/2]). -export([get_shop_by_id_for_party/3]). +-export([get_shop_cash_limits_for_party/3]). -export([suspend_shop_for_party/3]). -export([activate_shop_for_party/3]). @@ -30,6 +31,18 @@ get_shop_by_id_for_party(Context, PartyID, ShopID) -> Response = swag_client_shops_api:get_shop_by_id_for_party(Url, PreparedParams, Opts), capi_client_lib:handle_response(Response). +-spec get_shop_cash_limits_for_party(context(), binary(), binary()) -> {ok, term()} | {error, term()}. +get_shop_cash_limits_for_party(Context, PartyID, ShopID) -> + Params = #{ + binding => genlib_map:compact(#{ + <<"partyID">> => PartyID, + <<"shopID">> => ShopID + }) + }, + {Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params), + Response = swag_client_shops_api:get_shop_cash_limits_for_party(Url, PreparedParams, Opts), + capi_client_lib:handle_response(Response). + -spec suspend_shop_for_party(context(), binary(), binary()) -> ok | {error, term()}. suspend_shop_for_party(Context, PartyID, ShopID) -> Params = #{