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

feat: P4ADEV-1933-add-activity-debt-position-expiration #106

Merged
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
@@ -0,0 +1,25 @@
package it.gov.pagopa.payhub.activities.activity.debtposition;

import io.temporal.activity.ActivityInterface;
import io.temporal.activity.ActivityMethod;

import java.time.OffsetDateTime;

/**
* Service interface responsible for handling the expiration process of a debt position.
* This activity checks and updates the expiration status based on its installments.
*/
@ActivityInterface
public interface DebtPositionExpirationActivity {

/**
* Checks the expiration status of the installments linked to a specific debt position
* and updates the overall status of the debt position accordingly.
*
* @param debtPositionId the unique identifier of the debt position to be processed.
* @return the minimum due date ({@link OffsetDateTime}) among all unpaid installments,
* or {@code null} if no unpaid installments exist.
*/
@ActivityMethod
OffsetDateTime checkAndUpdateInstallmentExpiration(Long debtPositionId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package it.gov.pagopa.payhub.activities.activity.debtposition;

import it.gov.pagopa.payhub.activities.connector.debtposition.DebtPositionService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.time.OffsetDateTime;

@Lazy
@Service
public class DebtPositionExpirationActivityImpl implements DebtPositionExpirationActivity{

private final DebtPositionService debtPositionService;

public DebtPositionExpirationActivityImpl(DebtPositionService debtPositionService) {
this.debtPositionService = debtPositionService;
}

@Override
public OffsetDateTime checkAndUpdateInstallmentExpiration(Long debtPositionId) {
return debtPositionService.checkAndUpdateInstallmentExpiration(debtPositionId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import it.gov.pagopa.pu.debtposition.dto.generated.DebtPositionDTO;
import it.gov.pagopa.pu.debtposition.dto.generated.IupdSyncStatusUpdateDTO;

import java.time.OffsetDateTime;
import java.util.Map;

/**
Expand All @@ -18,4 +19,11 @@ public interface DebtPositionService {
*/
DebtPositionDTO finalizeSyncStatus(Long debtPositionId, Map<String, IupdSyncStatusUpdateDTO> syncStatusUpdateDTO);

/**
* Checks and updates the expiration date of the installments associated to a debt position
*
* @param debtPositionId the unique identifier of the debt position to be processed.
* @return the minimum due date ({@link OffsetDateTime}) among all unpaid installments
*/
OffsetDateTime checkAndUpdateInstallmentExpiration(Long debtPositionId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
import it.gov.pagopa.payhub.activities.connector.auth.AuthnService;
import it.gov.pagopa.payhub.activities.connector.debtposition.client.DebtPositionClient;
import it.gov.pagopa.pu.debtposition.dto.generated.DebtPositionDTO;
import it.gov.pagopa.pu.debtposition.dto.generated.InstallmentDTO;
import it.gov.pagopa.pu.debtposition.dto.generated.IupdSyncStatusUpdateDTO;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.time.OffsetDateTime;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

@Lazy
@Service
Expand All @@ -26,4 +30,19 @@ public DebtPositionDTO finalizeSyncStatus(Long debtPositionId, Map<String, IupdS
String accessToken = authnService.getAccessToken();
return debtPositionClient.finalizeSyncStatus(accessToken, debtPositionId, syncStatusUpdateDTO);
}

@Override
public OffsetDateTime checkAndUpdateInstallmentExpiration(Long debtPositionId) {
String accessToken = authnService.getAccessToken();
DebtPositionDTO debtPositionDTO = debtPositionClient.checkAndUpdateInstallmentExpiration(accessToken, debtPositionId);

Optional<OffsetDateTime> dueDate = debtPositionDTO.getPaymentOptions().stream()
.flatMap(paymentOption -> paymentOption.getInstallments().stream())
.filter(installment -> InstallmentDTO.StatusEnum.UNPAID.equals(installment.getStatus()))
.map(InstallmentDTO::getDueDate)
.filter(Objects::nonNull)
.min(OffsetDateTime::compareTo);

return dueDate.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ public DebtPositionClient(DebtPositionApisHolder debtPositionApisHolder) {
public DebtPositionDTO finalizeSyncStatus(String accessToken, Long debtPositionId, Map<String, IupdSyncStatusUpdateDTO> syncStatusUpdateDTO){
return debtPositionApisHolder.getDebtPositionApi(accessToken).finalizeSyncStatus(debtPositionId, syncStatusUpdateDTO);
}

public DebtPositionDTO checkAndUpdateInstallmentExpiration(String accessToken, Long debtPositionId){
return debtPositionApisHolder.getDebtPositionApi(accessToken).checkAndUpdateInstallmentExpiration(debtPositionId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package it.gov.pagopa.payhub.activities.activity.debtposition;

import it.gov.pagopa.payhub.activities.connector.debtposition.DebtPositionService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import java.time.OffsetDateTime;

import static it.gov.pagopa.payhub.activities.util.TestUtils.OFFSETDATETIME;
import static org.junit.jupiter.api.Assertions.assertSame;

@ExtendWith(MockitoExtension.class)
class DebtPositionExpirationActivityTest {

@Mock
private DebtPositionService debtPositionServiceMock;

private DebtPositionExpirationActivity activity;

@BeforeEach
void init() {
activity = new DebtPositionExpirationActivityImpl(debtPositionServiceMock);
}

@AfterEach
void verifyNoMoreInteractions(){
Mockito.verifyNoMoreInteractions(debtPositionServiceMock);
}

@Test
void givenCheckAndUpdateInstallmentExpirationThenOk(){
Mockito.when(debtPositionServiceMock.checkAndUpdateInstallmentExpiration(1L))
.thenReturn(OFFSETDATETIME);

OffsetDateTime offsetDateTime = activity.checkAndUpdateInstallmentExpiration(1L);

Mockito.verify(debtPositionServiceMock, Mockito.times(1))
.checkAndUpdateInstallmentExpiration(1L);
assertSame(OFFSETDATETIME, offsetDateTime);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import it.gov.pagopa.payhub.activities.connector.auth.AuthnService;
import it.gov.pagopa.payhub.activities.connector.debtposition.client.DebtPositionClient;
import it.gov.pagopa.pu.debtposition.dto.generated.DebtPositionDTO;
import it.gov.pagopa.pu.debtposition.dto.generated.InstallmentDTO;
import it.gov.pagopa.pu.debtposition.dto.generated.IupdSyncStatusUpdateDTO;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -11,8 +13,13 @@
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import java.time.OffsetDateTime;
import java.util.List;
import java.util.Map;

import static it.gov.pagopa.payhub.activities.util.faker.DebtPositionFaker.buildDebtPositionDTO;
import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(MockitoExtension.class)
class DebtPositionServiceTest {

Expand Down Expand Up @@ -53,4 +60,57 @@ void whenFinalizeSyncStatusThenInvokeClient() {
// Then
Mockito.verify(debtPositionClientMock).finalizeSyncStatus(accessToken, 0L, Map.of("iud", iupdSyncStatusUpdateDTO));
}

@Test
void givenCheckAndUpdateInstallmentExpirationThenOk() {
// Given
String accessToken = "ACCESSTOKEN";
DebtPositionDTO debtPositionDTO = buildDebtPositionDTO();
InstallmentDTO.StatusEnum unpaidStatus = InstallmentDTO.StatusEnum.UNPAID;
OffsetDateTime now = OffsetDateTime.now();

InstallmentDTO installment1 = new InstallmentDTO();
installment1.setStatus(unpaidStatus);
installment1.setDueDate(now.plusDays(10));

InstallmentDTO installment2 = new InstallmentDTO();
installment2.setStatus(unpaidStatus);
installment2.setDueDate(now.plusDays(5));

debtPositionDTO.getPaymentOptions().getFirst().setInstallments(List.of(installment1, installment2));

Mockito.when(authnServiceMock.getAccessToken())
.thenReturn(accessToken);

Mockito.when(debtPositionClientMock.checkAndUpdateInstallmentExpiration(accessToken, 1L))
.thenReturn(debtPositionDTO);

// When
OffsetDateTime dueDate = debtPositionService.checkAndUpdateInstallmentExpiration(1L);

// Then
assertNotNull(dueDate);
assertEquals(installment2.getDueDate(), dueDate);
Mockito.verify(debtPositionClientMock).checkAndUpdateInstallmentExpiration(accessToken, 1L);
}

@Test
void givenCheckAndUpdateInstallmentExpirationWhenInstallmentIsNotUnpaidThenNull() {
// Given
String accessToken = "ACCESSTOKEN";
DebtPositionDTO debtPositionDTO = buildDebtPositionDTO();

Mockito.when(authnServiceMock.getAccessToken())
.thenReturn(accessToken);

Mockito.when(debtPositionClientMock.checkAndUpdateInstallmentExpiration(accessToken,1L))
.thenReturn(debtPositionDTO);

// When
OffsetDateTime dueDate = debtPositionService.checkAndUpdateInstallmentExpiration(1L);

// Then
assertNull(dueDate);
Mockito.verify(debtPositionClientMock).checkAndUpdateInstallmentExpiration(accessToken,1L);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,24 @@ void whenFinalizeSyncStatusThenInvokeWithAccessToken(){
// Then
Assertions.assertSame(expectedResult, result);
}

@Test
void givenCheckAndUpdateInstallmentExpirationThenOk(){
// Given
String accessToken = "ACCESSTOKEN";
Long debtPositionId = 0L;

DebtPositionDTO expectedResult = buildDebtPositionDTO();

Mockito.when(debtPositionApisHolderMock.getDebtPositionApi(accessToken))
.thenReturn(debtPositionApiMock);
Mockito.when(debtPositionApiMock.checkAndUpdateInstallmentExpiration(debtPositionId))
.thenReturn(expectedResult);

// When
DebtPositionDTO result = debtPositionClient.checkAndUpdateInstallmentExpiration(accessToken, debtPositionId);

// Then
Assertions.assertSame(expectedResult, result);
}
}
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.45.5
1.46.0-SNAPSHOT