diff --git a/src/main/java/dev/vality/newway/dao/invoicing/impl/RefundDaoImpl.java b/src/main/java/dev/vality/newway/dao/invoicing/impl/RefundDaoImpl.java index 44d9889c..ce1b32cb 100644 --- a/src/main/java/dev/vality/newway/dao/invoicing/impl/RefundDaoImpl.java +++ b/src/main/java/dev/vality/newway/dao/invoicing/impl/RefundDaoImpl.java @@ -64,16 +64,28 @@ public void updateCommissions(Long rfndId) throws DaoException { MapSqlParameterSource params = new MapSqlParameterSource("rfndId", rfndId).addValue("objType", PaymentChangeType.refund.name()); this.getNamedParameterJdbcTemplate().update( - "UPDATE dw.refund SET fee = (SELECT dw.get_refund_fee(dw.cash_flow.*) " + - "FROM dw.cash_flow WHERE obj_id = :rfndId " + - "AND obj_type = CAST(:objType as dw.payment_change_type)), " + - "provider_fee = (SELECT dw.get_refund_provider_fee(dw.cash_flow.*) " + - "FROM dw.cash_flow WHERE obj_id = :rfndId " + - "AND obj_type = CAST(:objType as dw.payment_change_type)), " + - "external_fee = (SELECT dw.get_refund_external_fee(dw.cash_flow.*) " + - "FROM dw.cash_flow WHERE obj_id = :rfndId " + - "AND obj_type = CAST(:objType as dw.payment_change_type)) " + - "WHERE id = :rfndId", + """ + UPDATE dw.refund + SET + fee = ( + SELECT dw.get_refund_fee(dw.cash_flow.*) + FROM dw.cash_flow + WHERE obj_id = :rfndId + AND obj_type = CAST(:objType as dw.payment_change_type) + ), + provider_fee = ( + SELECT dw.get_refund_provider_fee(dw.cash_flow.*) + FROM dw.cash_flow + WHERE obj_id = :rfndId + AND obj_type = CAST(:objType as dw.payment_change_type) + ), + external_fee = ( + SELECT dw.get_refund_external_fee(dw.cash_flow.*) + FROM dw.cash_flow + WHERE obj_id = :rfndId + AND obj_type = CAST(:objType as dw.payment_change_type) + ) + WHERE id = :rfndId""", params); } diff --git a/src/main/resources/db/migration/V1__init.sql b/src/main/resources/db/migration/V1__init.sql index 0fbee282..08a3f75f 100644 --- a/src/main/resources/db/migration/V1__init.sql +++ b/src/main/resources/db/migration/V1__init.sql @@ -1677,4 +1677,134 @@ CREATE TABLE dw.withdrawal_session CREATE INDEX withdrawal_session_event_created_at_idx ON dw.withdrawal_session USING btree (event_created_at); CREATE INDEX withdrawal_session_event_occured_at_idx ON dw.withdrawal_session USING btree (event_occured_at); -CREATE INDEX withdrawal_session_id_idx ON dw.withdrawal_session USING btree (withdrawal_session_id); \ No newline at end of file +CREATE INDEX withdrawal_session_id_idx ON dw.withdrawal_session USING btree (withdrawal_session_id); + + +-- FUNCTION + +CREATE FUNCTION dw.get_cashflow_sum(_cash_flow dw.cash_flow, obj_type dw.payment_change_type, + source_account_type dw.cash_flow_account, + source_account_type_values character varying[], + destination_account_type dw.cash_flow_account, + destination_account_type_values character varying[]) RETURNS bigint + LANGUAGE plpgsql + IMMUTABLE PARALLEL SAFE +AS +$_$ +begin + return ( + coalesce( + ( + select amount + from (select ($1).*) as cash_flow + where cash_flow.obj_type = $2 + and cash_flow.source_account_type = $3 + and cash_flow.source_account_type_value = ANY ($4) + and cash_flow.destination_account_type = $5 + and cash_flow.destination_account_type_value = ANY ($6) + and ( + (cash_flow.obj_type = 'adjustment' and cash_flow.adj_flow_type = 'new_cash_flow') + or (cash_flow.obj_type != 'adjustment' and cash_flow.adj_flow_type is null) + ) + ), 0) + ); +end; +$_$; + + +CREATE FUNCTION dw.cashflow_sum_finalfunc(amount bigint) RETURNS bigint + LANGUAGE plpgsql + IMMUTABLE PARALLEL SAFE +AS +$$ +begin + return amount; +end; +$$; + + +CREATE FUNCTION dw.get_refund_fee_sfunc(amount bigint, cash_flow dw.cash_flow) RETURNS bigint + LANGUAGE plpgsql + IMMUTABLE PARALLEL SAFE +AS +$_$ +begin + return $1 + ( + dw.get_cashflow_sum( + $2, + 'refund'::dw.payment_change_type, + 'merchant'::dw.cash_flow_account, + '{"settlement"}', + 'system'::dw.cash_flow_account, + '{"settlement"}' + ) + ); +end; +$_$; + + +CREATE FUNCTION dw.get_refund_external_fee_sfunc(amount bigint, cash_flow dw.cash_flow) RETURNS bigint + LANGUAGE plpgsql + IMMUTABLE PARALLEL SAFE +AS +$_$ +begin + return $1 + ( + dw.get_cashflow_sum( + $2, + 'refund'::dw.payment_change_type, + 'system'::dw.cash_flow_account, + '{"settlement"}', + 'external'::dw.cash_flow_account, + '{"income", "outcome"}' + ) + ); +end; +$_$; + + +CREATE FUNCTION dw.get_refund_provider_fee_sfunc(amount bigint, cash_flow dw.cash_flow) RETURNS bigint + LANGUAGE plpgsql + IMMUTABLE PARALLEL SAFE +AS +$_$ +begin + return $1 + ( + dw.get_cashflow_sum( + $2, + 'refund'::dw.payment_change_type, + 'system'::dw.cash_flow_account, + '{"settlement"}', + 'provider'::dw.cash_flow_account, + '{"settlement"}' + ) + ); +end; +$_$; + + +-- AGGREGATE + +CREATE AGGREGATE dw.get_refund_external_fee(dw.cash_flow) ( + SFUNC = dw.get_refund_external_fee_sfunc, + STYPE = bigint, + INITCOND = '0', + FINALFUNC = dw.cashflow_sum_finalfunc, + PARALLEL = safe + ); + +CREATE AGGREGATE dw.get_refund_fee(dw.cash_flow) ( + SFUNC = dw.get_refund_fee_sfunc, + STYPE = bigint, + INITCOND = '0', + FINALFUNC = dw.cashflow_sum_finalfunc, + PARALLEL = safe + ); + +CREATE AGGREGATE dw.get_refund_provider_fee(dw.cash_flow) ( + SFUNC = dw.get_refund_provider_fee_sfunc, + STYPE = bigint, + INITCOND = '0', + FINALFUNC = dw.cashflow_sum_finalfunc, + PARALLEL = safe + ); \ No newline at end of file diff --git a/src/test/java/dev/vality/newway/dao/DaoTests.java b/src/test/java/dev/vality/newway/dao/DaoTests.java index 9ddf8b4b..c5e4a068 100644 --- a/src/test/java/dev/vality/newway/dao/DaoTests.java +++ b/src/test/java/dev/vality/newway/dao/DaoTests.java @@ -488,6 +488,8 @@ public void refundDaoTest() { assertEquals(refund, refundGet); refundDao.updateNotCurrent(refund.getId()); + refundDao.updateCommissions(refund.getId()); + assertThrows(NotFoundException.class, () -> refundDao.get(refund.getInvoiceId(), refund.getPaymentId(), refund.getRefundId())); }