From bd592f54e95fb052f64c3930e5efff5595c5f693 Mon Sep 17 00:00:00 2001 From: eugenbegiqi <146853548+eugenbegiqi@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:31:18 +0200 Subject: [PATCH] [SELC-5169] feat : Added record PecNotification in persistOnboarding (#525) --- .../resources/config/core-config.properties | 5 +- .../mscore/constant/GenericError.java | 4 +- .../pecnotification/PecNotification.java | 1 + .../dao/PecNotificationConnectorImpl.java | 2 +- .../dao/PecNotificationRepository.java | 1 + .../dao/model/PecNotificationEntity.java | 3 +- .../dao/PecNotificationConnectorImplTest.java | 4 +- .../mscore/core/OnboardingServiceImpl.java | 47 +++++++++++++++++-- .../core/OnboardingServiceImplTest.java | 42 ++++++++++++++--- 9 files changed, 93 insertions(+), 16 deletions(-) diff --git a/app/src/main/resources/config/core-config.properties b/app/src/main/resources/config/core-config.properties index 8f8e3dd7..9a5ec02e 100644 --- a/app/src/main/resources/config/core-config.properties +++ b/app/src/main/resources/config/core-config.properties @@ -25,4 +25,7 @@ mscore.blob-storage.connection-string-product = ${BLOB_STORAGE_PRODUCT_CONNECTIO #SES mscore.aws-ses-secret-id=${AWS_SES_ACCESS_KEY_ID:secret-id-example} mscore.aws-ses-secret-key=${AWS_SES_SECRET_ACCESS_KEY:secret-key-example} -mscore.aws-ses-region=${AWS_SES_REGION:eu-south-1} \ No newline at end of file +mscore.aws-ses-region=${AWS_SES_REGION:eu-south-1} + +mscore.sending-frequency-pec-notification=${SENDING_FREQUENCY_PEC_NOTIFICATION:30} +mscore.epoch-date-pec-notification=${EPOCH_DATE_PEC_NOTIFICATION:2024-01-01} \ No newline at end of file diff --git a/connector-api/src/main/java/it/pagopa/selfcare/mscore/constant/GenericError.java b/connector-api/src/main/java/it/pagopa/selfcare/mscore/constant/GenericError.java index e72036ce..c7b0911b 100644 --- a/connector-api/src/main/java/it/pagopa/selfcare/mscore/constant/GenericError.java +++ b/connector-api/src/main/java/it/pagopa/selfcare/mscore/constant/GenericError.java @@ -63,7 +63,9 @@ public enum GenericError { UPDATE_USER_INSTITUTION_ERROR("0000", "Error while updating InstitutionUser for id %s"), GENERIC_ERROR("0000", "Generic Error"), DELETE_ONBOARDED_OPERATION_ERROR("0000", "Error while deleting Onboarded Institution"), - DELETE_NOTIFICATION_OPERATION_ERROR ("0000", "PecNotificationEntity was not deleted because either it does not exist or there are multiple records"); + DELETE_NOTIFICATION_OPERATION_ERROR ("0000", "PecNotificationEntity was not deleted because either it does not exist or there are multiple records"), + INVALID_INSERT_PEC_NOTIFICATION_ERROR ("0001", "PecNotificationEntity was not inserted because either it exist or the data are invalid"); + private final String code; private final String detail; diff --git a/connector-api/src/main/java/it/pagopa/selfcare/mscore/model/pecnotification/PecNotification.java b/connector-api/src/main/java/it/pagopa/selfcare/mscore/model/pecnotification/PecNotification.java index a7ccb420..f6fcf923 100644 --- a/connector-api/src/main/java/it/pagopa/selfcare/mscore/model/pecnotification/PecNotification.java +++ b/connector-api/src/main/java/it/pagopa/selfcare/mscore/model/pecnotification/PecNotification.java @@ -16,6 +16,7 @@ public class PecNotification { private String institutionId; private String productId; private Integer moduleDayOfTheEpoch; + private String digitalAddress; private OffsetDateTime createdAt; private OffsetDateTime updatedAt; diff --git a/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationConnectorImpl.java b/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationConnectorImpl.java index ed51e378..c6ee1c3c 100644 --- a/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationConnectorImpl.java +++ b/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationConnectorImpl.java @@ -52,7 +52,7 @@ public boolean insertPecNotification(PecNotification pecNotification){ PecNotificationEntity pecNotificationEntity = this.pecNotificationMapper.convertToPecNotificationEntity(pecNotification); - boolean exist = repository.existsById(pecNotificationEntity.getId()); + boolean exist = repository.existsByInstitutionIdAndProductId(pecNotificationEntity.getInstitutionId(), pecNotificationEntity.getProductId()); if (exist){ log.trace("Cannot insert the PecNotification: {}, as it already exists in the collection", pecNotification.toString()); diff --git a/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationRepository.java b/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationRepository.java index 6518201f..87c8f85b 100644 --- a/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationRepository.java +++ b/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationRepository.java @@ -4,4 +4,5 @@ import org.springframework.data.mongodb.repository.MongoRepository; public interface PecNotificationRepository extends MongoRepository, MongoCustomConnector { + boolean existsByInstitutionIdAndProductId(String institutionId, String productId); } diff --git a/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/model/PecNotificationEntity.java b/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/model/PecNotificationEntity.java index 6f5350f3..ac2c57ab 100644 --- a/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/model/PecNotificationEntity.java +++ b/connector/dao/src/main/java/it/pagopa/selfcare/mscore/connector/dao/model/PecNotificationEntity.java @@ -1,6 +1,5 @@ package it.pagopa.selfcare.mscore.connector.dao.model; -import it.pagopa.selfcare.mscore.connector.dao.model.inner.UserBindingEntity; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.FieldNameConstants; @@ -9,7 +8,6 @@ import org.springframework.data.mongodb.core.mapping.Sharded; import java.time.OffsetDateTime; -import java.util.List; @Data @NoArgsConstructor @@ -23,6 +21,7 @@ public class PecNotificationEntity { private String institutionId; private String productId; private Integer moduleDayOfTheEpoch; + private String digitalAddress; private OffsetDateTime createdAt; private OffsetDateTime updatedAt; diff --git a/connector/dao/src/test/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationConnectorImplTest.java b/connector/dao/src/test/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationConnectorImplTest.java index 4297e362..43d6f950 100644 --- a/connector/dao/src/test/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationConnectorImplTest.java +++ b/connector/dao/src/test/java/it/pagopa/selfcare/mscore/connector/dao/PecNotificationConnectorImplTest.java @@ -84,7 +84,7 @@ void findAndDeletePecNotification_notExist() { @Test void insertPecNotification_success() { when(pecNotificationMapper.convertToPecNotificationEntity(pecNotification)).thenReturn(pecNotificationEntity); - when(repository.existsById(pecNotificationEntity.getId())).thenReturn(false); + when(repository.existsByInstitutionIdAndProductId(any(), any())).thenReturn(false); boolean result = pecNotificationConnector.insertPecNotification(pecNotification); @@ -95,7 +95,7 @@ void insertPecNotification_success() { @Test void insertPecNotification_alreadyExists() { when(pecNotificationMapper.convertToPecNotificationEntity(pecNotification)).thenReturn(pecNotificationEntity); - when(repository.existsById(pecNotificationEntity.getId())).thenReturn(true); + when(repository.existsByInstitutionIdAndProductId(any(), any())).thenReturn(true); boolean result = pecNotificationConnector.insertPecNotification(pecNotification); diff --git a/core/src/main/java/it/pagopa/selfcare/mscore/core/OnboardingServiceImpl.java b/core/src/main/java/it/pagopa/selfcare/mscore/core/OnboardingServiceImpl.java index 1b153038..91e636ff 100644 --- a/core/src/main/java/it/pagopa/selfcare/mscore/core/OnboardingServiceImpl.java +++ b/core/src/main/java/it/pagopa/selfcare/mscore/core/OnboardingServiceImpl.java @@ -10,15 +10,20 @@ import it.pagopa.selfcare.mscore.model.institution.Institution; import it.pagopa.selfcare.mscore.model.institution.Onboarding; import it.pagopa.selfcare.mscore.model.onboarding.VerifyOnboardingFilters; +import it.pagopa.selfcare.mscore.model.pecnotification.PecNotification; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import java.time.LocalDate; import java.time.OffsetDateTime; +import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.UUID; import static it.pagopa.selfcare.mscore.constant.GenericError.*; @@ -29,16 +34,23 @@ public class OnboardingServiceImpl implements OnboardingService { private final InstitutionService institutionService; private final InstitutionConnector institutionConnector; private final PecNotificationConnector pecNotificationConnector; + private Integer sendingFrequencyPecNotification; + private String epochDatePecNotification; + private LocalDate currentDate = LocalDate.now(); public OnboardingServiceImpl(OnboardingDao onboardingDao, InstitutionService institutionService, InstitutionConnector institutionConnector, - PecNotificationConnector pecNotificationConnector) { + PecNotificationConnector pecNotificationConnector, + @Value("${mscore.sending-frequency-pec-notification}") Integer sendingFrequencyPecNotification, + @Value("${mscore.epoch-date-pec-notification}") String epochDatePecNotification) { this.onboardingDao = onboardingDao; this.institutionService = institutionService; this.institutionConnector = institutionConnector; this.pecNotificationConnector = pecNotificationConnector; + this.sendingFrequencyPecNotification = sendingFrequencyPecNotification; + this.epochDatePecNotification = epochDatePecNotification; } @Override @@ -67,10 +79,39 @@ public void verifyOnboardingInfoByFilters(VerifyOnboardingFilters filters) { } } + public void insertPecNotification(String institutionId, String productId, String digitalAddress) { + + PecNotification pecNotification = new PecNotification(); + pecNotification.setId(UUID.randomUUID().toString()); + pecNotification.setCreatedAt(OffsetDateTime.now()); + pecNotification.setProductId(productId); + pecNotification.setInstitutionId(institutionId); + pecNotification.setModuleDayOfTheEpoch(calculateModuleDayOfTheEpoch()); + pecNotification.setDigitalAddress(digitalAddress); + + if (!pecNotificationConnector.insertPecNotification(pecNotification)){ + throw new InvalidRequestException(INVALID_INSERT_PEC_NOTIFICATION_ERROR.getMessage(), INVALID_INSERT_PEC_NOTIFICATION_ERROR.getCode()); + } + + } + + public int calculateModuleDayOfTheEpoch() { + LocalDate epochStart = LocalDate.parse(this.epochDatePecNotification); + long daysDiff = ChronoUnit.DAYS.between(epochStart, this.currentDate); + int moduleDayOfTheEpoch = (int) (daysDiff % this.sendingFrequencyPecNotification); + return moduleDayOfTheEpoch; + } + @Override public Institution persistOnboarding(String institutionId, String productId, Onboarding onboarding, StringBuilder httpStatus) { + Institution institution = persistAndGetInstitution(institutionId, productId, onboarding, httpStatus); + this.insertPecNotification(institutionId, productId, institution.getDigitalAddress()); + return institution; + } + + private Institution persistAndGetInstitution(String institutionId, String productId, Onboarding onboarding, StringBuilder httpStatus) { log.trace("persistForUpdate start"); log.debug("persistForUpdate institutionId = {}, productId = {}", institutionId, productId); onboarding.setStatus(RelationshipState.ACTIVE); @@ -86,9 +127,9 @@ public Institution persistOnboarding(String institutionId, String if (Optional.ofNullable(institution.getOnboarding()).flatMap(onboardings -> onboardings.stream() .filter(item -> item.getProductId().equals(productId) && UtilEnumList.VALID_RELATIONSHIP_STATES.contains(item.getStatus())) .findAny()).isPresent()) { - + httpStatus.append(HttpStatus.OK.value()); - return institution; + return institution; } try { diff --git a/core/src/test/java/it/pagopa/selfcare/mscore/core/OnboardingServiceImplTest.java b/core/src/test/java/it/pagopa/selfcare/mscore/core/OnboardingServiceImplTest.java index 5af062ee..6fda8bad 100644 --- a/core/src/test/java/it/pagopa/selfcare/mscore/core/OnboardingServiceImplTest.java +++ b/core/src/test/java/it/pagopa/selfcare/mscore/core/OnboardingServiceImplTest.java @@ -13,25 +13,25 @@ import it.pagopa.selfcare.mscore.model.institution.Institution; import it.pagopa.selfcare.mscore.model.institution.Onboarding; import it.pagopa.selfcare.mscore.model.onboarding.*; +import it.pagopa.selfcare.mscore.model.pecnotification.PecNotification; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.*; import org.mockito.junit.jupiter.MockitoExtension; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.util.ReflectionTestUtils; import java.time.LocalDate; +import java.time.temporal.ChronoUnit; import java.util.List; import java.util.UUID; import static it.pagopa.selfcare.mscore.constant.GenericError.DELETE_NOTIFICATION_OPERATION_ERROR; import static it.pagopa.selfcare.mscore.constant.GenericError.ONBOARDING_OPERATION_ERROR; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @ContextConfiguration(classes = {OnboardingServiceImpl.class}) @@ -134,12 +134,16 @@ void testVerifyOnboardingInfo5() { @Test void persistOnboarding_whenUserExistsOnRegistry() { + ReflectionTestUtils.setField(onboardingServiceImpl, "sendingFrequencyPecNotification", 30); + ReflectionTestUtils.setField(onboardingServiceImpl, "epochDatePecNotification", "2024-01-01"); + Onboarding onboarding = dummyOnboarding(); onboarding.setStatus(UtilEnumList.VALID_RELATIONSHIP_STATES.get(0)); - Institution institution = new Institution(); institution.setId("institutionId"); institution.setOnboarding(List.of(onboarding, dummyOnboarding())); + + when(pecNotificationConnector.insertPecNotification(any(PecNotification.class))).thenReturn(true); when(institutionConnector.findById(institution.getId())).thenReturn(institution); String institutionId = institution.getId(); @@ -195,6 +199,9 @@ void persistOnboarding_shouldRollback() { @Test void persistOnboarding_whenUserNotExistsOnRegistry() { + ReflectionTestUtils.setField(onboardingServiceImpl, "sendingFrequencyPecNotification", 30); + ReflectionTestUtils.setField(onboardingServiceImpl, "epochDatePecNotification", "2024-01-01"); + String pricingPlan = "pricingPlan"; String productId = "productId"; Billing billing = new Billing(); @@ -214,7 +221,7 @@ void persistOnboarding_whenUserNotExistsOnRegistry() { Institution institution = new Institution(); institution.setId("institutionId"); institution.setOnboarding(List.of(onboarding)); - + institution.setDigitalAddress("test@junit.pagopa"); Token token = new Token(); token.setId(onboarding.getTokenId()); @@ -225,6 +232,7 @@ void persistOnboarding_whenUserNotExistsOnRegistry() { token.setStatus(onboarding.getStatus()); token.setContractSigned(onboarding.getContract()); + when(pecNotificationConnector.insertPecNotification(any(PecNotification.class))).thenReturn(true); when(institutionConnector.findById(institution.getId())).thenReturn(institution); when(institutionConnector.findAndUpdate(any(), any(), any(), any())).thenReturn(institution); @@ -240,6 +248,11 @@ void persistOnboarding_whenUserNotExistsOnRegistry() { assertEquals(actual.getCreatedAt().getDayOfYear(), LocalDate.now().getDayOfYear()); assertEquals(HttpStatus.CREATED.value(), Integer.parseInt(statusCode.toString())); + ArgumentCaptor< PecNotification > argCaptor = ArgumentCaptor.forClass(PecNotification.class); + verify(pecNotificationConnector, times(1)). insertPecNotification(argCaptor.capture()); + assertEquals(productId, argCaptor.getValue().getProductId()); + assertEquals("institutionId", argCaptor.getValue().getInstitutionId()); + assertEquals("test@junit.pagopa", argCaptor.getValue().getDigitalAddress()); } private Onboarding dummyOnboarding() { @@ -291,5 +304,22 @@ void deleteOnboardedInstitution_deletePecNotificationFails() { verify(institutionConnector, times(1)).findAndDeleteOnboarding(institutionId, productId); verify(pecNotificationConnector, times(1)).findAndDeletePecNotification(institutionId, productId); } + + @Test + public void testCalculateModuleDayOfTheEpoch() { + LocalDate mockCurrentDate = LocalDate.of(2024, 2, 1); // 31 days after epoch + + ReflectionTestUtils.setField(onboardingServiceImpl, "sendingFrequencyPecNotification", 30); + ReflectionTestUtils.setField(onboardingServiceImpl, "epochDatePecNotification", "2024-01-01"); + ReflectionTestUtils.setField(onboardingServiceImpl, "currentDate", mockCurrentDate); + + int result = onboardingServiceImpl.calculateModuleDayOfTheEpoch(); + + LocalDate epochStart = LocalDate.parse("2024-01-01"); + long daysDiff = ChronoUnit.DAYS.between(epochStart, mockCurrentDate); + int expected = (int) (daysDiff % 30); + + assertEquals(expected, result); + } }