Skip to content

Commit

Permalink
INTYGFV-16796: Implementation of email notification enabled for deep …
Browse files Browse the repository at this point in the history
…integrated users. (#1100)

Co-authored-by: mhornfeldt <[email protected]>
Co-authored-by: cigerhed <[email protected]>
  • Loading branch information
3 people authored Sep 2, 2024
1 parent baab40b commit ba65e8b
Show file tree
Hide file tree
Showing 23 changed files with 789 additions and 81 deletions.
2 changes: 2 additions & 0 deletions devops/dev/config/application-dev.properties
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,6 @@ servicenow.password=serviceNowPassword
servicenow.base.url=http://localhost:8020
servicenow.subscription.url=${servicenow.base.url}/services/stubs/servicenowstub/api/nabia/v1/inera_services/services/stub

unit.notification.config.path=${application.dir}/config/unit-notification-config.json

integration.intygproxyservice.baseurl=http://localhost:18020
12 changes: 12 additions & 0 deletions devops/dev/config/unit-notification-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{
"region": "Beta Regionen",
"configuration": [
{
"datetime": "2024-08-01T08:00",
"careProviders" : ["TSTNMT2321000156-BETA"],
"issuedOnUnit" : []
}
]
}
]
4 changes: 4 additions & 0 deletions web/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ dependencies {
implementation project(':webcert-common')
implementation project(':webcert-persistence')

implementation "com.fasterxml.jackson.core:jackson-core"
implementation "com.fasterxml.jackson.core:jackson-annotations"
implementation "com.fasterxml.jackson.core:jackson-databind"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
implementation "se.inera.intyg.infra:certificate:${infraVersion}"
implementation "se.inera.intyg.infra:common-redis-cache-core:${infraVersion}"
implementation "se.inera.intyg.infra:driftbanner-dto:${infraVersion}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2024 Inera AB (http://www.inera.se)
*
* This file is part of sklintyg (https://github.com/sklintyg).
*
* sklintyg is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sklintyg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package se.inera.intyg.webcert.web.csintegration.certificate;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
public class GetUnitNotificationConfig {


@Value("${unit.notification.config.path:}")
private String unitNotificationConfigPath;
private List<RegionNotificationConfig> integratedUnitNotificationConfig;

public List<RegionNotificationConfig> get() {
if (integratedUnitNotificationConfig == null) {
integratedUnitNotificationConfig = new ArrayList<>();
final var objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
try (final var resourceAsStream = new FileInputStream(unitNotificationConfigPath)) {
integratedUnitNotificationConfig = objectMapper.readValue(
resourceAsStream,
new TypeReference<>() {
});
log.info("Integrated Unit Notification was loaded with configuration: {}", integratedUnitNotificationConfig);
} catch (FileNotFoundException e) {
log.warn("File not found: {}. Returning empty configuration.", unitNotificationConfigPath);
} catch (Exception e) {
log.error(
String.format("Failed to load Integrated Unit Notification configuration. Reason: %s", e.getMessage()), e
);
}
}
return integratedUnitNotificationConfig;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2024 Inera AB (http://www.inera.se)
*
* This file is part of sklintyg (https://github.com/sklintyg).
*
* sklintyg is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sklintyg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package se.inera.intyg.webcert.web.csintegration.certificate;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Builder;
import lombok.Value;
import se.inera.intyg.webcert.web.csintegration.certificate.IntegratedUnitNotificationConfig.IntegratedUnitNotificationConfigBuilder;

@JsonInclude
@JsonDeserialize(builder = IntegratedUnitNotificationConfigBuilder.class)
@Builder
@Value
public class IntegratedUnitNotificationConfig {

@JsonProperty("careProviders")
List<String> careProviders;
@JsonProperty("issuedOnUnit")
List<String> issuedOnUnit;
@JsonProperty("datetime")
LocalDateTime datetime;

@JsonPOJOBuilder(withPrefix = "")
public static class IntegratedUnitNotificationConfigBuilder {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2024 Inera AB (http://www.inera.se)
*
* This file is part of sklintyg (https://github.com/sklintyg).
*
* sklintyg is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sklintyg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package se.inera.intyg.webcert.web.csintegration.certificate;

import java.time.LocalDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
public class IntegratedUnitNotificationEvaluator {

private final GetUnitNotificationConfig getUnitNotificationConfig;

public boolean mailNotification(String careProviderId, String issuedOnUnitId, String certificateId, LocalDateTime issuingDate) {
final var regionNotificationConfigs = getUnitNotificationConfig.get();
if (regionNotificationConfigs.isEmpty()) {
return false;
}

if (evaluateMailNotification(careProviderId, issuedOnUnitId, regionNotificationConfigs, issuingDate)) {
log.info(
"Certificate with id '{}' has been evaluated and should receive mail notification. CareProviderId: '{}',"
+ " IssuedOnUnitId: '{}', IssuingDate: '{}'", certificateId, careProviderId, issuedOnUnitId, issuingDate);
return true;
}

log.info(
"Certificate with id '{}' has been evaluated and should not receive mail notification. CareProviderId: '{}',"
+ " IssuedOnUnitId: '{}', IssuingDate: '{}'", certificateId, careProviderId, issuedOnUnitId, issuingDate);
return false;
}

private boolean evaluateMailNotification(String careProviderId, String issuedOnUnitId,
List<RegionNotificationConfig> regionNotificationConfigs, LocalDateTime issuingDate) {
return regionNotificationConfigs.stream()
.map(RegionNotificationConfig::getConfiguration)
.flatMap(List::stream)
.anyMatch(config ->
evaluateMailNotification(
config.getIssuedOnUnit(),
config.getCareProviders(),
config.getDatetime(),
issuedOnUnitId,
careProviderId,
issuingDate
)
);
}

private boolean evaluateMailNotification(List<String> unitIds, List<String> careProviderIds, LocalDateTime activateFrom, String unitId,
String careProviderId, LocalDateTime issuingDate) {
if ((careProviderIds != null && !careProviderIds.contains(careProviderId)) && (unitIds != null && !unitIds.contains(unitId))) {
return false;
}

return activateFrom.isBefore(issuingDate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import se.inera.intyg.common.support.common.enumerations.HandelsekodEnum;
import se.inera.intyg.common.support.facade.model.Certificate;
import se.inera.intyg.infra.security.common.model.IntygUser;
import se.inera.intyg.webcert.web.csintegration.integration.CSIntegrationRequestFactory;
import se.inera.intyg.webcert.web.csintegration.integration.CSIntegrationService;
import se.inera.intyg.webcert.web.integration.registry.IntegreradeEnheterRegistry;
import se.inera.intyg.webcert.web.service.notification.NotificationService;
Expand All @@ -37,7 +36,6 @@ public class PublishCertificateStatusUpdateService {

private final IntegreradeEnheterRegistry integreradeEnheterRegistry;
private final CSIntegrationService csIntegrationService;
private final CSIntegrationRequestFactory csIntegrationRequestFactory;
private final NotificationMessageFactory notificationMessageFactory;
private final NotificationService notificationService;
private final WebCertUserService webCertUserService;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2024 Inera AB (http://www.inera.se)
*
* This file is part of sklintyg (https://github.com/sklintyg).
*
* sklintyg is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sklintyg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package se.inera.intyg.webcert.web.csintegration.certificate;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import java.util.List;
import lombok.Builder;
import lombok.Value;
import se.inera.intyg.webcert.web.csintegration.certificate.RegionNotificationConfig.RegionNotificationConfigBuilder;

@JsonInclude
@JsonDeserialize(builder = RegionNotificationConfigBuilder.class)
@Builder
@Value
public class RegionNotificationConfig {

@JsonProperty("region")
String region;
@JsonProperty("configuration")
List<IntegratedUnitNotificationConfig> configuration;

@JsonPOJOBuilder(withPrefix = "")
public static class RegionNotificationConfigBuilder {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import se.inera.intyg.common.support.common.enumerations.HandelsekodEnum;
import se.inera.intyg.common.support.facade.model.Certificate;
import se.inera.intyg.webcert.persistence.arende.model.ArendeAmne;
import se.inera.intyg.webcert.web.csintegration.certificate.IntegratedUnitNotificationEvaluator;
import se.inera.intyg.webcert.web.csintegration.certificate.PublishCertificateStatusUpdateService;
import se.inera.intyg.webcert.web.csintegration.integration.CSIntegrationRequestFactory;
import se.inera.intyg.webcert.web.csintegration.integration.CSIntegrationService;
import se.inera.intyg.webcert.web.integration.registry.IntegreradeEnheterRegistry;
import se.inera.intyg.webcert.web.service.monitoring.MonitoringLogService;
import se.riv.clinicalprocess.healthcond.certificate.sendMessageToCare.v2.SendMessageToCareResponseType;
import se.riv.clinicalprocess.healthcond.certificate.sendMessageToCare.v2.SendMessageToCareType;
Expand All @@ -39,7 +42,9 @@
public class ProcessIncomingMessageService {

private final CSIntegrationService csIntegrationService;
private final IntegreradeEnheterRegistry integreradeEnheterRegistry;
private final CSIntegrationRequestFactory csIntegrationRequestFactory;
private final IntegratedUnitNotificationEvaluator integratedUnitNotificationEvaluator;
private final MonitoringLogService monitoringLogService;
private final PublishCertificateStatusUpdateService publishCertificateStatusUpdateService;
private final SendMailNotificationForReceivedMessageService sendMailNotificationForReceivedMessageService;
Expand All @@ -65,8 +70,13 @@ public SendMessageToCareResponseType process(SendMessageToCareType sendMessageTo
isAnswer
);

publishCertificateStatusUpdateService.publish(certificate, getEventType(questionType, isAnswer));
sendMailNotificationForReceivedMessageService.send(sendMessageToCare, certificate);
final var shouldReciveMailNotifications = shouldReciveMailNotifications(certificate);

if (!unitIsIntegrated(certificate) || shouldReciveMailNotifications) {
sendMailNotificationForReceivedMessageService.send(sendMessageToCare, certificate);
} else {
publishCertificateStatusUpdateService.publish(certificate, getEventType(questionType, isAnswer));
}

final var sendMessageToCareResponseType = new SendMessageToCareResponseType();
final var result = new ResultType();
Expand All @@ -75,10 +85,23 @@ public SendMessageToCareResponseType process(SendMessageToCareType sendMessageTo
return sendMessageToCareResponseType;
}

private boolean shouldReciveMailNotifications(Certificate certificate) {
return integratedUnitNotificationEvaluator.mailNotification(
certificate.getMetadata().getCareProvider().getUnitId(),
certificate.getMetadata().getUnit().getUnitId(),
certificate.getMetadata().getId(),
certificate.getMetadata().getSigned()
);
}

private static HandelsekodEnum getEventType(ArendeAmne questionType, boolean isAnswer) {
if (questionType.equals(ArendeAmne.PAMINN) || !isAnswer) {
return HandelsekodEnum.NYFRFM;
}
return HandelsekodEnum.NYSVFM;
}

private boolean unitIsIntegrated(Certificate certificate) {
return integreradeEnheterRegistry.getIntegreradEnhet(certificate.getMetadata().getUnit().getUnitId()) != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.springframework.stereotype.Service;
import se.inera.intyg.common.support.facade.model.Certificate;
import se.inera.intyg.webcert.persistence.arende.model.ArendeAmne;
import se.inera.intyg.webcert.web.integration.registry.IntegreradeEnheterRegistry;
import se.inera.intyg.webcert.web.service.mail.MailNotification;
import se.inera.intyg.webcert.web.service.mail.MailNotificationService;
import se.riv.clinicalprocess.healthcond.certificate.sendMessageToCare.v2.SendMessageToCareType;
Expand All @@ -34,14 +33,9 @@
@RequiredArgsConstructor
public class SendMailNotificationForReceivedMessageService {

private final IntegreradeEnheterRegistry integreradeEnheterRegistry;
private final MailNotificationService mailNotificationService;

public void send(SendMessageToCareType sendMessageToCare, Certificate certificate) {
if (unitIsIntegrated(certificate)) {
return;
}

final var questionType = ArendeAmne.valueOf(sendMessageToCare.getAmne().getCode());
final var isAnswer = sendMessageToCare.getSvarPa() != null;
if (questionType.equals(ArendeAmne.PAMINN) || !isAnswer) {
Expand All @@ -65,8 +59,4 @@ private static MailNotification buildMailNotification(SendMessageToCareType send
certificate.getMetadata().getIssuedBy().getPersonId()
);
}

private boolean unitIsIntegrated(Certificate certificate) {
return integreradeEnheterRegistry.getIntegreradEnhet(certificate.getMetadata().getUnit().getUnitId()) != null;
}
}
Loading

0 comments on commit ba65e8b

Please sign in to comment.