From 09d3c66738c6b9558dd6a81dc2d09beac0050f99 Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Mon, 30 Nov 2020 05:05:26 +0300 Subject: [PATCH 01/11] add adjustment clock update event --- apps/hellgate/include/payment_events.hrl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/hellgate/include/payment_events.hrl b/apps/hellgate/include/payment_events.hrl index 8adc8cb1b..44569024e 100644 --- a/apps/hellgate/include/payment_events.hrl +++ b/apps/hellgate/include/payment_events.hrl @@ -174,6 +174,10 @@ {invoice_payment_adjustment_status_changed, #payproc_InvoicePaymentAdjustmentStatusChanged{status = Status}} ). +-define(adjustment_clock_update(Clock), + {invoice_payment_adjustment_clock_update, #payproc_InvoicePaymentClockUpdate{clock = Clock}} +). + -define(adjustment_pending(), {pending, #domain_InvoicePaymentAdjustmentPending{}} ). From 50c67ff6fd241c3b70cead3e47f27e2e4e320129 Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Mon, 30 Nov 2020 05:05:47 +0300 Subject: [PATCH 02/11] update adjustment tests --- apps/hellgate/test/hg_invoice_tests_SUITE.erl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/hellgate/test/hg_invoice_tests_SUITE.erl b/apps/hellgate/test/hg_invoice_tests_SUITE.erl index 4b77ef282..7d997b1e5 100644 --- a/apps/hellgate/test/hg_invoice_tests_SUITE.erl +++ b/apps/hellgate/test/hg_invoice_tests_SUITE.erl @@ -1692,6 +1692,7 @@ payment_adjustment_success(C) -> ?invalid_adjustment_pending(AdjustmentID) = hg_client_invoicing:create_payment_adjustment(InvoiceID, PaymentID, make_adjustment_params(), Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_processed()))) ] = next_event(InvoiceID, Client), ok = @@ -1701,6 +1702,7 @@ payment_adjustment_success(C) -> ?invalid_adjustment_status(?adjustment_captured(_)) = hg_client_invoicing:cancel_payment_adjustment(InvoiceID, PaymentID, AdjustmentID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_captured(_)))) ] = next_event(InvoiceID, Client), %% verify that cash deposited correctly everywhere @@ -1755,10 +1757,12 @@ partial_captured_payment_adjustment(C) -> ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_created(Adjustment))) ] = next_event(InvoiceID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_processed()))) ] = next_event(InvoiceID, Client), ok = hg_client_invoicing:capture_payment_adjustment(InvoiceID, PaymentID, AdjustmentID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_captured(_)))) ] = next_event(InvoiceID, Client), % verify that cash deposited correctly everywhere @@ -1826,10 +1830,12 @@ payment_adjustment_captured_from_failed(C) -> ?payment_ev(PaymentID, ?adjustment_ev(FailedAdjustmentID, ?adjustment_created(_))) ] = next_event(InvoiceID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(FailedAdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(FailedAdjustmentID, ?adjustment_status_changed(?adjustment_processed()))) ] = next_event(InvoiceID, Client), ok = hg_client_invoicing:capture_payment_adjustment(InvoiceID, PaymentID, FailedAdjustmentID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(FailedAdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(FailedAdjustmentID, ?adjustment_status_changed(?adjustment_captured(_)))) ] = next_event(InvoiceID, Client), ?assertMatch( @@ -1850,10 +1856,12 @@ payment_adjustment_captured_from_failed(C) -> ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_created(Adjustment))) ] = next_event(InvoiceID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_processed()))) ] = next_event(InvoiceID, Client), ok = hg_client_invoicing:capture_payment_adjustment(InvoiceID, PaymentID, AdjustmentID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_captured(_)))) ] = next_event(InvoiceID, Client), ?payment_state(Payment) = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client), @@ -1912,10 +1920,12 @@ payment_adjustment_failed_from_captured(C) -> ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_created(Adjustment))) ] = next_event(InvoiceID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_processed()))) ] = next_event(InvoiceID, Client), ok = hg_client_invoicing:capture_payment_adjustment(InvoiceID, PaymentID, AdjustmentID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_captured(_)))) ] = next_event(InvoiceID, Client), ?assertMatch( @@ -5562,11 +5572,13 @@ make_payment_adjustment_and_get_revision(PaymentID, InvoiceID, Client) -> ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_created(Adjustment))) ] = next_event(InvoiceID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_processed()))) ] = next_event(InvoiceID, Client), ok = hg_client_invoicing:capture_payment_adjustment(InvoiceID, PaymentID, AdjustmentID, Client), [ + ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_clock_update(_))), ?payment_ev(PaymentID, ?adjustment_ev(AdjustmentID, ?adjustment_status_changed(?adjustment_captured(_)))) ] = next_event(InvoiceID, Client), AdjustmentRev. From 9b03def106b2c68403e024e83262cff8cede0769 Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Mon, 30 Nov 2020 05:06:21 +0300 Subject: [PATCH 03/11] add adjustment clock handling --- apps/hellgate/src/hg_invoice_payment.erl | 66 ++++++++++++++---------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/apps/hellgate/src/hg_invoice_payment.erl b/apps/hellgate/src/hg_invoice_payment.erl index da497ed77..0ec38e041 100644 --- a/apps/hellgate/src/hg_invoice_payment.erl +++ b/apps/hellgate/src/hg_invoice_payment.erl @@ -149,7 +149,8 @@ failure :: undefined | failure(), timings :: undefined | hg_timings:t(), latest_change_at :: undefined | hg_datetime:timestamp(), - clock :: hg_accounting_new:clock() + clock :: hg_accounting_new:clock(), + adjustment_clock :: hg_accounting_new:clock() }). -record(refund_st, { @@ -1683,7 +1684,7 @@ cancel_adjustment(ID, St, Options) -> finalize_adjustment(ID, Intent, St, Options = #{timestamp := Timestamp}) -> Adjustment = get_adjustment(ID, St), ok = assert_adjustment_status(processed, Adjustment), - ok = finalize_adjustment_cashflow(Intent, Adjustment, St, Options), + Clock = finalize_adjustment_cashflow(Intent, Adjustment, St, Options), Status = case Intent of capture -> @@ -1691,22 +1692,23 @@ finalize_adjustment(ID, Intent, St, Options = #{timestamp := Timestamp}) -> cancel -> ?adjustment_cancelled(Timestamp) end, + ClockEvent = ?adjustment_ev(ID, ?adjustment_clock_update(Clock)), Event = ?adjustment_ev(ID, ?adjustment_status_changed(Status)), - {ok, {[Event], hg_machine_action:new()}}. + {ok, {[ClockEvent, Event], hg_machine_action:new()}}. -prepare_adjustment_cashflow(Adjustment, St, Options) -> +prepare_adjustment_cashflow(Adjustment, St, Options = #{timestamp := Timestamp}) -> PlanID = construct_adjustment_plan_id(Adjustment, St, Options), Plan = get_adjustment_cashflow_plan(Adjustment), - plan(PlanID, Plan). + plan(PlanID, Plan, Timestamp, St#st.clock). -finalize_adjustment_cashflow(Intent, Adjustment, St, Options) -> +finalize_adjustment_cashflow(Intent, Adjustment, St, Options = #{timestamp := Timestamp}) -> PlanID = construct_adjustment_plan_id(Adjustment, St, Options), Plan = get_adjustment_cashflow_plan(Adjustment), case Intent of capture -> - commit(PlanID, Plan); + commit(PlanID, Plan, Timestamp, St#st.adjustment_clock); cancel -> - rollback(PlanID, Plan) + rollback(PlanID, Plan, Timestamp, St#st.adjustment_clock) end. get_adjustment_cashflow_plan(#domain_InvoicePaymentAdjustment{ @@ -1722,23 +1724,20 @@ number_plan([[] | Tail], Number, Acc) -> number_plan([NonEmpty | Tail], Number, Acc) -> number_plan(Tail, Number + 1, [{Number, NonEmpty} | Acc]). -plan(_PlanID, []) -> - ok; -plan(PlanID, Plan) -> - _ = hg_accounting:plan(PlanID, Plan), - ok. +plan(_PlanID, [], _Timestamp, Clock) -> + Clock; +plan(PlanID, Plan, Timestamp, _Clock) -> + hg_accounting_new:plan(PlanID, Plan, Timestamp). -commit(_PlanID, []) -> - ok; -commit(PlanID, Plan) -> - _ = hg_accounting:commit(PlanID, Plan), - ok. +commit(_PlanID, [], _Timestamp, Clock) -> + Clock; +commit(PlanID, Plan, Timestamp, Clock) -> + hg_accounting_new:commit(PlanID, Plan, Timestamp, Clock). -rollback(_PlanID, []) -> - ok; -rollback(PlanID, Plan) -> - _ = hg_accounting:rollback(PlanID, Plan), - ok. +rollback(_PlanID, [], _Timestamp, Clock) -> + Clock; +rollback(PlanID, Plan, Timestamp, Clock) -> + hg_accounting_new:rollback(PlanID, Plan, Timestamp, Clock). assert_adjustment_status(Status, #domain_InvoicePaymentAdjustment{status = {Status, _}}) -> ok; @@ -1966,8 +1965,11 @@ get_manual_refund_events(#refund_st{transaction_info = TransactionInfo}) -> process_adjustment_cashflow(ID, _Action, St) -> Opts = get_opts(St), Adjustment = get_adjustment(ID, St), - ok = prepare_adjustment_cashflow(Adjustment, St, Opts), - Events = [?adjustment_ev(ID, ?adjustment_status_changed(?adjustment_processed()))], + Clock = prepare_adjustment_cashflow(Adjustment, St, Opts), + Events = [ + ?adjustment_ev(ID, ?adjustment_clock_update(Clock)), + ?adjustment_ev(ID, ?adjustment_status_changed(?adjustment_processed())) + ], {done, {Events, hg_machine_action:new()}}. process_accounter_update(Action, St = #st{partial_cash_flow = FinalCashflow, capture_params = CaptureParams}) -> @@ -3031,12 +3033,15 @@ merge_change(Change = ?adjustment_ev(ID, Event), St, Opts) -> ?adjustment_status_changed(?adjustment_processed()) -> _ = validate_transition({adjustment_new, ID}, Change, St, Opts), St#st{activity = {adjustment_pending, ID}}; + ?adjustment_clock_update(_) -> + _ = validate_transition([{adjustment_new, ID}, {adjustment_pending, ID}], Change, St, Opts), + St; ?adjustment_status_changed(_) -> _ = validate_transition({adjustment_pending, ID}, Change, St, Opts), St#st{activity = idle} end, Adjustment = merge_adjustment_change(Event, try_get_adjustment(ID, St1)), - St2 = set_adjustment(ID, Adjustment, St1), + St2 = set_adjustment_clock(set_adjustment(ID, Adjustment, St1), Event), % TODO new cashflow imposed implicitly on the payment state? rough case get_adjustment_status(Adjustment) of ?adjustment_captured(_) -> @@ -3128,6 +3133,8 @@ merge_refund_change(?session_ev(?refunded(), Change), St) -> merge_adjustment_change(?adjustment_created(Adjustment), undefined) -> Adjustment; +merge_adjustment_change(?adjustment_clock_update(_), Adjustment) -> + Adjustment; merge_adjustment_change(?adjustment_status_changed(Status), Adjustment) -> Adjustment#domain_InvoicePaymentAdjustment{status = Status}. @@ -3305,6 +3312,13 @@ try_get_adjustment(ID, #st{adjustments = As}) -> set_adjustment(ID, Adjustment, St = #st{adjustments = As}) -> St#st{adjustments = lists:keystore(ID, #domain_InvoicePaymentAdjustment.id, As, Adjustment)}. +set_adjustment_clock(St = #st{activity = {adjustment_new, _}}, ?adjustment_clock_update(Clock)) -> + St#st{adjustment_clock = Clock}; +set_adjustment_clock(St = #st{activity = {adjustment_pending, _}}, ?adjustment_clock_update(Clock)) -> + St#st{clock = Clock}; +set_adjustment_clock(St = #st{}, _) -> + St. + merge_session_change(?session_finished(Result), Session, Opts) -> Session2 = Session#{status := finished, result => Result}, accrue_session_timing(finished, started, Opts, Session2); From 9dca8abd16b83d9e7243cb0a6c22443d77b6d38d Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Mon, 30 Nov 2020 11:29:04 +0300 Subject: [PATCH 04/11] fix format --- apps/hellgate/test/hg_invoice_tests_SUITE.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/hellgate/test/hg_invoice_tests_SUITE.erl b/apps/hellgate/test/hg_invoice_tests_SUITE.erl index 7d997b1e5..aba1e37b0 100644 --- a/apps/hellgate/test/hg_invoice_tests_SUITE.erl +++ b/apps/hellgate/test/hg_invoice_tests_SUITE.erl @@ -4842,10 +4842,10 @@ consistent_account_balances(C) -> Party = hg_client_party:get(PartyClient), Shops = maps:values(Party#domain_Party.shops), _ = [ - { + { consistent_account_balance(AccountID, Shop), consistent_account_balance_new(AccountID, Shop) - } + } || #domain_Shop{account = ShopAccount} = Shop <- Shops, #domain_ShopAccount{settlement = AccountID1, guarantee = AccountID2} <- [ShopAccount], AccountID <- [AccountID1, AccountID2] From 3ca121f0dd6fbf362693a357d8e55d39d49744e7 Mon Sep 17 00:00:00 2001 From: Kehitt Date: Fri, 9 Jul 2021 14:44:50 +0300 Subject: [PATCH 05/11] fix test --- apps/hellgate/test/hg_invoice_tests_SUITE.erl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/hellgate/test/hg_invoice_tests_SUITE.erl b/apps/hellgate/test/hg_invoice_tests_SUITE.erl index fa8b6b6a7..cc16fa692 100644 --- a/apps/hellgate/test/hg_invoice_tests_SUITE.erl +++ b/apps/hellgate/test/hg_invoice_tests_SUITE.erl @@ -2150,18 +2150,17 @@ payment_adjustment_failed_from_captured(C) -> Failed = ?failed({failure, #domain_Failure{code = <<"404">>}}), AdjustmentParams = make_status_adjustment_params(Failed, AdjReason = <<"because i can">>), AdjustmentID = execute_payment_adjustment(InvoiceID, PaymentID, AdjustmentParams, Client), + ?adjustment_reason(AdjReason) = + hg_client_invoicing:get_payment_adjustment(InvoiceID, PaymentID, AdjustmentID, Client), ?assertMatch( ?payment_state(?payment_w_status(PaymentID, Failed)), hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client) ), - #domain_InvoicePaymentAdjustment{new_cash_flow = CF2} = - ?adjustment_reason(AdjReason) = - hg_client_invoicing:get_payment_adjustment(InvoiceID, PaymentID, AdjustmentID, Client), % verify that cash deposited correctly everywhere % new cash flow must be calculated using initial domain and party revisions - PrvAccount2 = get_cashflow_account({provider, settlement}, CF2), - SysAccount2 = get_cashflow_account({system, settlement}, CF2), - MrcAccount2 = get_cashflow_account({merchant, settlement}, CF2), + PrvAccount2 = get_cashflow_account({provider, settlement}, CF1), + SysAccount2 = get_cashflow_account({system, settlement}, CF1), + MrcAccount2 = get_cashflow_account({merchant, settlement}, CF1), Context = #{operation_amount => ?cash(Amount, <<"RUB">>)}, #domain_Cash{amount = MrcAmount1} = hg_cashflow:compute_volume(?merchant_to_system_share_1, Context), MrcDiff = Amount - MrcAmount1, From 835fecfeed93fe647d72d677929d03c437b5cb67 Mon Sep 17 00:00:00 2001 From: Kehitt Date: Mon, 12 Jul 2021 18:35:34 +0300 Subject: [PATCH 06/11] update accounting get_balance --- apps/hellgate/test/hg_invoice_tests_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hellgate/test/hg_invoice_tests_SUITE.erl b/apps/hellgate/test/hg_invoice_tests_SUITE.erl index 42777a2e6..61ab366e3 100644 --- a/apps/hellgate/test/hg_invoice_tests_SUITE.erl +++ b/apps/hellgate/test/hg_invoice_tests_SUITE.erl @@ -2242,7 +2242,7 @@ get_cashflow_account(Type, CF) -> } <- CF, T == Type ], - hg_ct_helper:get_balance(ID). + hg_accounting_new:get_balance(ID). -spec invalid_payment_w_deprived_party(config()) -> test_return(). invalid_payment_w_deprived_party(C) -> From ec918a9cf55143c1386aa48f2c3d6cd457e6adb7 Mon Sep 17 00:00:00 2001 From: Kehitt Date: Thu, 5 Aug 2021 17:13:03 +0300 Subject: [PATCH 07/11] merge clocks --- apps/hellgate/src/hg_invoice_payment.erl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/hellgate/src/hg_invoice_payment.erl b/apps/hellgate/src/hg_invoice_payment.erl index 7fbca8d4d..a4538eb02 100644 --- a/apps/hellgate/src/hg_invoice_payment.erl +++ b/apps/hellgate/src/hg_invoice_payment.erl @@ -149,8 +149,7 @@ failure :: undefined | failure(), timings :: undefined | hg_timings:t(), latest_change_at :: undefined | hg_datetime:timestamp(), - clock :: undefined | hg_accounting_new:clock(), - adjustment_clock :: undefined | hg_accounting_new:clock() + clock :: undefined | hg_accounting_new:clock() }). -record(refund_st, { @@ -1683,9 +1682,9 @@ finalize_adjustment_cashflow(Intent, Adjustment, St, Options = #{timestamp := Ti Plan = get_adjustment_cashflow_plan(Adjustment), case Intent of capture -> - commit(PlanID, Plan, Timestamp, St#st.adjustment_clock); + commit(PlanID, Plan, Timestamp, St#st.clock); cancel -> - rollback(PlanID, Plan, Timestamp, St#st.adjustment_clock) + rollback(PlanID, Plan, Timestamp, St#st.clock) end. get_adjustment_cashflow_plan(#domain_InvoicePaymentAdjustment{ @@ -3364,9 +3363,10 @@ try_get_adjustment(ID, #st{adjustments = As}) -> set_adjustment(ID, Adjustment, St = #st{adjustments = As}) -> St#st{adjustments = lists:keystore(ID, #domain_InvoicePaymentAdjustment.id, As, Adjustment)}. -set_adjustment_clock(St = #st{activity = {adjustment_new, _}}, ?adjustment_clock_update(Clock)) -> - St#st{adjustment_clock = Clock}; -set_adjustment_clock(St = #st{activity = {adjustment_pending, _}}, ?adjustment_clock_update(Clock)) -> +set_adjustment_clock(St = #st{activity = {AdjustmentActivity, _}}, ?adjustment_clock_update(Clock)) when + AdjustmentActivity =:= adjustment_new; + AdjustmentActivity =:= adjustment_pending +-> St#st{clock = Clock}; set_adjustment_clock(St = #st{}, _) -> St. From cafae86b7c4ab1b280afd5f9bfbd586cc4cc94dc Mon Sep 17 00:00:00 2001 From: Kehitt Date: Fri, 6 Aug 2021 16:46:05 +0300 Subject: [PATCH 08/11] use clock for plan --- apps/hellgate/src/hg_invoice_payment.erl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/hellgate/src/hg_invoice_payment.erl b/apps/hellgate/src/hg_invoice_payment.erl index a4538eb02..6c727c453 100644 --- a/apps/hellgate/src/hg_invoice_payment.erl +++ b/apps/hellgate/src/hg_invoice_payment.erl @@ -1702,8 +1702,8 @@ number_plan([NonEmpty | Tail], Number, Acc) -> plan(_PlanID, [], _Timestamp, Clock) -> Clock; -plan(PlanID, Plan, Timestamp, _Clock) -> - hg_accounting_new:plan(PlanID, Plan, Timestamp). +plan(PlanID, Plan, Timestamp, Clock) -> + hg_accounting_new:plan(PlanID, Plan, Timestamp, Clock). commit(_PlanID, [], _Timestamp, Clock) -> Clock; @@ -3093,7 +3093,7 @@ merge_change(Change = ?adjustment_ev(ID, Event), St, Opts) -> St#st{activity = idle} end, Adjustment = merge_adjustment_change(Event, try_get_adjustment(ID, St1)), - St2 = set_adjustment_clock(set_adjustment(ID, Adjustment, St1), Event), + St2 = set_adjustment_clock(Event, set_adjustment(ID, Adjustment, St1)), % TODO new cashflow imposed implicitly on the payment state? rough case get_adjustment_status(Adjustment) of ?adjustment_captured(_) -> @@ -3363,12 +3363,12 @@ try_get_adjustment(ID, #st{adjustments = As}) -> set_adjustment(ID, Adjustment, St = #st{adjustments = As}) -> St#st{adjustments = lists:keystore(ID, #domain_InvoicePaymentAdjustment.id, As, Adjustment)}. -set_adjustment_clock(St = #st{activity = {AdjustmentActivity, _}}, ?adjustment_clock_update(Clock)) when +set_adjustment_clock(?adjustment_clock_update(Clock), St = #st{activity = {AdjustmentActivity, _}}) when AdjustmentActivity =:= adjustment_new; AdjustmentActivity =:= adjustment_pending -> St#st{clock = Clock}; -set_adjustment_clock(St = #st{}, _) -> +set_adjustment_clock(_, St = #st{}) -> St. merge_session_change(?session_finished(Result), Session, Opts) -> From 7e92e8fc7a4da5787c8e5a45d884903dbb7e5daf Mon Sep 17 00:00:00 2001 From: Kehitt Date: Wed, 22 Sep 2021 15:44:33 +0300 Subject: [PATCH 09/11] use new accounter api for adjustments --- apps/hellgate/src/hg_invoice_payment.erl | 63 +++++++++++-------- apps/hellgate/test/hg_invoice_tests_SUITE.erl | 3 +- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/apps/hellgate/src/hg_invoice_payment.erl b/apps/hellgate/src/hg_invoice_payment.erl index 72475d990..ef024e785 100644 --- a/apps/hellgate/src/hg_invoice_payment.erl +++ b/apps/hellgate/src/hg_invoice_payment.erl @@ -1660,31 +1660,35 @@ cancel_adjustment(ID, St, Options) -> finalize_adjustment(ID, Intent, St, Options = #{timestamp := Timestamp}) -> Adjustment = get_adjustment(ID, St), ok = assert_adjustment_status(processed, Adjustment), - Clock = finalize_adjustment_cashflow(Intent, Adjustment, St, Options), - Status = - case Intent of - capture -> - ?adjustment_captured(Timestamp); - cancel -> - ?adjustment_cancelled(Timestamp) - end, - ClockEvent = ?adjustment_ev(ID, ?adjustment_clock_update(Clock)), - Event = ?adjustment_ev(ID, ?adjustment_status_changed(Status)), - {ok, {[ClockEvent, Event], hg_machine_action:new()}}. + case finalize_adjustment_cashflow(Intent, Adjustment, St, Options) of + {ok, Clock} -> + Status = + case Intent of + capture -> + ?adjustment_captured(Timestamp); + cancel -> + ?adjustment_cancelled(Timestamp) + end, + ClockEvent = ?adjustment_ev(ID, ?adjustment_clock_update(Clock)), + Event = ?adjustment_ev(ID, ?adjustment_status_changed(Status)), + {ok, {[ClockEvent, Event], hg_machine_action:new()}}; + {error, not_ready} -> + woody_error:raise(system, {external, resource_unavailable, <<"Accounter was not ready">>}) + end. prepare_adjustment_cashflow(Adjustment, St, Options = #{timestamp := Timestamp}) -> PlanID = construct_adjustment_plan_id(Adjustment, St, Options), Plan = get_adjustment_cashflow_plan(Adjustment), - plan(PlanID, Plan, Timestamp, St#st.clock). + plan_adjustment_cashflow(PlanID, Plan, Timestamp, St#st.clock). finalize_adjustment_cashflow(Intent, Adjustment, St, Options = #{timestamp := Timestamp}) -> PlanID = construct_adjustment_plan_id(Adjustment, St, Options), Plan = get_adjustment_cashflow_plan(Adjustment), case Intent of capture -> - commit(PlanID, Plan, Timestamp, St#st.clock); + commit_adjustment_cashflow(PlanID, Plan, Timestamp, St#st.clock); cancel -> - rollback(PlanID, Plan, Timestamp, St#st.clock) + rollback_adjustment_cashflow(PlanID, Plan, Timestamp, St#st.clock) end. get_adjustment_cashflow_plan(#domain_InvoicePaymentAdjustment{ @@ -1700,19 +1704,19 @@ number_plan([[] | Tail], Number, Acc) -> number_plan([NonEmpty | Tail], Number, Acc) -> number_plan(Tail, Number + 1, [{Number, NonEmpty} | Acc]). -plan(_PlanID, [], _Timestamp, Clock) -> +plan_adjustment_cashflow(_PlanID, [], _Timestamp, Clock) -> Clock; -plan(PlanID, Plan, Timestamp, Clock) -> +plan_adjustment_cashflow(PlanID, Plan, Timestamp, Clock) -> hg_accounting_new:plan(PlanID, Plan, Timestamp, Clock). -commit(_PlanID, [], _Timestamp, Clock) -> +commit_adjustment_cashflow(_PlanID, [], _Timestamp, Clock) -> Clock; -commit(PlanID, Plan, Timestamp, Clock) -> +commit_adjustment_cashflow(PlanID, Plan, Timestamp, Clock) -> hg_accounting_new:commit(PlanID, Plan, Timestamp, Clock). -rollback(_PlanID, [], _Timestamp, Clock) -> +rollback_adjustment_cashflow(_PlanID, [], _Timestamp, Clock) -> Clock; -rollback(PlanID, Plan, Timestamp, Clock) -> +rollback_adjustment_cashflow(PlanID, Plan, Timestamp, Clock) -> hg_accounting_new:rollback(PlanID, Plan, Timestamp, Clock). assert_adjustment_status(Status, #domain_InvoicePaymentAdjustment{status = {Status, _}}) -> @@ -1964,15 +1968,20 @@ get_manual_refund_events(#refund_st{transaction_info = TransactionInfo}) -> %% -spec process_adjustment_cashflow(adjustment_id(), action(), st()) -> machine_result(). -process_adjustment_cashflow(ID, _Action, St) -> +process_adjustment_cashflow(ID, Action, St) -> Opts = get_opts(St), Adjustment = get_adjustment(ID, St), - Clock = prepare_adjustment_cashflow(Adjustment, St, Opts), - Events = [ - ?adjustment_ev(ID, ?adjustment_clock_update(Clock)), - ?adjustment_ev(ID, ?adjustment_status_changed(?adjustment_processed())) - ], - {done, {Events, hg_machine_action:new()}}. + case prepare_adjustment_cashflow(Adjustment, St, Opts) of + {ok, Clock} -> + Events = [ + ?adjustment_ev(ID, ?adjustment_clock_update(Clock)), + ?adjustment_ev(ID, ?adjustment_status_changed(?adjustment_processed())) + ], + {done, {Events, hg_machine_action:new()}}; + {error, not_ready} -> + _ = logger:warning("Accounter was not ready, retrying"), + {next, {[], hg_machine_action:set_timeout(0, Action)}} + end. process_accounter_update(Action, St = #st{partial_cash_flow = FinalCashflow, capture_params = CaptureParams}) -> #{timestamp := Timestamp} = Opts = get_opts(St), diff --git a/apps/hellgate/test/hg_invoice_tests_SUITE.erl b/apps/hellgate/test/hg_invoice_tests_SUITE.erl index c5b65311d..7eff0f5fe 100644 --- a/apps/hellgate/test/hg_invoice_tests_SUITE.erl +++ b/apps/hellgate/test/hg_invoice_tests_SUITE.erl @@ -2255,7 +2255,8 @@ get_cashflow_account(Type, CF) -> } <- CF, T == Type ], - hg_accounting_new:get_balance(ID). + {ok, Balance} = hg_accounting_new:get_balance(ID), + Balance. -spec invalid_payment_w_deprived_party(config()) -> test_return(). invalid_payment_w_deprived_party(C) -> From a6a95b26b6cc833f1f6a458e56f8a7643fc337b7 Mon Sep 17 00:00:00 2001 From: Kehitt Date: Wed, 22 Sep 2021 16:48:12 +0300 Subject: [PATCH 10/11] fix clock --- apps/hellgate/src/hg_invoice_payment.erl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/hellgate/src/hg_invoice_payment.erl b/apps/hellgate/src/hg_invoice_payment.erl index ef024e785..6f4c295ae 100644 --- a/apps/hellgate/src/hg_invoice_payment.erl +++ b/apps/hellgate/src/hg_invoice_payment.erl @@ -1705,17 +1705,17 @@ number_plan([NonEmpty | Tail], Number, Acc) -> number_plan(Tail, Number + 1, [{Number, NonEmpty} | Acc]). plan_adjustment_cashflow(_PlanID, [], _Timestamp, Clock) -> - Clock; + {ok, Clock}; plan_adjustment_cashflow(PlanID, Plan, Timestamp, Clock) -> hg_accounting_new:plan(PlanID, Plan, Timestamp, Clock). commit_adjustment_cashflow(_PlanID, [], _Timestamp, Clock) -> - Clock; + {ok, Clock}; commit_adjustment_cashflow(PlanID, Plan, Timestamp, Clock) -> hg_accounting_new:commit(PlanID, Plan, Timestamp, Clock). rollback_adjustment_cashflow(_PlanID, [], _Timestamp, Clock) -> - Clock; + {ok, Clock}; rollback_adjustment_cashflow(PlanID, Plan, Timestamp, Clock) -> hg_accounting_new:rollback(PlanID, Plan, Timestamp, Clock). @@ -1968,7 +1968,7 @@ get_manual_refund_events(#refund_st{transaction_info = TransactionInfo}) -> %% -spec process_adjustment_cashflow(adjustment_id(), action(), st()) -> machine_result(). -process_adjustment_cashflow(ID, Action, St) -> +process_adjustment_cashflow(ID, _Action, St) -> Opts = get_opts(St), Adjustment = get_adjustment(ID, St), case prepare_adjustment_cashflow(Adjustment, St, Opts) of @@ -1979,8 +1979,7 @@ process_adjustment_cashflow(ID, Action, St) -> ], {done, {Events, hg_machine_action:new()}}; {error, not_ready} -> - _ = logger:warning("Accounter was not ready, retrying"), - {next, {[], hg_machine_action:set_timeout(0, Action)}} + woody_error:raise(system, {external, resource_unavailable, <<"Accounter was not ready">>}) end. process_accounter_update(Action, St = #st{partial_cash_flow = FinalCashflow, capture_params = CaptureParams}) -> From 372ac19e3e3c629549053e518901afa66347f106 Mon Sep 17 00:00:00 2001 From: Kehitt Date: Thu, 23 Sep 2021 15:00:05 +0300 Subject: [PATCH 11/11] avoid resource_unavailable when possible --- apps/hellgate/src/hg_invoice_payment.erl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/hellgate/src/hg_invoice_payment.erl b/apps/hellgate/src/hg_invoice_payment.erl index 8421a8300..6dc7764cf 100644 --- a/apps/hellgate/src/hg_invoice_payment.erl +++ b/apps/hellgate/src/hg_invoice_payment.erl @@ -1968,7 +1968,7 @@ get_manual_refund_events(#refund_st{transaction_info = TransactionInfo}) -> %% -spec process_adjustment_cashflow(adjustment_id(), action(), st()) -> machine_result(). -process_adjustment_cashflow(ID, _Action, St) -> +process_adjustment_cashflow(ID, Action, St) -> Opts = get_opts(St), Adjustment = get_adjustment(ID, St), case prepare_adjustment_cashflow(Adjustment, St, Opts) of @@ -1979,7 +1979,8 @@ process_adjustment_cashflow(ID, _Action, St) -> ], {done, {Events, hg_machine_action:new()}}; {error, not_ready} -> - woody_error:raise(system, {external, resource_unavailable, <<"Accounter was not ready">>}) + _ = logger:warning("Accounter was not ready, retrying"), + {next, {[], hg_machine_action:set_timeout(0, Action)}} end. process_accounter_update(Action, St = #st{partial_cash_flow = FinalCashflow, capture_params = CaptureParams}) ->