Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix adjustments #25

Merged
merged 3 commits into from
Oct 31, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public interface CallbackNotifier {

void sendDisputePoolingExpired(Dispute dispute);

void sendDisputeReadyForCreateAdjustment(List<Dispute> disputes);
void sendDisputesReadyForCreateAdjustment(List<Dispute> disputes);
Copy link
Collaborator Author

@karle0wne karle0wne Oct 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d1183c8

  • в AccessService проверяется платеж, если не финальный статус, то возвращается 400 наружу (то есть не даем создать диспут в нефинальном статусе платежа) . все таки когда даем создать диспут, не учитывая статус платежа мы создаем пространство для коллизий: 1) платеж%пендинг диспут%создали , затем платеж%успех диспут%идет_в_провайдера - диспут успех на успех платежа? 2) платеж%пендинг диспут%создали , затем платеж%успех диспут%успех(сразу) - то есть это спор с тем что платеж в пендинге был? 3) более выраженный кейс когда создается диспут при платеже в captured для изменения суммы , иначе нам как то разелять , что отдельно есть запрос captured для изменения суммы и отдельно запрос когда платеж был pending а стал captured (диспут для которого надо в успех финалить) . будет проще - пендинг - нехуй лезть, убьет
  • преименовал sendDisputeReady
  • переименовал CreateAdjustments* в Adjustments
  • сложил основные сервисы в пакет .core.*
  • убрал проверку в пакете .core.* if (!status.isSetCaptured() && !status.isSetCancelled() && !status.isSetFailed()) { (тк переносим на AccessService
  • при такой логике тест testSkipDisputeWhenPaymentNonFinalStatus не актуален


void sendDisputeFailedReviewRequired(Dispute dispute, String errorCode, String errorDescription);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ public void sendDisputePoolingExpired(Dispute dispute) {
}

@Override
public void sendDisputeReadyForCreateAdjustment(List<Dispute> disputes) {
public void sendDisputesReadyForCreateAdjustment(List<Dispute> disputes) {
var disputeReadyForCreateAdjustments = disputes.stream()
.map(Dispute::getId)
.map(UUID::toString)
.map(DisputeReadyForCreateAdjustment::new)
.toList();
disputesTgBotService.sendDisputeReadyForCreateAdjustment(disputeReadyForCreateAdjustments);
disputesTgBotService.sendDisputesReadyForCreateAdjustment(disputeReadyForCreateAdjustments);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void sendDisputePoolingExpired(Dispute dispute) {
}

@Override
public void sendDisputeReadyForCreateAdjustment(List<Dispute> disputes) {
public void sendDisputesReadyForCreateAdjustment(List<Dispute> disputes) {
log.debug("Trying to call DummyCallbackNotifierImpl.sendDisputeReadyForCreateAdjustment() {}", disputes.size());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.vality.disputes.api.controller;

import dev.vality.disputes.exception.AuthorizationException;
import dev.vality.disputes.exception.InvoicingPaymentStatusPendingException;
import dev.vality.disputes.exception.NotFoundException;
import dev.vality.disputes.exception.TokenKeeperException;
import dev.vality.swag.disputes.model.GeneralError;
Expand Down Expand Up @@ -35,6 +36,14 @@ public class ErrorControllerAdvice {

// ----------------- 4xx -----------------------------------------------------

@ExceptionHandler({InvoicingPaymentStatusPendingException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Object handleInvalidMimeTypeException(InvoicingPaymentStatusPendingException e) {
log.warn("<- Res [400]: Payment has non-final status", e);
return new GeneralError()
.message("Payment has non-final status");
}

@ExceptionHandler({InvalidMimeTypeException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Object handleInvalidMimeTypeException(InvalidMimeTypeException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ public class InvoicingPaymentStatusPendingException extends RuntimeException {
public InvoicingPaymentStatusPendingException(Throwable cause) {
super(cause);
}

public InvoicingPaymentStatusPendingException() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import dev.vality.disputes.admin.callback.CallbackNotifier;
import dev.vality.disputes.admin.management.MdcTopicProducer;
import dev.vality.disputes.schedule.service.CreateAdjustmentsService;
import dev.vality.disputes.schedule.core.AdjustmentsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
Expand All @@ -14,18 +14,18 @@
@Service
@RequiredArgsConstructor
@SuppressWarnings({"ParameterName", "LineLength", "MissingSwitchDefault"})
public class TaskReadyForCreateAdjustmentsService {
public class AdjustmentsReadyNotificationTask {

private final CreateAdjustmentsService createAdjustmentsService;
private final AdjustmentsService adjustmentsService;
private final CallbackNotifier callbackNotifier;
private final MdcTopicProducer mdcTopicProducer;

@Scheduled(fixedDelayString = "${dispute.fixedDelayReadyForCreateAdjustments}", initialDelayString = "${dispute.initialDelayReadyForCreateAdjustments}")
public void processPending() {
log.debug("Processing ReadyForCreateAdjustments get started");
var disputes = createAdjustmentsService.getReadyDisputesForCreateAdjustment();
var disputes = adjustmentsService.getReadyDisputesForCreateAdjustment();
mdcTopicProducer.sendReadyForCreateAdjustments(disputes);
callbackNotifier.sendDisputeReadyForCreateAdjustment(disputes);
callbackNotifier.sendDisputesReadyForCreateAdjustment(disputes);
log.info("ReadyForCreateAdjustments were processed");
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package dev.vality.disputes.schedule;

import dev.vality.disputes.domain.tables.pojos.Dispute;
import dev.vality.disputes.schedule.handler.CreateAdjustmentHandler;
import dev.vality.disputes.schedule.service.CreateAdjustmentsService;
import dev.vality.disputes.schedule.core.AdjustmentsService;
import dev.vality.disputes.schedule.handler.AdjustmentHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -20,18 +20,18 @@
@Service
@RequiredArgsConstructor
@SuppressWarnings({"ParameterName", "LineLength", "MissingSwitchDefault"})
public class TaskCreateAdjustmentsService {
public class AdjustmentsTask {

private final ExecutorService disputesThreadPool;
private final CreateAdjustmentsService createAdjustmentsService;
private final AdjustmentsService adjustmentsService;
@Value("${dispute.batchSize}")
private int batchSize;

@Scheduled(fixedDelayString = "${dispute.fixedDelayCreateAdjustments}", initialDelayString = "${dispute.initialDelayCreateAdjustments}")
public void processPending() {
log.debug("Processing create adjustments get started");
try {
var disputes = createAdjustmentsService.getDisputesForHgCall(batchSize);
var disputes = adjustmentsService.getDisputesForHgCall(batchSize);
var callables = disputes.stream()
.map(this::handleCreateAdjustment)
.collect(Collectors.toList());
Expand All @@ -46,6 +46,6 @@ public void processPending() {
}

private Callable<UUID> handleCreateAdjustment(Dispute dispute) {
return () -> new CreateAdjustmentHandler(createAdjustmentsService).handle(dispute);
return () -> new AdjustmentHandler(adjustmentsService).handle(dispute);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package dev.vality.disputes.schedule;

import dev.vality.disputes.domain.tables.pojos.Dispute;
import dev.vality.disputes.schedule.core.CreatedDisputesService;
import dev.vality.disputes.schedule.handler.CreatedDisputeHandler;
import dev.vality.disputes.schedule.service.CreatedDisputesService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -19,7 +19,7 @@
@ConditionalOnProperty(value = "dispute.isScheduleCreatedEnabled", havingValue = "true")
@Service
@RequiredArgsConstructor
public class TaskCreatedDisputesService {
public class CreatedDisputesTask {

private final ExecutorService disputesThreadPool;
private final CreatedDisputesService createdDisputesService;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package dev.vality.disputes.schedule;

import dev.vality.disputes.domain.tables.pojos.Dispute;
import dev.vality.disputes.schedule.core.PendingDisputesService;
import dev.vality.disputes.schedule.handler.PendingDisputeHandler;
import dev.vality.disputes.schedule.service.PendingDisputesService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -19,7 +19,7 @@
@ConditionalOnProperty(value = "dispute.isSchedulePendingEnabled", havingValue = "true")
@Service
@RequiredArgsConstructor
public class TaskPendingDisputesService {
public class PendingDisputesTask {

private final ExecutorService disputesThreadPool;
private final PendingDisputesService pendingDisputesService;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,31 @@
package dev.vality.disputes.schedule.converter;

import dev.vality.damsel.domain.*;
import dev.vality.damsel.domain.InvoicePaymentAdjustmentStatusChange;
import dev.vality.damsel.domain.InvoicePaymentCaptured;
import dev.vality.damsel.domain.InvoicePaymentStatus;
import dev.vality.damsel.payment_processing.InvoicePaymentAdjustmentParams;
import dev.vality.damsel.payment_processing.InvoicePaymentAdjustmentScenario;
import dev.vality.disputes.domain.tables.pojos.Dispute;
import dev.vality.disputes.schedule.service.AdjustmentExtractor;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class InvoicePaymentAdjustmentParamsConverter {
@RequiredArgsConstructor
public class InvoicePaymentCapturedAdjustmentParamsConverter {

public static final String DISPUTE_MASK = "disputeId=%s";
private final AdjustmentExtractor adjustmentExtractor;

public InvoicePaymentAdjustmentParams convert(Dispute dispute) {
var captured = new InvoicePaymentCaptured();
var reason = getReason(dispute);
var reason = adjustmentExtractor.getReason(dispute);
captured.setReason(reason);
var changedAmount = dispute.getChangedAmount();
if (changedAmount != null) {
var cost = new Cash(changedAmount, new CurrencyRef(dispute.getCurrencySymbolicCode()));
captured.setCost(cost);
}
var params = new InvoicePaymentAdjustmentParams();
params.setReason(reason);
params.setScenario(getInvoicePaymentAdjustmentScenario(captured));
return params;
}

public String getReason(Dispute dispute) {
return Optional.ofNullable(dispute.getReason())
.map(s -> String.format(DISPUTE_MASK + ", reason=%s", dispute.getId(), s))
.orElse(String.format(DISPUTE_MASK, dispute.getId()));
}

private InvoicePaymentAdjustmentScenario getInvoicePaymentAdjustmentScenario(InvoicePaymentCaptured captured) {
return InvoicePaymentAdjustmentScenario.status_change(new InvoicePaymentAdjustmentStatusChange(
InvoicePaymentStatus.captured(captured)));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.vality.disputes.schedule.converter;

import dev.vality.damsel.domain.InvoicePaymentAdjustmentCashFlow;
import dev.vality.damsel.domain.InvoicePaymentCaptured;
import dev.vality.damsel.payment_processing.InvoicePaymentAdjustmentParams;
import dev.vality.damsel.payment_processing.InvoicePaymentAdjustmentScenario;
import dev.vality.disputes.domain.tables.pojos.Dispute;
import dev.vality.disputes.schedule.service.AdjustmentExtractor;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class InvoicePaymentCashFlowAdjustmentParamsConverter {

private final AdjustmentExtractor adjustmentExtractor;

public InvoicePaymentAdjustmentParams convert(Dispute dispute) {
var captured = new InvoicePaymentCaptured();
var reason = adjustmentExtractor.getReason(dispute);
captured.setReason(reason);
var params = new InvoicePaymentAdjustmentParams();
params.setReason(reason);
params.setScenario(getInvoicePaymentAdjustmentScenario(dispute.getChangedAmount()));
return params;
}

private InvoicePaymentAdjustmentScenario getInvoicePaymentAdjustmentScenario(Long changedAmount) {
return InvoicePaymentAdjustmentScenario.cash_flow(new InvoicePaymentAdjustmentCashFlow()
.setNewAmount(changedAmount));
karle0wne marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.vality.disputes.schedule.converter;

import dev.vality.damsel.domain.*;
import dev.vality.damsel.payment_processing.InvoicePaymentAdjustmentParams;
import dev.vality.damsel.payment_processing.InvoicePaymentAdjustmentScenario;
import dev.vality.disputes.domain.tables.pojos.Dispute;
import dev.vality.disputes.schedule.service.AdjustmentExtractor;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class InvoicePaymentFailedAdjustmentParamsConverter {

private final AdjustmentExtractor adjustmentExtractor;

public InvoicePaymentAdjustmentParams convert(Dispute dispute) {
var invoicePaymentFailed = new InvoicePaymentFailed();
var reason = adjustmentExtractor.getReason(dispute);
invoicePaymentFailed.setFailure(OperationFailure.failure(
new Failure("failed_by_disputes_api").setReason(reason)));
var params = new InvoicePaymentAdjustmentParams();
params.setReason(reason);
params.setScenario(getInvoicePaymentAdjustmentScenario(invoicePaymentFailed));
return params;
}

private InvoicePaymentAdjustmentScenario getInvoicePaymentAdjustmentScenario(InvoicePaymentFailed failed) {
return InvoicePaymentAdjustmentScenario.status_change(new InvoicePaymentAdjustmentStatusChange(
InvoicePaymentStatus.failed(failed)));
}
}
Loading
Loading