diff --git a/apps/limiter/src/lim_body.erl b/apps/limiter/src/lim_body.erl index 4c500dc..c2be6f4 100644 --- a/apps/limiter/src/lim_body.erl +++ b/apps/limiter/src/lim_body.erl @@ -8,7 +8,7 @@ currency := currency() }. --type currency() :: lim_base_thrift:'CurrencySymbolicCode'(). +-type currency() :: lim_domain_thrift:'CurrencySymbolicCode'(). -type config() :: lim_config_machine:config(). -type body_type() :: full | partial. diff --git a/apps/limiter/src/lim_config_codec.erl b/apps/limiter/src/lim_config_codec.erl index b53e60d..13b25fa 100644 --- a/apps/limiter/src/lim_config_codec.erl +++ b/apps/limiter/src/lim_config_codec.erl @@ -85,16 +85,16 @@ marshal_behaviour(addition) -> marshal_time_range_type({calendar, CalendarType}) -> {calendar, marshal_calendar_time_range_type(CalendarType)}; marshal_time_range_type({interval, Amount}) -> - {interval, #time_range_TimeRangeTypeInterval{amount = Amount}}. + {interval, #limiter_time_range_TimeRangeTypeInterval{amount = Amount}}. marshal_calendar_time_range_type(day) -> - {day, #time_range_TimeRangeTypeCalendarDay{}}; + {day, #limiter_time_range_TimeRangeTypeCalendarDay{}}; marshal_calendar_time_range_type(week) -> - {week, #time_range_TimeRangeTypeCalendarWeek{}}; + {week, #limiter_time_range_TimeRangeTypeCalendarWeek{}}; marshal_calendar_time_range_type(month) -> - {month, #time_range_TimeRangeTypeCalendarMonth{}}; + {month, #limiter_time_range_TimeRangeTypeCalendarMonth{}}; marshal_calendar_time_range_type(year) -> - {year, #time_range_TimeRangeTypeCalendarYear{}}. + {year, #limiter_time_range_TimeRangeTypeCalendarYear{}}. marshal_context_type(payment_processing) -> {payment_processing, #limiter_config_LimitContextTypePaymentProcessing{}}. @@ -235,7 +235,7 @@ unmarshal_body_type_deprecated({cash, #limiter_config_LimitBodyTypeCash{currency unmarshal_time_range_type({calendar, CalendarType}) -> {calendar, unmarshal_calendar_time_range_type(CalendarType)}; -unmarshal_time_range_type({interval, #time_range_TimeRangeTypeInterval{amount = Amount}}) -> +unmarshal_time_range_type({interval, #limiter_time_range_TimeRangeTypeInterval{amount = Amount}}) -> {interval, Amount}. unmarshal_calendar_time_range_type({day, _}) -> @@ -308,7 +308,7 @@ unmarshal_created_w_deprecated_body_type_test_() -> created_at = lim_time:to_rfc3339(Now), started_at = <<"2000-01-01T00:00:00Z">>, shard_size = 42, - time_range_type = {calendar, {day, #time_range_TimeRangeTypeCalendarDay{}}}, + time_range_type = {calendar, {day, #limiter_time_range_TimeRangeTypeCalendarDay{}}}, context_type = {payment_processing, #limiter_config_LimitContextTypePaymentProcessing{}}, body_type_deprecated = {cash, #limiter_config_LimitBodyTypeCash{currency = <<"☭☭☭"/utf8>>}} }, diff --git a/apps/limiter/src/lim_config_machine.erl b/apps/limiter/src/lim_config_machine.erl index 48a8ccf..81b3086 100644 --- a/apps/limiter/src/lim_config_machine.erl +++ b/apps/limiter/src/lim_config_machine.erl @@ -38,7 +38,7 @@ -type limit_type() :: {turnover, lim_turnover_metric:t()}. -type limit_scope() :: ordsets:ordset(limit_scope_type()). --type limit_scope_type() :: party | shop | wallet | identity. +-type limit_scope_type() :: party | shop | wallet | identity | payment_tool. -type shard_size() :: pos_integer(). -type shard_id() :: binary(). -type prefix() :: binary(). @@ -560,11 +560,27 @@ append_context_bits(shop, Bits) -> % Also we need to preserve order between party / shop to ensure backwards compatibility. {order, 1, {from, payment_processing, owner_id, invoice}}, {order, 2, {from, payment_processing, shop_id, invoice}} - ]). + ]); +append_context_bits(payment_tool, Bits) -> + ordsets:add_element( + {from, payment_processing, payer, invoice_payment}, + Bits + ). -spec extract_context_bit(context_bit(), lim_context()) -> {ok, binary()}. extract_context_bit({order, _, Bit}, LimitContext) -> extract_context_bit(Bit, LimitContext); +extract_context_bit({from, payment_processing, payer, Op}, LimitContext) -> + {ok, {_, PayerData}} = lim_context:get_from_context(payment_processing, payer, Op, LimitContext), + #{payment_tool := {PaymentToolType, PaymentToolData}} = PayerData, + case PaymentToolType of + bank_card -> + Token = maps:get(token, PaymentToolData), + ExpData = maps:get(exp_date, PaymentToolData, <<>>), + {ok, <>}; + _ -> + {error, {unsupported_payment_tool_type, PaymentToolType}} + end; extract_context_bit({from, ContextType, ValueName, Op}, LimitContext) -> lim_context:get_from_context(ContextType, ValueName, Op, LimitContext). diff --git a/apps/limiter/src/lim_configurator.erl b/apps/limiter/src/lim_configurator.erl index 93c6502..b5b09cd 100644 --- a/apps/limiter/src/lim_configurator.erl +++ b/apps/limiter/src/lim_configurator.erl @@ -23,7 +23,7 @@ handle_function(Fn, Args, WoodyCtx, Opts) -> -spec handle_function_(woody:func(), woody:args(), lim_context:t(), woody:options()) -> {ok, woody:result()}. handle_function_( 'CreateLegacy', - {#limiter_cfg_LimitCreateParams{ + {#limiter_configurator_LimitCreateParams{ id = ID, name = Name, description = Description, @@ -51,7 +51,7 @@ handle_function_( {error, {name, notfound}} -> woody_error:raise( business, - #limiter_cfg_LimitConfigNameNotFound{} + #limiter_configurator_LimitConfigNameNotFound{} ) end; handle_function_('Create', {Params}, LimitContext, _Opts) -> @@ -70,7 +70,7 @@ handle_function_('Get', {LimitID}, LimitContext, _Opts) -> {ok, LimitConfig} -> {ok, lim_config_codec:marshal_config(LimitConfig)}; {error, notfound} -> - woody_error:raise(business, #limiter_cfg_LimitConfigNotFound{}) + woody_error:raise(business, #limiter_configurator_LimitConfigNotFound{}) end. map_type({turnover, _}) -> @@ -78,7 +78,7 @@ map_type({turnover, _}) -> map_type(_) -> woody_error:raise( business, - #limiter_base_InvalidRequest{errors = [<<"Config type not found.">>]} + #'InvalidRequest'{errors = [<<"Config type not found.">>]} ). mk_limit_config(<<"ShopDayTurnover">>) -> diff --git a/apps/limiter/src/lim_context.erl b/apps/limiter/src/lim_context.erl index 90e2baf..f2bca88 100644 --- a/apps/limiter/src/lim_context.erl +++ b/apps/limiter/src/lim_context.erl @@ -18,6 +18,8 @@ -type thrift_context() :: lim_limiter_thrift:'LimitContext'(). -type clock() :: lim_limiter_thrift:'Clock'(). -type id() :: binary(). +-type token() :: binary(). +-type exp_date() :: binary(). -type cash() :: lim_body:cash(). -type t() :: #{ @@ -52,8 +54,8 @@ shop_id => id(), cost => cash(), created_at => timestamp(), - effective_adjustment => payment_processing_adjustment(), - effective_payment => payment_processing_payment() + adjustment => payment_processing_adjustment(), + payment => payment_processing_payment() }. -type payment_processing_adjustment() :: #{ @@ -68,10 +70,26 @@ capture_cost => cash(), created_at => timestamp(), flow => instant | hold, - payer => payment_resource | customer | recurrent, - effective_adjustment => payment_processing_payment_adjustment(), - effective_refund => payment_processing_payment_refund(), - effective_chargeback => payment_processing_payment_chargeback() + payer => payment_processing_payer(), + adjustment => payment_processing_payment_adjustment(), + refund => payment_processing_payment_refund(), + chargeback => payment_processing_payment_chargeback() +}. + +-type payment_processing_payer() :: + {payment_resource, payment_processing_payer_data()} + | {customer, payment_processing_payer_data()} + | {recurrent, payment_processing_payer_data()}. + +-type payment_processing_payer_data() :: #{ + payment_tool => payment_processing_payment_tool() +}. + +-type payment_processing_payment_tool() :: {bank_card, payment_processing_bank_card()}. + +-type payment_processing_bank_card() :: #{ + token => token(), + exp_date => exp_date() }. -type payment_processing_payment_adjustment() :: #{ @@ -93,6 +111,7 @@ }. -export_type([t/0]). +-export_type([context/0]). -export_type([context_type/0]). -export_type([context_operation/0]). @@ -156,23 +175,23 @@ get_from_context(_, _ValueName, _Op, _LimContext) -> get_payment_processing_operation_context(invoice, #{invoice := Invoice}) -> {ok, Invoice}; -get_payment_processing_operation_context(invoice_adjustment, #{invoice := #{effective_adjustment := Adjustment}}) -> +get_payment_processing_operation_context(invoice_adjustment, #{invoice := #{adjustment := Adjustment}}) -> {ok, Adjustment}; -get_payment_processing_operation_context(invoice_payment, #{invoice := #{effective_payment := Payment}}) -> +get_payment_processing_operation_context(invoice_payment, #{invoice := #{payment := Payment}}) -> {ok, Payment}; get_payment_processing_operation_context( invoice_payment_adjustment, - #{invoice := #{effective_payment := #{effective_adjustment := Adjustment}}} + #{invoice := #{payment := #{adjustment := Adjustment}}} ) -> {ok, Adjustment}; get_payment_processing_operation_context( invoice_payment_refund, - #{invoice := #{effective_payment := #{effective_refund := Refund}}} + #{invoice := #{payment := #{refund := Refund}}} ) -> {ok, Refund}; get_payment_processing_operation_context( invoice_payment_chargeback, - #{invoice := #{effective_payment := #{effective_chargeback := Chargeback}}} + #{invoice := #{payment := #{chargeback := Chargeback}}} ) -> {ok, Chargeback}; get_payment_processing_operation_context(_, _) -> @@ -180,126 +199,13 @@ get_payment_processing_operation_context(_, _) -> %% -unmarshal_context(#limiter_context_LimitContext{payment_processing = PaymentProcessing}) -> - #{payment_processing => unmarshal_payment_processing_context(PaymentProcessing)}; +unmarshal_context(#limiter_context_LimitContext{limiter_payment_processing = PaymentProcessing}) when + PaymentProcessing =/= undefined +-> + #{payment_processing => lim_limiter_context:unmarshal(PaymentProcessing)}; +unmarshal_context(#limiter_context_LimitContext{payment_processing = PaymentProcessing}) when + PaymentProcessing =/= undefined +-> + #{payment_processing => lim_payproc_context:unmarshal(PaymentProcessing)}; unmarshal_context(_) -> #{}. - -unmarshal_payment_processing_context(#limiter_context_ContextPaymentProcessing{ - op = {Operation, _}, - invoice = Invoice -}) -> - genlib_map:compact(#{ - op => Operation, - invoice => maybe_unmarshal(Invoice, fun unmarshal_payment_processing_invoice/1) - }). - -unmarshal_payment_processing_invoice(#limiter_context_Invoice{ - id = ID, - owner_id = OwnerID, - shop_id = ShopID, - cost = Cost, - created_at = CreatedAt, - effective_payment = EffectivePayment, - effective_adjustment = EffectiveAdjustment -}) -> - genlib_map:compact(#{ - id => maybe_unmarshal(ID, fun unmarshal_string/1), - owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1), - shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1), - cost => maybe_unmarshal(Cost, fun unmarshal_cash/1), - created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1), - effective_adjustment => maybe_unmarshal( - EffectiveAdjustment, - fun unmarshal_payment_processing_invoice_adjustment/1 - ), - effective_payment => maybe_unmarshal(EffectivePayment, fun unmarshal_payment_processing_invoice_payment/1) - }). - -unmarshal_payment_processing_invoice_adjustment(#limiter_context_InvoiceAdjustment{id = ID}) -> - genlib_map:compact(#{ - id => maybe_unmarshal(ID, fun unmarshal_string/1) - }). - -unmarshal_payment_processing_invoice_payment(#limiter_context_InvoicePayment{ - id = ID, - owner_id = OwnerID, - shop_id = ShopID, - cost = Cost, - capture_cost = CaptureCost, - created_at = CreatedAt, - flow = Flow, - payer = Payer, - effective_adjustment = EffectiveAdjustment, - effective_refund = EffectiveRefund, - effective_chargeback = EffectiveChargeback -}) -> - genlib_map:compact(#{ - id => maybe_unmarshal(ID, fun unmarshal_string/1), - owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1), - shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1), - cost => maybe_unmarshal(Cost, fun unmarshal_cash/1), - capture_cost => maybe_unmarshal(CaptureCost, fun unmarshal_cash/1), - created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1), - flow => maybe_unmarshal(Flow, fun unmarshal_payment_processing_invoice_payment_flow/1), - payer => maybe_unmarshal(Payer, fun unmarshal_payment_processing_invoice_payment_payer/1), - effective_adjustment => maybe_unmarshal( - EffectiveAdjustment, - fun unmarshal_payment_processing_invoice_payment_adjustment/1 - ), - effective_refund => maybe_unmarshal(EffectiveRefund, fun unmarshal_payment_processing_invoice_payment_refund/1), - effective_chargeback => maybe_unmarshal( - EffectiveChargeback, - fun unmarshal_payment_processing_invoice_payment_chargeback/1 - ) - }). - -unmarshal_payment_processing_invoice_payment_flow({Flow, _}) -> - Flow. - -unmarshal_payment_processing_invoice_payment_payer({Payer, _}) -> - Payer. - -unmarshal_payment_processing_invoice_payment_adjustment(#limiter_context_InvoicePaymentAdjustment{ - id = ID, - created_at = CreatedAt -}) -> - genlib_map:compact(#{ - id => maybe_unmarshal(ID, fun unmarshal_string/1), - created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1) - }). - -unmarshal_payment_processing_invoice_payment_refund(#limiter_context_InvoicePaymentRefund{ - id = ID, - cost = Cost, - created_at = CreatedAt -}) -> - genlib_map:compact(#{ - id => maybe_unmarshal(ID, fun unmarshal_string/1), - cost => maybe_unmarshal(Cost, fun unmarshal_cash/1), - created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1) - }). - -unmarshal_payment_processing_invoice_payment_chargeback(#limiter_context_InvoicePaymentChargeback{ - id = ID, - levy = Levy, - body = Body, - created_at = CreatedAt -}) -> - genlib_map:compact(#{ - id => maybe_unmarshal(ID, fun unmarshal_string/1), - levy => maybe_unmarshal(Levy, fun unmarshal_cash/1), - body => maybe_unmarshal(Body, fun unmarshal_cash/1), - created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1) - }). - -unmarshal_cash(#limiter_base_Cash{amount = Amount, currency = #limiter_base_CurrencyRef{symbolic_code = Currency}}) -> - #{amount => Amount, currency => Currency}. - -unmarshal_string(Value) -> - Value. - -maybe_unmarshal(undefined, _) -> - undefined; -maybe_unmarshal(Value, UnmarshalFun) -> - UnmarshalFun(Value). diff --git a/apps/limiter/src/lim_handler.erl b/apps/limiter/src/lim_handler.erl index 8a6b4f1..6e0d7b9 100644 --- a/apps/limiter/src/lim_handler.erl +++ b/apps/limiter/src/lim_handler.erl @@ -84,7 +84,7 @@ handle_get_error(Error) -> -spec handle_hold_error(_) -> no_return(). handle_hold_error({_, {invalid_request, Errors}}) -> - woody_error:raise(business, #limiter_base_InvalidRequest{errors = Errors}); + woody_error:raise(business, #'InvalidRequest'{errors = Errors}); handle_hold_error(Error) -> handle_default_error(Error). @@ -92,13 +92,13 @@ handle_hold_error(Error) -> handle_commit_error({_, {forbidden_operation_amount, Error}}) -> handle_forbidden_operation_amount_error(Error); handle_commit_error({_, {invalid_request, Errors}}) -> - woody_error:raise(business, #limiter_base_InvalidRequest{errors = Errors}); + woody_error:raise(business, #'InvalidRequest'{errors = Errors}); handle_commit_error(Error) -> handle_default_error(Error). -spec handle_rollback_error(_) -> no_return(). handle_rollback_error({_, {invalid_request, Errors}}) -> - woody_error:raise(business, #limiter_base_InvalidRequest{errors = Errors}); + woody_error:raise(business, #'InvalidRequest'{errors = Errors}); handle_rollback_error(Error) -> handle_default_error(Error). diff --git a/apps/limiter/src/lim_limiter_context.erl b/apps/limiter/src/lim_limiter_context.erl new file mode 100644 index 0000000..9ffbcb8 --- /dev/null +++ b/apps/limiter/src/lim_limiter_context.erl @@ -0,0 +1,129 @@ +-module(lim_limiter_context). + +-include_lib("limiter_proto/include/lim_limiter_context_thrift.hrl"). + +-export([unmarshal/1]). + +-type thrift_context() :: lim_limiter_context_thrift:'ContextPaymentProcessing'(). + +%% + +-spec unmarshal(thrift_context()) -> lim_context:context(). +unmarshal(#limiter_context_ContextPaymentProcessing{ + op = {Operation, _}, + invoice = Invoice +}) -> + genlib_map:compact(#{ + op => Operation, + invoice => maybe_unmarshal(Invoice, fun unmarshal_payment_processing_invoice/1) + }). + +unmarshal_payment_processing_invoice(#limiter_context_Invoice{ + id = ID, + owner_id = OwnerID, + shop_id = ShopID, + cost = Cost, + created_at = CreatedAt, + effective_payment = Payment, + effective_adjustment = Adjustment +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1), + shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1), + cost => maybe_unmarshal(Cost, fun unmarshal_cash/1), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1), + adjustment => maybe_unmarshal( + Adjustment, + fun unmarshal_payment_processing_invoice_adjustment/1 + ), + payment => maybe_unmarshal(Payment, fun unmarshal_payment_processing_invoice_payment/1) + }). + +unmarshal_payment_processing_invoice_adjustment(#limiter_context_InvoiceAdjustment{id = ID}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1) + }). + +unmarshal_payment_processing_invoice_payment(#limiter_context_InvoicePayment{ + id = ID, + owner_id = OwnerID, + shop_id = ShopID, + cost = Cost, + capture_cost = CaptureCost, + created_at = CreatedAt, + flow = Flow, + payer = Payer, + effective_adjustment = Adjustment, + effective_refund = EffectiveRefund, + effective_chargeback = EffectiveChargeback +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1), + shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1), + cost => maybe_unmarshal(Cost, fun unmarshal_cash/1), + capture_cost => maybe_unmarshal(CaptureCost, fun unmarshal_cash/1), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1), + flow => maybe_unmarshal(Flow, fun unmarshal_payment_processing_invoice_payment_flow/1), + payer => maybe_unmarshal(Payer, fun unmarshal_payment_processing_invoice_payment_payer/1), + adjustment => maybe_unmarshal( + Adjustment, + fun unmarshal_payment_processing_invoice_payment_adjustment/1 + ), + refund => maybe_unmarshal(EffectiveRefund, fun unmarshal_payment_processing_invoice_payment_refund/1), + chargeback => maybe_unmarshal( + EffectiveChargeback, + fun unmarshal_payment_processing_invoice_payment_chargeback/1 + ) + }). + +unmarshal_payment_processing_invoice_payment_flow({Flow, _}) -> + Flow. + +unmarshal_payment_processing_invoice_payment_payer({Payer, _}) -> + {Payer, #{}}. + +unmarshal_payment_processing_invoice_payment_adjustment(#limiter_context_InvoicePaymentAdjustment{ + id = ID, + created_at = CreatedAt +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1) + }). + +unmarshal_payment_processing_invoice_payment_refund(#limiter_context_InvoicePaymentRefund{ + id = ID, + cost = Cost, + created_at = CreatedAt +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + cost => maybe_unmarshal(Cost, fun unmarshal_cash/1), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1) + }). + +unmarshal_payment_processing_invoice_payment_chargeback(#limiter_context_InvoicePaymentChargeback{ + id = ID, + levy = Levy, + body = Body, + created_at = CreatedAt +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + levy => maybe_unmarshal(Levy, fun unmarshal_cash/1), + body => maybe_unmarshal(Body, fun unmarshal_cash/1), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1) + }). + +unmarshal_cash(#domain_Cash{amount = Amount, currency = #domain_CurrencyRef{symbolic_code = Currency}}) -> + #{amount => Amount, currency => Currency}. + +unmarshal_string(Value) -> + Value. + +maybe_unmarshal(undefined, _) -> + undefined; +maybe_unmarshal(Value, UnmarshalFun) -> + UnmarshalFun(Value). diff --git a/apps/limiter/src/lim_payproc_context.erl b/apps/limiter/src/lim_payproc_context.erl new file mode 100644 index 0000000..18cb257 --- /dev/null +++ b/apps/limiter/src/lim_payproc_context.erl @@ -0,0 +1,213 @@ +-module(lim_payproc_context). + +-include_lib("limiter_proto/include/lim_limiter_payproc_context_thrift.hrl"). + +-export([unmarshal/1]). + +-type thrift_context() :: lim_limiter_payproc_context_thrift:'Context'(). + +%% + +-spec unmarshal(thrift_context()) -> lim_context:context(). +unmarshal(#limiter_context_payproc_Context{ + op = {Operation, _}, + invoice = Invoice +}) -> + genlib_map:compact(#{ + op => Operation, + invoice => maybe_unmarshal(Invoice, fun unmarshal_payment_processing_invoice/1) + }). + +unmarshal_payment_processing_invoice(#limiter_context_payproc_Invoice{ + invoice = #domain_Invoice{ + id = ID, + owner_id = OwnerID, + shop_id = ShopID, + cost = Cost, + created_at = CreatedAt + }, + payment = Payment, + adjustment = Adjustment +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1), + shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1), + cost => maybe_unmarshal(Cost, fun unmarshal_cash/1), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1), + adjustment => maybe_unmarshal( + Adjustment, + fun unmarshal_payment_processing_invoice_adjustment/1 + ), + payment => maybe_unmarshal(Payment, fun unmarshal_payment_processing_invoice_payment/1) + }). + +unmarshal_payment_processing_invoice_adjustment(#domain_InvoiceAdjustment{id = ID}) -> + #{id => unmarshal_string(ID)}. + +unmarshal_payment_processing_invoice_payment(#limiter_context_payproc_InvoicePayment{ + payment = #domain_InvoicePayment{ + id = ID, + owner_id = OwnerID, + shop_id = ShopID, + cost = Cost, + created_at = CreatedAt, + flow = Flow, + status = Status, + payer = Payer + }, + adjustment = Adjustment, + refund = EffectiveRefund, + chargeback = EffectiveChargeback +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1), + shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1), + cost => maybe_unmarshal(Cost, fun unmarshal_cash/1), + capture_cost => get_capture_cost_from_status(Status), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1), + flow => maybe_unmarshal(Flow, fun unmarshal_payment_processing_invoice_payment_flow/1), + payer => maybe_unmarshal(Payer, fun unmarshal_payment_processing_invoice_payment_payer/1), + adjustment => maybe_unmarshal( + Adjustment, + fun unmarshal_payment_processing_invoice_payment_adjustment/1 + ), + refund => maybe_unmarshal(EffectiveRefund, fun unmarshal_payment_processing_invoice_payment_refund/1), + chargeback => maybe_unmarshal( + EffectiveChargeback, + fun unmarshal_payment_processing_invoice_payment_chargeback/1 + ) + }). + +get_capture_cost_from_status({captured, #domain_InvoicePaymentCaptured{cost = Cost}}) -> + maybe_unmarshal(Cost, fun unmarshal_cash/1); +get_capture_cost_from_status(_) -> + undefined. + +unmarshal_payment_processing_invoice_payment_flow({Flow, _}) -> + Flow. + +unmarshal_payment_processing_invoice_payment_payer({Payer, Data}) -> + {Payer, unmarshal_payment_processing_invoice_payment_payer_data(Data)}. + +unmarshal_payment_processing_invoice_payment_payer_data(#domain_PaymentResourcePayer{ + resource = #domain_DisposablePaymentResource{payment_tool = PaymentTool} +}) -> + genlib_map:compact(#{ + payment_tool => maybe_unmarshal(PaymentTool, fun unmarshal_payment_processing_payment_tool/1) + }); +unmarshal_payment_processing_invoice_payment_payer_data(#domain_CustomerPayer{payment_tool = PaymentTool}) -> + genlib_map:compact(#{ + payment_tool => maybe_unmarshal(PaymentTool, fun unmarshal_payment_processing_payment_tool/1) + }); +unmarshal_payment_processing_invoice_payment_payer_data(#domain_RecurrentPayer{payment_tool = PaymentTool}) -> + genlib_map:compact(#{ + payment_tool => maybe_unmarshal(PaymentTool, fun unmarshal_payment_processing_payment_tool/1) + }). + +unmarshal_payment_processing_payment_tool({bank_card, #domain_BankCard{token = Token, exp_date = ExpDate}}) -> + {bank_card, #{ + token => Token, + exp_date => maybe_unmarshal(ExpDate, fun unmarshal_payment_processing_bank_card_exp_data/1) + }}; +unmarshal_payment_processing_payment_tool(_) -> + undefined. + +unmarshal_payment_processing_bank_card_exp_data(#domain_BankCardExpDate{month = Month, year = Year}) -> + BinaryMonth = integer_to_binary(Month), + BinaryYear = integer_to_binary(Year), + <>. + +unmarshal_payment_processing_invoice_payment_adjustment(#domain_InvoicePaymentAdjustment{ + id = ID, + created_at = CreatedAt +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1) + }). + +unmarshal_payment_processing_invoice_payment_refund(#domain_InvoicePaymentRefund{ + id = ID, + cash = Cost, + created_at = CreatedAt +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + cost => maybe_unmarshal(Cost, fun unmarshal_cash/1), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1) + }). + +unmarshal_payment_processing_invoice_payment_chargeback(#domain_InvoicePaymentChargeback{ + id = ID, + levy = Levy, + body = Body, + created_at = CreatedAt +}) -> + genlib_map:compact(#{ + id => maybe_unmarshal(ID, fun unmarshal_string/1), + levy => maybe_unmarshal(Levy, fun unmarshal_cash/1), + body => maybe_unmarshal(Body, fun unmarshal_cash/1), + created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1) + }). + +unmarshal_cash(#domain_Cash{amount = Amount, currency = #domain_CurrencyRef{symbolic_code = Currency}}) -> + #{amount => Amount, currency => Currency}. + +unmarshal_string(Value) -> + Value. + +maybe_unmarshal(undefined, _) -> + undefined; +maybe_unmarshal(Value, UnmarshalFun) -> + UnmarshalFun(Value). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +-spec test() -> _. + +-spec marshal_unmarshal_created_test() -> _. +marshal_unmarshal_created_test() -> + ExpDate = #domain_BankCardExpDate{month = 2, year = 2022}, + PaymentTool = + {bank_card, #domain_BankCard{ + token = <<"Token">>, + bin = <<"bin">>, + exp_date = ExpDate, + last_digits = <<"1234">> + }}, + Data0 = #domain_PaymentResourcePayer{ + resource = #domain_DisposablePaymentResource{payment_tool = PaymentTool}, + contact_info = #domain_ContactInfo{} + }, + #{payment_tool := _} = unmarshal_payment_processing_invoice_payment_payer_data(Data0), + Data1 = #domain_CustomerPayer{ + customer_id = <<"customer_id">>, + customer_binding_id = <<"customer_binding_id">>, + rec_payment_tool_id = <<"rec_payment_tool_id">>, + payment_tool = PaymentTool, + contact_info = #domain_ContactInfo{} + }, + #{payment_tool := _} = unmarshal_payment_processing_invoice_payment_payer_data(Data1), + Data2 = #domain_RecurrentPayer{ + payment_tool = PaymentTool, + recurrent_parent = #domain_RecurrentParentPayment{ + invoice_id = <<"invoice_id">>, + payment_id = <<"payment_id">> + }, + contact_info = #domain_ContactInfo{} + }, + #{payment_tool := _} = unmarshal_payment_processing_invoice_payment_payer_data(Data2), + Data3 = #domain_RecurrentPayer{ + payment_tool = {payment_terminal, #domain_PaymentTerminal{}}, + recurrent_parent = #domain_RecurrentParentPayment{ + invoice_id = <<"invoice_id">>, + payment_id = <<"payment_id">> + }, + contact_info = #domain_ContactInfo{} + }, + #{} = unmarshal_payment_processing_invoice_payment_payer_data(Data3). + +-endif. diff --git a/apps/limiter/src/lim_range_codec.erl b/apps/limiter/src/lim_range_codec.erl index 7767f69..8e854bd 100644 --- a/apps/limiter/src/lim_range_codec.erl +++ b/apps/limiter/src/lim_range_codec.erl @@ -48,7 +48,7 @@ marshal(time_range, #{ account_id_from := AccountIDFrom, account_id_to := AccountIDTo }) -> - #time_range_TimeRange{ + #limiter_time_range_TimeRange{ upper = Upper, lower = Lower, account_id_from = AccountIDFrom, @@ -57,15 +57,15 @@ marshal(time_range, #{ marshal(time_range_type, {calendar, SubType}) -> {calendar, marshal(time_range_sub_type, SubType)}; marshal(time_range_type, {interval, Interval}) -> - {interval, #time_range_TimeRangeTypeInterval{amount = Interval}}; + {interval, #limiter_time_range_TimeRangeTypeInterval{amount = Interval}}; marshal(time_range_sub_type, year) -> - {year, #time_range_TimeRangeTypeCalendarYear{}}; + {year, #limiter_time_range_TimeRangeTypeCalendarYear{}}; marshal(time_range_sub_type, month) -> - {month, #time_range_TimeRangeTypeCalendarMonth{}}; + {month, #limiter_time_range_TimeRangeTypeCalendarMonth{}}; marshal(time_range_sub_type, week) -> - {week, #time_range_TimeRangeTypeCalendarWeek{}}; + {week, #limiter_time_range_TimeRangeTypeCalendarWeek{}}; marshal(time_range_sub_type, day) -> - {day, #time_range_TimeRangeTypeCalendarDay{}}; + {day, #limiter_time_range_TimeRangeTypeCalendarDay{}}; marshal(timestamp, {DateTime, USec}) -> DateTimeinSeconds = genlib_time:daytime_to_unixtime(DateTime), {TimeinUnit, Unit} = @@ -99,7 +99,7 @@ unmarshal(range, #limiter_range_LimitRange{ created_at => CreatedAt, currency => Currency }); -unmarshal(time_range, #time_range_TimeRange{ +unmarshal(time_range, #limiter_time_range_TimeRange{ upper = Upper, lower = Lower, account_id_from = AccountIDFrom, @@ -113,7 +113,7 @@ unmarshal(time_range, #time_range_TimeRange{ }; unmarshal(time_range_type, {calendar, SubType}) -> {calendar, unmarshal(time_range_sub_type, SubType)}; -unmarshal(time_range_type, {interval, #time_range_TimeRangeTypeInterval{amount = Interval}}) -> +unmarshal(time_range_type, {interval, #limiter_time_range_TimeRangeTypeInterval{amount = Interval}}) -> {interval, Interval}; unmarshal(time_range_sub_type, {year, _}) -> year; diff --git a/apps/limiter/src/lim_turnover_metric.erl b/apps/limiter/src/lim_turnover_metric.erl index 6582bda..cc99c6f 100644 --- a/apps/limiter/src/lim_turnover_metric.erl +++ b/apps/limiter/src/lim_turnover_metric.erl @@ -3,7 +3,7 @@ -export([compute/4]). -type amount() :: lim_body:amount(). --type currency() :: lim_base_thrift:'CurrencySymbolicCode'(). +-type currency() :: lim_domain_thrift:'CurrencySymbolicCode'(). -type stage() :: hold | commit. -type t() :: number | {amount, currency()}. diff --git a/apps/limiter/test/lim_configurator_SUITE.erl b/apps/limiter/test/lim_configurator_SUITE.erl index 5571c4d..61e8f64 100644 --- a/apps/limiter/test/lim_configurator_SUITE.erl +++ b/apps/limiter/test/lim_configurator_SUITE.erl @@ -81,7 +81,7 @@ legacy_create_config(C) -> Client = lim_client:new(), ID = ?config(limit_id, C), Description = genlib:unique(), - Params = #limiter_cfg_LimitCreateParams{ + Params = #limiter_configurator_LimitCreateParams{ id = ID, name = <<"GlobalMonthTurnover">>, description = Description, @@ -150,7 +150,7 @@ get_config(C) -> prepare_environment(ID, LimitName, _C) -> Client = lim_client:new(), - Params = #limiter_cfg_LimitCreateParams{ + Params = #limiter_configurator_LimitCreateParams{ id = ID, name = LimitName, description = <<"description">>, diff --git a/apps/limiter/test/lim_ct_helper.hrl b/apps/limiter/test/lim_ct_helper.hrl index 70f0e00..57bbc3e 100644 --- a/apps/limiter/test/lim_ct_helper.hrl +++ b/apps/limiter/test/lim_ct_helper.hrl @@ -4,11 +4,13 @@ -include_lib("limiter_proto/include/lim_configurator_thrift.hrl"). -define(currency, <<"RUB">>). +-define(string, <<"STRING">>). +-define(timestamp, <<"2000-01-01T00:00:00Z">>). -define(cash(Amount), ?cash(Amount, ?currency)). --define(cash(Amount, Currency), #limiter_base_Cash{ +-define(cash(Amount, Currency), #domain_Cash{ amount = Amount, - currency = #limiter_base_CurrencyRef{symbolic_code = Currency} + currency = #domain_CurrencyRef{symbolic_code = Currency} }). -define(scope(Types), {multi, ordsets:from_list(Types)}). @@ -16,6 +18,7 @@ -define(scope_party(), {party, #limiter_config_LimitScopeEmptyDetails{}}). -define(scope_shop(), {shop, #limiter_config_LimitScopeEmptyDetails{}}). +-define(scope_payment_tool(), {payment_tool, #limiter_config_LimitScopeEmptyDetails{}}). -define(lim_type_turnover(), ?lim_type_turnover(?turnover_metric_number())). -define(lim_type_turnover(Metric), @@ -29,13 +32,16 @@ ). -define(time_range_day(), - {calendar, {day, #time_range_TimeRangeTypeCalendarDay{}}} + {calendar, {day, #limiter_time_range_TimeRangeTypeCalendarDay{}}} ). -define(time_range_week(), - {calendar, {week, #time_range_TimeRangeTypeCalendarWeek{}}} + {calendar, {week, #limiter_time_range_TimeRangeTypeCalendarWeek{}}} ). -define(time_range_month(), - {calendar, {month, #time_range_TimeRangeTypeCalendarMonth{}}} + {calendar, {month, #limiter_time_range_TimeRangeTypeCalendarMonth{}}} +). +-define(time_range_year(), + {calendar, {year, #limiter_time_range_TimeRangeTypeCalendarYear{}}} ). -define(op_behaviour(), ?op_behaviour(?op_addition())). @@ -54,7 +60,7 @@ -define(op_invoice_payment(), {invoice_payment, #limiter_context_PaymentProcessingOperationInvoicePayment{}}). -define(ctx_invoice(Cost), #limiter_context_LimitContext{ - payment_processing = #limiter_context_ContextPaymentProcessing{ + limiter_payment_processing = #limiter_context_ContextPaymentProcessing{ op = ?op_invoice(), invoice = #limiter_context_Invoice{ created_at = <<"2000-01-01T00:00:00Z">>, @@ -66,7 +72,7 @@ -define(ctx_invoice_payment(Cost, CaptureCost), ?ctx_invoice_payment(undefined, undefined, Cost, CaptureCost)). -define(ctx_invoice_payment(OwnerID, ShopID, Cost, CaptureCost), #limiter_context_LimitContext{ - payment_processing = #limiter_context_ContextPaymentProcessing{ + limiter_payment_processing = #limiter_context_ContextPaymentProcessing{ op = ?op_invoice_payment(), invoice = #limiter_context_Invoice{ owner_id = OwnerID, @@ -74,14 +80,19 @@ effective_payment = #limiter_context_InvoicePayment{ created_at = <<"2000-01-01T00:00:00Z">>, cost = Cost, - capture_cost = CaptureCost - } + capture_cost = CaptureCost, + flow = {hold, #limiter_context_InvoicePaymentFlowHold{}}, + payer = {payment_resource, #limiter_context_PaymentResourcePayer{}}, + effective_adjustment = #limiter_context_InvoicePaymentAdjustment{}, + effective_chargeback = #limiter_context_InvoicePaymentChargeback{} + }, + effective_adjustment = #limiter_context_InvoiceAdjustment{} } } }). -define(ctx_invoice_payment(Payment), #limiter_context_LimitContext{ - payment_processing = #limiter_context_ContextPaymentProcessing{ + limiter_payment_processing = #limiter_context_ContextPaymentProcessing{ op = ?op_invoice_payment(), invoice = #limiter_context_Invoice{ effective_payment = Payment @@ -90,7 +101,7 @@ }). -define(ctx_invoice_payment_refund(OwnerID, ShopID, Cost, CaptureCost, RefundCost), #limiter_context_LimitContext{ - payment_processing = #limiter_context_ContextPaymentProcessing{ + limiter_payment_processing = #limiter_context_ContextPaymentProcessing{ op = {invoice_payment_refund, #limiter_context_PaymentProcessingOperationInvoicePaymentRefund{}}, invoice = #limiter_context_Invoice{ owner_id = OwnerID, @@ -108,4 +119,109 @@ } }). +%% Payproc + +-define(payproc_op_invoice, {invoice, #limiter_context_payproc_OperationInvoice{}}). +-define(payproc_op_invoice_payment, {invoice_payment, #limiter_context_payproc_OperationInvoicePayment{}}). + +-define(payproc_bank_card(), + ?payproc_bank_card(?string, 2, 2022) +). + +-define(payproc_bank_card(Token, Month, Year), #domain_BankCard{ + token = Token, + bin = ?string, + last_digits = ?string, + exp_date = #domain_BankCardExpDate{month = Month, year = Year} +}). + +-define(payproc_invoice(OwnerID, ShopID, Cost), #domain_Invoice{ + id = ?string, + owner_id = OwnerID, + shop_id = ShopID, + created_at = ?timestamp, + status = {unpaid, #domain_InvoiceUnpaid{}}, + details = #domain_InvoiceDetails{product = ?string}, + due = ?timestamp, + cost = Cost +}). + +-define(payproc_invoice_payment(Cost, CaptureCost), + ?payproc_invoice_payment(Cost, CaptureCost, {bank_card, ?payproc_bank_card()}) +). + +-define(payproc_invoice_payment(Cost, CaptureCost, PaymentTool), #domain_InvoicePayment{ + id = ?string, + created_at = ?timestamp, + status = {captured, #domain_InvoicePaymentCaptured{cost = CaptureCost}}, + cost = Cost, + domain_revision = 1, + flow = {instant, #domain_InvoicePaymentFlowInstant{}}, + payer = + {payment_resource, #domain_PaymentResourcePayer{ + resource = #domain_DisposablePaymentResource{ + payment_tool = PaymentTool + }, + contact_info = #domain_ContactInfo{} + }} +}). + +-define(payproc_ctx_invoice(Cost), #limiter_context_LimitContext{ + payment_processing = #limiter_context_payproc_Context{ + op = ?payproc_op_invoice, + invoice = #limiter_context_payproc_Invoice{ + invoice = ?payproc_invoice(?string, ?string, Cost) + } + } +}). + +-define(payproc_ctx_invoice_payment(Cost, CaptureCost), + ?payproc_ctx_invoice_payment(?string, ?string, Cost, CaptureCost) +). + +-define(payproc_ctx_invoice_payment(OwnerID, ShopID, Cost, CaptureCost), #limiter_context_LimitContext{ + payment_processing = #limiter_context_payproc_Context{ + op = ?payproc_op_invoice_payment, + invoice = #limiter_context_payproc_Invoice{ + invoice = ?payproc_invoice(OwnerID, ShopID, Cost), + payment = #limiter_context_payproc_InvoicePayment{ + payment = ?payproc_invoice_payment(Cost, CaptureCost) + } + } + } +}). + +-define(payproc_ctx_invoice_payment(Payment), #limiter_context_LimitContext{ + payment_processing = #limiter_context_payproc_Context{ + op = ?payproc_op_invoice_payment, + invoice = #limiter_context_payproc_Invoice{ + invoice = ?payproc_invoice(?string, ?string, ?cash(10)), + payment = #limiter_context_payproc_InvoicePayment{ + payment = Payment + } + } + } +}). + +-define(payproc_ctx_invoice_payment_refund(OwnerID, ShopID, Cost, CaptureCost, RefundCost), + #limiter_context_LimitContext{ + payment_processing = #limiter_context_payproc_Context{ + op = {invoice_payment_refund, #limiter_context_payproc_OperationInvoicePaymentRefund{}}, + invoice = #limiter_context_payproc_Invoice{ + invoice = ?payproc_invoice(OwnerID, ShopID, Cost), + payment = #limiter_context_payproc_InvoicePayment{ + payment = ?payproc_invoice_payment(Cost, CaptureCost), + refund = #domain_InvoicePaymentRefund{ + id = ?string, + status = {succeeded, #domain_InvoicePaymentRefundSucceeded{}}, + created_at = ?timestamp, + domain_revision = 1, + cash = RefundCost + } + } + } + } + } +). + -endif. diff --git a/apps/limiter/test/lim_turnover_SUITE.erl b/apps/limiter/test/lim_turnover_SUITE.erl index abb2dcc..1d07ff1 100644 --- a/apps/limiter/test/lim_turnover_SUITE.erl +++ b/apps/limiter/test/lim_turnover_SUITE.erl @@ -40,6 +40,12 @@ -export([commit_refund_keep_number_unchanged/1]). -export([partial_commit_number_counts_as_single_op/1]). +-export([payproc_hold_ok/1]). +-export([payproc_commit_ok/1]). +-export([payproc_rollback_ok/1]). +-export([payproc_refund_ok/1]). +-export([payproc_commit_with_payment_tool_scope_ok/1]). + -type group_name() :: atom(). -type test_case_name() :: atom(). @@ -72,7 +78,12 @@ groups() -> refund_ok, commit_inexistent_hold_fails, partial_commit_inexistent_hold_fails, - commit_multirange_limit_ok + commit_multirange_limit_ok, + payproc_hold_ok, + payproc_commit_ok, + payproc_rollback_ok, + payproc_refund_ok, + payproc_commit_with_payment_tool_scope_ok ]}, {cashless, [parallel], [ commit_number_ok, @@ -145,13 +156,13 @@ commit_with_default_exchange(C) -> _ = mock_exchange(Rational, C), ID = configure_limit(?time_range_month(), ?global(), C), Context = #limiter_context_LimitContext{ - payment_processing = #limiter_context_ContextPaymentProcessing{ + limiter_payment_processing = #limiter_context_ContextPaymentProcessing{ op = {invoice, #limiter_context_PaymentProcessingOperationInvoice{}}, invoice = #limiter_context_Invoice{ created_at = <<"2000-01-01T00:00:00Z">>, - cost = #limiter_base_Cash{ + cost = #domain_Cash{ amount = 10000, - currency = #limiter_base_CurrencyRef{symbolic_code = <<"SOME_CURRENCY">>} + currency = #domain_CurrencyRef{symbolic_code = <<"SOME_CURRENCY">>} } } } @@ -165,18 +176,18 @@ partial_commit_with_exchange(C) -> _ = mock_exchange(Rational, C), ID = configure_limit(?time_range_month(), ?global(), C), Context = #limiter_context_LimitContext{ - payment_processing = #limiter_context_ContextPaymentProcessing{ + limiter_payment_processing = #limiter_context_ContextPaymentProcessing{ op = {invoice_payment, #limiter_context_PaymentProcessingOperationInvoicePayment{}}, invoice = #limiter_context_Invoice{ effective_payment = #limiter_context_InvoicePayment{ created_at = <<"2000-01-01T00:00:00Z">>, - cost = #limiter_base_Cash{ + cost = #domain_Cash{ amount = 10000, - currency = #limiter_base_CurrencyRef{symbolic_code = <<"USD">>} + currency = #domain_CurrencyRef{symbolic_code = <<"USD">>} }, - capture_cost = #limiter_base_Cash{ + capture_cost = #domain_Cash{ amount = 8000, - currency = #limiter_base_CurrencyRef{symbolic_code = <<"USD">>} + currency = #domain_CurrencyRef{symbolic_code = <<"USD">>} } } } @@ -191,13 +202,13 @@ commit_with_exchange(C) -> _ = mock_exchange(Rational, C), ID = configure_limit(?time_range_month(), ?global(), C), Context = #limiter_context_LimitContext{ - payment_processing = #limiter_context_ContextPaymentProcessing{ + limiter_payment_processing = #limiter_context_ContextPaymentProcessing{ op = {invoice, #limiter_context_PaymentProcessingOperationInvoice{}}, invoice = #limiter_context_Invoice{ created_at = <<"2000-01-01T00:00:00Z">>, - cost = #limiter_base_Cash{ + cost = #domain_Cash{ amount = 10000, - currency = #limiter_base_CurrencyRef{symbolic_code = <<"USD">>} + currency = #domain_CurrencyRef{symbolic_code = <<"USD">>} } } } @@ -251,13 +262,13 @@ hold_ok(C) -> commit_ok(C) -> ID = configure_limit(?time_range_month(), ?global(), C), Context = #limiter_context_LimitContext{ - payment_processing = #limiter_context_ContextPaymentProcessing{ + limiter_payment_processing = #limiter_context_ContextPaymentProcessing{ op = {invoice, #limiter_context_PaymentProcessingOperationInvoice{}}, invoice = #limiter_context_Invoice{ created_at = <<"2000-01-01T00:00:00Z">>, - cost = #limiter_base_Cash{ + cost = #domain_Cash{ amount = 10, - currency = #limiter_base_CurrencyRef{symbolic_code = <<"RUB">>} + currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>} } } } @@ -299,7 +310,7 @@ commit_inexistent_hold_fails(C) -> % NOTE % We do not expect `LimitChangeNotFound` here because we no longer reconcile with accounter % before requesting him to hold / commit. - {exception, #limiter_base_InvalidRequest{}} = + {exception, #'InvalidRequest'{}} = lim_client:commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)). -spec partial_commit_inexistent_hold_fails(config()) -> _. @@ -309,7 +320,7 @@ partial_commit_inexistent_hold_fails(C) -> % NOTE % We do not expect `LimitChangeNotFound` here because we no longer reconcile with accounter % before requesting him to hold / commit. - {exception, #limiter_base_InvalidRequest{}} = + {exception, #'InvalidRequest'{}} = lim_client:commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)). -spec commit_multirange_limit_ok(config()) -> _. @@ -468,6 +479,79 @@ partial_commit_number_counts_as_single_op(C) -> %% +-spec payproc_hold_ok(config()) -> _. +payproc_hold_ok(C) -> + ID = configure_limit(?time_range_month(), ?global(), C), + Context = ?payproc_ctx_invoice(?cash(10)), + {ok, {vector, #limiter_VectorClock{}}} = lim_client:hold(?LIMIT_CHANGE(ID), Context, ?config(client, C)), + {ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)). + +-spec payproc_commit_ok(config()) -> _. +payproc_commit_ok(C) -> + ID = configure_limit(?time_range_year(), ?global(), C), + Context = ?payproc_ctx_invoice(?cash(10)), + {ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)), + {ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)). + +-spec payproc_rollback_ok(config()) -> _. +payproc_rollback_ok(C) -> + ID = configure_limit(?time_range_week(), ?global(), C), + Context0 = ?payproc_ctx_invoice_payment(?cash(10), ?cash(10)), + Context1 = ?payproc_ctx_invoice_payment(?cash(10), ?cash(0)), + Change = ?LIMIT_CHANGE(ID), + {ok, {vector, _}} = lim_client:hold(Change, Context0, ?config(client, C)), + {ok, {vector, _}} = lim_client:commit(Change, Context1, ?config(client, C)). + +-spec payproc_refund_ok(config()) -> _. +payproc_refund_ok(C) -> + Client = ?config(client, C), + OwnerID = <<"WWWcool Ltd">>, + ShopID = <<"shop">>, + ID = configure_limit(?time_range_day(), ?scope([?scope_party(), ?scope_shop()]), C), + Context0 = ?payproc_ctx_invoice_payment(OwnerID, ShopID, ?cash(15), ?cash(15)), + RefundContext1 = ?payproc_ctx_invoice_payment_refund(OwnerID, ShopID, ?cash(10), ?cash(10), ?cash(10)), + {ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, <<"Payment">>), Context0, Client), + {ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, <<"Refund">>), RefundContext1, Client), + {ok, #limiter_Limit{} = Limit2} = lim_client:get(ID, RefundContext1, Client), + ?assertEqual(Limit2#limiter_Limit.amount, 5). + +-spec payproc_commit_with_payment_tool_scope_ok(config()) -> _. +payproc_commit_with_payment_tool_scope_ok(C) -> + Client = ?config(client, C), + ID = configure_limit(?time_range_week(), ?scope([?scope_payment_tool()]), ?turnover_metric_number(), C), + Context0 = ?payproc_ctx_invoice_payment( + ?payproc_invoice_payment( + ?cash(10), + ?cash(10), + {bank_card, ?payproc_bank_card()} + ) + ), + Context1 = ?payproc_ctx_invoice_payment( + ?payproc_invoice_payment( + ?cash(10), + ?cash(10), + {bank_card, ?payproc_bank_card(<<"OtherToken">>, 2, 2022)} + ) + ), + Context2 = ?payproc_ctx_invoice_payment( + ?payproc_invoice_payment( + ?cash(10), + ?cash(10), + {bank_card, ?payproc_bank_card(?string, 3, 2022)} + ) + ), + {ok, LimitState0} = lim_client:get(ID, Context0, Client), + _ = hold_and_commit(?LIMIT_CHANGE(ID, 1), Context0, Client), + _ = hold_and_commit(?LIMIT_CHANGE(ID, 2), Context1, Client), + _ = hold_and_commit(?LIMIT_CHANGE(ID, 3), Context2, Client), + {ok, LimitState1} = lim_client:get(ID, Context0, Client), + ?assertEqual( + LimitState1#limiter_Limit.amount, + LimitState0#limiter_Limit.amount + 1 + ). + +%% + gen_change_id(LimitID, ChangeID) -> genlib:format("~s/~p", [LimitID, ChangeID]). diff --git a/rebar.config b/rebar.config index 3bdee95..80ddc11 100644 --- a/rebar.config +++ b/rebar.config @@ -50,7 +50,7 @@ % mandatory unmatched_returns, error_handling, - race_conditions, + % race_conditions, unknown ]}, {plt_apps, all_deps} diff --git a/rebar.lock b/rebar.lock index 5586537..a8ad132 100644 --- a/rebar.lock +++ b/rebar.lock @@ -25,7 +25,7 @@ {<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1}, {<<"limiter_proto">>, {git,"https://github.com/valitydev/limiter-proto.git", - {ref,"6723e862157a7f78194a64271899c2ef1581e177"}}, + {ref,"ac9705389211682263c0a983ae76f663d4857ec9"}}, 0}, {<<"machinery">>, {git,"https://github.com/valitydev/machinery-erlang.git",