Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
<dependency>
<groupId>dev.vality</groupId>
<artifactId>damsel</artifactId>
<version>1.695-25e75a5</version>
<version>1.696-b07c077</version>
</dependency>
<dependency>
<groupId>dev.vality</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ public void handle(InvoiceChange invoiceChange, MachineEvent event, Integer chan
invoicePaymentAdjustmentState.getStatusChange().getScenario().getTargetStatus(),
PaymentStatus.class);
adjustment.setPaymentStatus(paymentStatus);
} else if (invoicePaymentAdjustmentState.isSetTransactionInfo()) {
var transactionInfo = invoicePaymentAdjustmentState.getTransactionInfo().getScenario().getTrx();
if (transactionInfo.isSetAdditionalInfo()) {
adjustment.setTransactionInfoRrn(transactionInfo.getAdditionalInfo().getRrn());
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
import dev.vality.damsel.payment_processing.InvoicePaymentChange;
import dev.vality.daway.dao.invoicing.iface.AdjustmentDao;
import dev.vality.daway.dao.invoicing.iface.CashFlowDao;
import dev.vality.daway.dao.invoicing.iface.PaymentAdditionalInfoDao;
import dev.vality.daway.domain.enums.AdjustmentCashFlowType;
import dev.vality.daway.domain.enums.AdjustmentStatus;
import dev.vality.daway.domain.tables.pojos.Adjustment;
import dev.vality.daway.domain.tables.pojos.CashFlow;
import dev.vality.daway.domain.tables.pojos.PaymentAdditionalInfo;
import dev.vality.daway.factory.machine.event.MachineEventCopyFactory;
import dev.vality.daway.handler.event.stock.impl.invoicing.InvoicingHandler;
import dev.vality.daway.model.InvoicingKey;
import dev.vality.geck.common.util.TBaseUtil;
import dev.vality.geck.common.util.TypeUtil;
import dev.vality.geck.filter.Filter;
Expand All @@ -27,6 +30,7 @@
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

@Slf4j
@Component
Expand All @@ -35,6 +39,7 @@ public class InvoicePaymentAdjustmentStatusChangedHandler implements InvoicingHa

private final AdjustmentDao adjustmentDao;
private final CashFlowDao cashFlowDao;
private final PaymentAdditionalInfoDao paymentAdditionalInfoDao;
private final MachineEventCopyFactory<Adjustment, Integer> machineEventCopyFactory;

@Getter
Expand Down Expand Up @@ -92,6 +97,11 @@ public void handle(InvoiceChange invoiceChange, MachineEvent event, Integer chan
pcf.setObjId(id);
});
cashFlowDao.save(oldCashFlows);
applyTransactionInfoAdjustment(
adjustmentOld,
invoicePaymentAdjustmentStatus,
event,
changeId);
log.info("Adjustment status change has been saved, " +
"sequenceId={}, invoiceId={}, paymentId={}, adjustmentId={}",
sequenceId, invoiceId, paymentId, adjustmentId);
Expand All @@ -102,4 +112,30 @@ public void handle(InvoiceChange invoiceChange, MachineEvent event, Integer chan
sequenceId, invoiceId, paymentId, adjustmentId));
}

private void applyTransactionInfoAdjustment(
Adjustment adjustment,
InvoicePaymentAdjustmentStatus status,
MachineEvent event,
int changeId) {
if (!status.isSetCaptured() || adjustment.getTransactionInfoRrn() == null) {
return;
}
var invoiceId = adjustment.getInvoiceId();
var paymentId = adjustment.getPaymentId();
var key = InvoicingKey.buildKey(invoiceId, paymentId);
var currentAdditionalInfo = paymentAdditionalInfoDao.safeGet(invoiceId, paymentId);
var additionalInfo = currentAdditionalInfo == null
? new PaymentAdditionalInfo()
: new PaymentAdditionalInfo(currentAdditionalInfo);
additionalInfo.setId(null);
additionalInfo.setEventCreatedAt(TypeUtil.stringToLocalDateTime(event.getCreatedAt()));
additionalInfo.setInvoiceId(invoiceId);
additionalInfo.setPaymentId(paymentId);
additionalInfo.setRrn(adjustment.getTransactionInfoRrn());
additionalInfo.setSequenceId(event.getEventId());
additionalInfo.setChangeId(changeId);
paymentAdditionalInfoDao.saveBatch(List.of(additionalInfo));
paymentAdditionalInfoDao.switchCurrent(Set.of(key));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE dw.adjustment
ADD COLUMN transaction_info_rrn CHARACTER VARYING;
97 changes: 97 additions & 0 deletions src/test/java/dev/vality/daway/IntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,54 @@ void test() {
assertDuplication();
}

@Test
void transactionInfoAdjustmentIsAppliedOnlyWhenCaptured() {
cleanUpTables();
invoicingService.handleEvents(getInitialInvoicePaymentEvents(invoiceId, paymentId));

var transactionInfo = new TransactionInfo()
.setId("adjustedTrxId")
.setExtra(Map.of("source", "dispute"))
.setAdditionalInfo(new AdditionalTransactionInfo().setRrn("adjustedRrn"));
invoicingService.handleEvents(List.of(createTransactionInfoAdjustmentCreatedEvent(2, transactionInfo)));
assertEquals("adjustedRrn", jdbcTemplate.queryForObject(
"SELECT transaction_info_rrn FROM dw.adjustment WHERE current",
String.class));
assertCurrentTransactionInfo("trxId", null);

invoicingService.handleEvents(List.of(createAdjustmentStatusChangedEvent(
3,
InvoicePaymentAdjustmentStatus.processed(new InvoicePaymentAdjustmentProcessed()))));
assertCurrentTransactionInfo("trxId", null);

invoicingService.handleEvents(List.of(createAdjustmentStatusChangedEvent(
4,
InvoicePaymentAdjustmentStatus.captured(
new InvoicePaymentAdjustmentCaptured().setAt("2026-07-13T14:00:00Z")))));
assertCurrentTransactionInfo("trxId", "adjustedRrn");
}

@Test
void cancelledTransactionInfoAdjustmentIsNotApplied() {
cleanUpTables();
invoicingService.handleEvents(getInitialInvoicePaymentEvents(invoiceId, paymentId));

var transactionInfo = new TransactionInfo()
.setId("cancelledTrxId")
.setExtra(Map.of())
.setAdditionalInfo(new AdditionalTransactionInfo().setRrn("cancelledRrn"));
invoicingService.handleEvents(List.of(createTransactionInfoAdjustmentCreatedEvent(2, transactionInfo)));
invoicingService.handleEvents(List.of(createAdjustmentStatusChangedEvent(
3,
InvoicePaymentAdjustmentStatus.processed(new InvoicePaymentAdjustmentProcessed()))));
invoicingService.handleEvents(List.of(createAdjustmentStatusChangedEvent(
4,
InvoicePaymentAdjustmentStatus.cancelled(
new InvoicePaymentAdjustmentCancelled().setAt("2026-07-13T14:00:00Z")))));

assertCurrentTransactionInfo("trxId", null);
}

@NotNull
private List<MachineEvent> getInitialInvoicePaymentEvents(String invoiceId, String paymentId) {
return List.of(
Expand Down Expand Up @@ -396,6 +444,54 @@ private List<MachineEvent> getInvoicePaymentFailedChange(String invoiceId, Strin
);
}

private MachineEvent createTransactionInfoAdjustmentCreatedEvent(long eventId, TransactionInfo transactionInfo) {
var adjustment = new InvoicePaymentAdjustment()
.setId("transactionInfoAdjustment")
.setStatus(InvoicePaymentAdjustmentStatus.pending(
new dev.vality.damsel.domain.InvoicePaymentAdjustmentPending()))
.setCreatedAt("2026-07-13T14:00:00Z")
.setDomainRevision(1)
.setReason("providerCallbackId=test")
.setNewCashFlow(List.of())
.setOldCashFlowInverse(List.of())
.setState(InvoicePaymentAdjustmentState.transaction_info(
new InvoicePaymentAdjustmentTransactionInfoState()
.setScenario(new InvoicePaymentAdjustmentTransactionInfo(transactionInfo))));
var payload = InvoicePaymentChangePayload.invoice_payment_adjustment_change(
new InvoicePaymentAdjustmentChange()
.setId(adjustment.getId())
.setPayload(InvoicePaymentAdjustmentChangePayload.invoice_payment_adjustment_created(
new InvoicePaymentAdjustmentCreated(adjustment))));
return createPaymentChangeEvent(eventId, payload);
}

private MachineEvent createAdjustmentStatusChangedEvent(
long eventId,
InvoicePaymentAdjustmentStatus status) {
var payload = InvoicePaymentChangePayload.invoice_payment_adjustment_change(
new InvoicePaymentAdjustmentChange()
.setId("transactionInfoAdjustment")
.setPayload(InvoicePaymentAdjustmentChangePayload.invoice_payment_adjustment_status_changed(
new InvoicePaymentAdjustmentStatusChanged(status))));
return createPaymentChangeEvent(eventId, payload);
}

private MachineEvent createPaymentChangeEvent(long eventId, InvoicePaymentChangePayload payload) {
var change = InvoiceChange.invoice_payment_change(
new InvoicePaymentChange().setId(paymentId).setPayload(payload));
return new MachineEvent()
.setSourceId(invoiceId)
.setEventId(eventId)
.setCreatedAt("2026-07-13T14:00:00Z")
.setData(Value.bin(serializer.serialize(EventPayload.invoice_changes(List.of(change)))));
}

private void assertCurrentTransactionInfo(String transactionId, String rrn) {
var paymentAdditionalInfo = paymentAdditionalInfoDao.get(invoiceId, paymentId);
assertEquals(transactionId, paymentAdditionalInfo.getTransactionId());
assertEquals(rrn, paymentAdditionalInfo.getRrn());
}

private void cleanUpTables() {
jdbcTemplate.execute("truncate table dw.invoice cascade");
jdbcTemplate.execute("truncate table dw.invoice_status_info cascade");
Expand All @@ -410,6 +506,7 @@ private void cleanUpTables() {
jdbcTemplate.execute("truncate table dw.payment_route cascade");
jdbcTemplate.execute("truncate table dw.cash_flow_link cascade");
jdbcTemplate.execute("truncate table dw.cash_flow cascade");
jdbcTemplate.execute("truncate table dw.adjustment cascade");
}

private void assertDuplication() {
Expand Down
Loading