Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
09d3c66
add adjustment clock update event
aenglisc Nov 30, 2020
50c67ff
update adjustment tests
aenglisc Nov 30, 2020
9b03def
add adjustment clock handling
aenglisc Nov 30, 2020
9dca8ab
fix format
aenglisc Nov 30, 2020
aa0cf6c
Merge branch 'HG-544/ft/shumaich_payments' into HG-544/ft/shumaich_ad…
aenglisc Nov 30, 2020
0b4aeb1
Merge branch 'HG-544/ft/shumaich_payments' of github.com:rbkmoney/hel…
aenglisc Nov 30, 2020
4dd60d6
Merge branch 'HG-544/ft/shumaich_payments' of github.com:rbkmoney/hel…
aenglisc Nov 30, 2020
3d49bfa
Merge branch 'HG-544/ft/shumaich_payments' into HG-544/ft/shumaich_ad…
kehitt Jul 8, 2021
3ca121f
fix test
kehitt Jul 9, 2021
977e6d1
Merge branch 'HG-544/ft/shumaich_payments' into HG-544/ft/shumaich_ad…
kehitt Jul 12, 2021
bf27681
Merge branch 'HG-544/ft/shumaich_payments' into HG-544/ft/shumaich_ad…
kehitt Jul 12, 2021
835fecf
update accounting get_balance
kehitt Jul 12, 2021
4480adb
Merge branch 'HG-544/ft/shumaich_payments' into HG-544/ft/shumaich_ad…
kehitt Jul 14, 2021
ec918a9
merge clocks
kehitt Aug 5, 2021
cafae86
use clock for plan
kehitt Aug 6, 2021
c5dfe93
Merge remote-tracking branch 'origin/HG-544/ft/shumaich_payments' int…
kehitt Sep 22, 2021
7e92e8f
use new accounter api for adjustments
kehitt Sep 22, 2021
a6a95b2
fix clock
kehitt Sep 22, 2021
772870f
Merge remote-tracking branch 'origin/HG-544/ft/shumaich_payments' int…
kehitt Sep 22, 2021
e01d895
Merge remote-tracking branch 'origin/HG-544/ft/shumaich_payments' int…
kehitt Sep 23, 2021
cc3fcca
Merge remote-tracking branch 'origin/HG-544/ft/shumaich_payments' int…
kehitt Sep 23, 2021
372ac19
avoid resource_unavailable when possible
kehitt Sep 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/hellgate/include/payment_events.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -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{}}
).
Expand Down
93 changes: 58 additions & 35 deletions apps/hellgate/src/hg_invoice_payment.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1660,30 +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),
ok = finalize_adjustment_cashflow(Intent, Adjustment, St, Options),
Status =
case Intent of
capture ->
?adjustment_captured(Timestamp);
cancel ->
?adjustment_cancelled(Timestamp)
end,
Event = ?adjustment_ev(ID, ?adjustment_status_changed(Status)),
{ok, {[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) ->
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_adjustment_cashflow(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_adjustment_cashflow(PlanID, Plan, Timestamp, St#st.clock);
cancel ->
rollback(PlanID, Plan)
rollback_adjustment_cashflow(PlanID, Plan, Timestamp, St#st.clock)
end.

get_adjustment_cashflow_plan(#domain_InvoicePaymentAdjustment{
Expand All @@ -1699,23 +1704,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_adjustment_cashflow(_PlanID, [], _Timestamp, Clock) ->
{ok, Clock};
plan_adjustment_cashflow(PlanID, Plan, Timestamp, Clock) ->
hg_accounting_new:plan(PlanID, Plan, Timestamp, Clock).

commit(_PlanID, []) ->
ok;
commit(PlanID, Plan) ->
_ = hg_accounting:commit(PlanID, Plan),
ok.
commit_adjustment_cashflow(_PlanID, [], _Timestamp, Clock) ->
{ok, Clock};
commit_adjustment_cashflow(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_adjustment_cashflow(_PlanID, [], _Timestamp, Clock) ->
{ok, Clock};
rollback_adjustment_cashflow(PlanID, Plan, Timestamp, Clock) ->
hg_accounting_new:rollback(PlanID, Plan, Timestamp, Clock).

assert_adjustment_status(Status, #domain_InvoicePaymentAdjustment{status = {Status, _}}) ->
ok;
Expand Down Expand Up @@ -1966,12 +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),
ok = prepare_adjustment_cashflow(Adjustment, St, Opts),
Events = [?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),
Expand Down Expand Up @@ -3091,12 +3101,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(Event, set_adjustment(ID, Adjustment, St1)),
% TODO new cashflow imposed implicitly on the payment state? rough
case get_adjustment_status(Adjustment) of
?adjustment_captured(_) ->
Expand Down Expand Up @@ -3188,6 +3201,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}.

Expand Down Expand Up @@ -3364,6 +3379,14 @@ 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(?adjustment_clock_update(Clock), St = #st{activity = {AdjustmentActivity, _}}) when
AdjustmentActivity =:= adjustment_new;
AdjustmentActivity =:= adjustment_pending
->
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);
Expand Down
8 changes: 7 additions & 1 deletion apps/hellgate/test/hg_invoice_tests_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1907,6 +1907,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 =
Expand All @@ -1916,6 +1917,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
Expand Down Expand Up @@ -2043,6 +2045,7 @@ payment_adjustment_captured_partial(C) ->
#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
PrvAccount2 = get_cashflow_account({provider, settlement}, CF2),
SysAccount2 = get_cashflow_account({system, settlement}, CF2),
MrcAccount2 = get_cashflow_account({merchant, settlement}, CF2),
Expand Down Expand Up @@ -2252,7 +2255,8 @@ get_cashflow_account(Type, CF) ->
} <- CF,
T == Type
],
hg_ct_helper: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) ->
Expand Down Expand Up @@ -5425,10 +5429,12 @@ execute_payment_adjustment(InvoiceID, PaymentID, Params, 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),
AdjustmentID.
Expand Down