diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/SykemeldingConsumer.java b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/SykemeldingConsumer.java index 40911984e1e..17de746a9e0 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/SykemeldingConsumer.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/SykemeldingConsumer.java @@ -1,6 +1,7 @@ package no.nav.dolly.bestilling.sykemelding; import com.fasterxml.jackson.databind.ObjectMapper; +import io.swagger.v3.core.util.Json; import lombok.extern.slf4j.Slf4j; import no.nav.dolly.bestilling.ConsumerStatus; import no.nav.dolly.bestilling.sykemelding.command.SykemeldingPostCommand; @@ -41,7 +42,7 @@ public SykemeldingConsumer( @Timed(name = "providers", tags = { "operation", "detaljertsykemelding_opprett" }) public Mono postDetaljertSykemelding(DetaljertSykemeldingRequest detaljertSykemeldingRequest) { - log.info("Detaljert Sykemelding sendt {}", detaljertSykemeldingRequest); + log.info("Detaljert Sykemelding sendt {}", Json.pretty(detaljertSykemeldingRequest)); return tokenService.exchange(serverProperties) .flatMap(token -> new SykemeldingPostCommand(webClient, detaljertSykemeldingRequest, diff --git a/apps/sykemelding-api/Dockerfile b/apps/sykemelding-api/Dockerfile index 89a589699dd..fabb0b8c4d2 100644 --- a/apps/sykemelding-api/Dockerfile +++ b/apps/sykemelding-api/Dockerfile @@ -1,6 +1,7 @@ FROM ghcr.io/navikt/baseimages/temurin:21 LABEL maintainer="Team Dolly" +ENV JAVA_OPTS="--add-opens java.base/java.lang=ALL-UNNAMED" ADD /build/libs/app.jar /app/app.jar EXPOSE 8080 diff --git a/apps/sykemelding-api/build.gradle b/apps/sykemelding-api/build.gradle index 9d5d8e6d49d..a7132cb3f5f 100644 --- a/apps/sykemelding-api/build.gradle +++ b/apps/sykemelding-api/build.gradle @@ -21,7 +21,6 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-security" implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:$versions.springdoc" - implementation "io.swagger.core.v3:swagger-annotations-jakarta:$versions.swagger" implementation "com.ibm.mq:mq-jms-spring-boot-starter:$versions.mq" implementation "jakarta.xml.bind:jakarta.xml.bind-api:$versions.jakartaXmlBindApi" @@ -29,6 +28,8 @@ dependencies { implementation "org.glassfish.jaxb:jaxb-runtime:$versions.jaxb" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml" + implementation "ma.glasnost.orika:orika-core:$versions.orika" + testImplementation "no.nav.testnav.libs:testing" testImplementation "org.springframework.security:spring-security-test" testImplementation "org.springframework.cloud:spring-cloud-contract-wiremock" diff --git a/apps/sykemelding-api/config.test.yml b/apps/sykemelding-api/config.test.yml index c22417b88ff..ccc74082c66 100644 --- a/apps/sykemelding-api/config.test.yml +++ b/apps/sykemelding-api/config.test.yml @@ -66,6 +66,8 @@ spec: - application: testnav-oversikt-frontend - application: testnav-synt-sykemelding-api-dev outbound: + rules: + - application: testnav-sykemelding-proxy external: - host: mqls04.preprod.local ports: diff --git a/apps/sykemelding-api/config.yml b/apps/sykemelding-api/config.yml index 38ec28ef58a..8070e276ea4 100644 --- a/apps/sykemelding-api/config.yml +++ b/apps/sykemelding-api/config.yml @@ -66,6 +66,8 @@ spec: - application: testnav-oversikt-frontend - application: testnav-synt-sykemelding-api outbound: + rules: + - application: testnav-sykemelding-proxy external: - host: mqls04.preprod.local ports: diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/Consumers.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/Consumers.java new file mode 100644 index 00000000000..a38bd85ccbe --- /dev/null +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/Consumers.java @@ -0,0 +1,21 @@ +package no.nav.registre.testnorge.sykemelding.config; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import no.nav.testnav.libs.securitycore.domain.ServerProperties; + +import static lombok.AccessLevel.PACKAGE; + +@Configuration +@ConfigurationProperties(prefix = "consumers") +@NoArgsConstructor(access = PACKAGE) +@Getter +@Setter(PACKAGE) +public class Consumers { + + private ServerProperties sykemeldingProxy; +} diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/MapperFacadeConfig.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/MapperFacadeConfig.java new file mode 100644 index 00000000000..d4705e61aef --- /dev/null +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/MapperFacadeConfig.java @@ -0,0 +1,37 @@ +package no.nav.registre.testnorge.sykemelding.config; + +import lombok.RequiredArgsConstructor; +import ma.glasnost.orika.CustomConverter; +import ma.glasnost.orika.MapperFacade; +import ma.glasnost.orika.impl.DefaultMapperFactory; +import no.nav.registre.testnorge.sykemelding.mapper.MappingStrategy; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +import static java.util.Objects.nonNull; + +@Configuration +@RequiredArgsConstructor +public class MapperFacadeConfig { + + @Bean + MapperFacade mapperFacade(List mappingStrategies, List customConverters) { + DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); + + if (nonNull(mappingStrategies)) { + for (MappingStrategy mapper : mappingStrategies) { + mapper.register(mapperFactory); + } + } + + if (nonNull(customConverters)) { + for (CustomConverter converter : customConverters) { + mapperFactory.getConverterFactory().registerConverter(converter); + } + } + + return mapperFactory.getMapperFacade(); + } +} \ No newline at end of file diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfoConsumer.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfoConsumer.java index d121155f9df..e51978b6662 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfoConsumer.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfoConsumer.java @@ -6,11 +6,12 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.jms.core.JmsTemplate; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; @Slf4j -@Component +@Service public class SyfoConsumer { + private final JmsTemplate jmsTemplate; private final String queueName; diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfosmreglerConsumer.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfosmreglerConsumer.java new file mode 100644 index 00000000000..96e328e0af4 --- /dev/null +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfosmreglerConsumer.java @@ -0,0 +1,34 @@ +package no.nav.registre.testnorge.sykemelding.consumer; + +import no.nav.registre.testnorge.sykemelding.config.Consumers; +import no.nav.registre.testnorge.sykemelding.consumer.command.SyfosmreglerPostValidateCommand; +import no.nav.registre.testnorge.sykemelding.dto.ReceivedSykemeldingDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.ValidationResultDTO; +import no.nav.testnav.libs.securitycore.domain.ServerProperties; +import no.nav.testnav.libs.servletsecurity.exchange.TokenExchange; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +@Service +public class SyfosmreglerConsumer { + + private final ServerProperties properties; + private final TokenExchange tokenExchange; + private final WebClient webClient; + + public SyfosmreglerConsumer(Consumers consumers, WebClient.Builder webClientBuilder, TokenExchange tokenExchange) { + + this.properties = consumers.getSykemeldingProxy(); + this.tokenExchange = tokenExchange; + this.webClient = webClientBuilder + .baseUrl(properties.getUrl()) + .build(); + } + + public Mono validate(ReceivedSykemeldingDTO sykemelding) { + + return tokenExchange.exchange(properties) + .flatMap(token -> new SyfosmreglerPostValidateCommand(webClient, sykemelding, token.getTokenValue()).call()); + } +} diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/command/SyfosmreglerPostValidateCommand.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/command/SyfosmreglerPostValidateCommand.java new file mode 100644 index 00000000000..5a4c9649a30 --- /dev/null +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/command/SyfosmreglerPostValidateCommand.java @@ -0,0 +1,42 @@ +package no.nav.registre.testnorge.sykemelding.consumer.command; + +import io.swagger.v3.core.util.Json; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import no.nav.registre.testnorge.sykemelding.dto.ReceivedSykemeldingDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.ValidationResultDTO; +import no.nav.testnav.libs.reactivecore.utils.WebClientFilter; +import org.springframework.http.HttpHeaders; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.util.concurrent.Callable; + +@Slf4j +@RequiredArgsConstructor +public class SyfosmreglerPostValidateCommand implements Callable> { + + private static final String SYFOSMREGLER_VALIDATE_URL = "/v1/rules/validate"; + + private final WebClient webClient; + private final ReceivedSykemeldingDTO receivedSykemelding; + private final String accessToken; + + @Override + public Mono call() { + + log.info("Sender til syfosmregler {}", Json.pretty(receivedSykemelding)); + + return webClient.post() + .uri(uriBuilder -> uriBuilder.path(SYFOSMREGLER_VALIDATE_URL).build()) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + .bodyValue(receivedSykemelding) + .retrieve() + .bodyToMono(ValidationResultDTO.class) + .doOnError(WebClientFilter::logErrorMessage) + .onErrorResume(error -> Mono.just(ValidationResultDTO.builder() + .httpStatus(WebClientFilter.getStatus(error)) + .message(WebClientFilter.getMessage(error)) + .build())); + } +} diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Aktivitet.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Aktivitet.java index ba3886c8a60..420fad60858 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Aktivitet.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Aktivitet.java @@ -2,21 +2,26 @@ import no.nav.registre.testnorge.sykemelding.external.xmlstds.helseopplysningerarbeidsuforhet._2013_10_01.XMLHelseOpplysningerArbeidsuforhet; import no.nav.testnav.libs.dto.sykemelding.v1.PeriodeDTO; +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; import java.time.LocalDate; import java.util.List; -import java.util.stream.Collectors; class Aktivitet { private final XMLHelseOpplysningerArbeidsuforhet.Aktivitet xmlAktivitet; Aktivitet(List dtos, boolean manglendeTilretteleggingPaaArbeidsplassen) { + + if (dtos.isEmpty()) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Perioder må angis"); + } this.xmlAktivitet = new XMLHelseOpplysningerArbeidsuforhet.Aktivitet() .withPeriode( dtos.stream() .map(value -> new Periode(value, manglendeTilretteleggingPaaArbeidsplassen)) .map(Periode::getXmlObject) - .collect(Collectors.toList()) + .toList() ); } diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Arbeidsgiver.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Arbeidsgiver.java index 13210281a1a..9bc46c66130 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Arbeidsgiver.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Arbeidsgiver.java @@ -7,13 +7,13 @@ import static java.util.Objects.nonNull; public class Arbeidsgiver { - private XMLHelseOpplysningerArbeidsuforhet.Arbeidsgiver xmlArbeidsgiver; + private final XMLHelseOpplysningerArbeidsuforhet.Arbeidsgiver xmlArbeidsgiver; Arbeidsgiver(ArbeidsgiverDTO dto) { xmlArbeidsgiver = new XMLHelseOpplysningerArbeidsuforhet.Arbeidsgiver() .withHarArbeidsgiver(new XMLCS() - .withDN("En arbeidsgiver") - .withV("1")) + .withDN(nonNull(dto) ? "En arbeidsgiver" : "Ingen arbeidsgiver") + .withV(nonNull(dto) ? "1" : "3")) .withNavnArbeidsgiver(nonNull(dto) ? dto.getNavn() : null) .withYrkesbetegnelse(nonNull(dto) ? dto.getYrkesbetegnelse() : null) .withStillingsprosent(nonNull(dto) ? getStillingsprosent(dto) : null); diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Dokument.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Dokument.java index 8a29dd7080d..7f047ee9610 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Dokument.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Dokument.java @@ -28,10 +28,12 @@ class Dokument { .withMedisinskVurdering(medisinskVurdering.getXmlObject()) .withAktivitet(aktivitet.getXmlObject()) .withPrognose(prognose.getXmlObject()) + .withUtdypendeOpplysninger(new UtdypendeOpplysninger(dto.getUtdypendeOpplysninger()).getXmlObject()) .withTiltak( new XMLHelseOpplysningerArbeidsuforhet.Tiltak() .withTiltakArbeidsplassen(dto.getDetaljer().getTiltakArbeidsplass()) .withTiltakNAV(dto.getDetaljer().getTiltakNav()) + .withAndreTiltak(dto.getDetaljer().getAndreTiltak()) ) .withKontaktMedPasient( new XMLHelseOpplysningerArbeidsuforhet.KontaktMedPasient() diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/MedisinskVurdering.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/MedisinskVurdering.java index 33e97b9a562..38a23bc28d8 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/MedisinskVurdering.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/MedisinskVurdering.java @@ -7,15 +7,14 @@ import java.time.LocalDate; import java.util.List; -import java.util.stream.Collectors; class MedisinskVurdering { - private final XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering medisinskVurdering; + private final XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering xmlMedisinskVurdering; MedisinskVurdering(LocalDate fom, DiagnoseDTO hovedDiagnose, List biDiagnoser) { - medisinskVurdering = new XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering() + xmlMedisinskVurdering = new XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering() .withHovedDiagnose(new XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering.HovedDiagnose() .withDiagnosekode(new XMLCV() .withDN(hovedDiagnose.getDiagnose()) @@ -29,19 +28,19 @@ class MedisinskVurdering { .withS(value.getSystem()) .withV(value.getDiagnosekode()) ) - .collect(Collectors.toList()) + .toList() ) ) .withYrkesskade(false) .withYrkesskadeDato(fom) .withSvangerskap(false) .withAnnenFraversArsak( - new XMLArsakType().withBeskriv("Medising årsak i kategorien annet") + new XMLArsakType().withBeskriv("Medisinsk årsak i kategorien annet") ) .withSkjermesForPasient(false); } XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering getXmlObject() { - return medisinskVurdering; + return xmlMedisinskVurdering; } } diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Pasient.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Pasient.java index 7808d811bb8..d9ffbd0ff75 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Pasient.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Pasient.java @@ -10,20 +10,27 @@ import no.nav.testnav.libs.dto.sykemelding.v1.HelsepersonellDTO; import no.nav.testnav.libs.dto.sykemelding.v1.PasientDTO; +import static java.util.Objects.nonNull; + public class Pasient { private final XMLHelseOpplysningerArbeidsuforhet.Pasient xmlPasient; Pasient(PasientDTO pasientDTO, HelsepersonellDTO helsepersonellDTO) { + var pasient = nonNull(pasientDTO) ? pasientDTO : PasientDTO.builder() + .ident("12508407724") + .fornavn("Test") + .etternavn("Testesen") + .build(); xmlPasient = new XMLHelseOpplysningerArbeidsuforhet.Pasient() .withNavn(new XMLNavnType() - .withEtternavn(pasientDTO.getEtternavn()) - .withMellomnavn(pasientDTO.getMellomnavn()) - .withFornavn(pasientDTO.getFornavn()) + .withEtternavn(pasient.getEtternavn()) + .withMellomnavn(pasient.getMellomnavn()) + .withFornavn(pasient.getFornavn()) ) .withFodselsnummer(new XMLIdent() - .withId(pasientDTO.getIdent()) + .withId(pasient.getIdent()) .withTypeId(new XMLCV() .withV("FNR") .withDN("Fødselsnummer") @@ -31,10 +38,10 @@ public class Pasient { ) .withKontaktInfo(new XMLTeleCom() .withTypeTelecom(new XMLCS().withV("HP").withDN("Hovedtelefon")) - .withTeleAddress(new XMLURL().withV("tel:" + pasientDTO.getTelefon())) + .withTeleAddress(new XMLURL().withV("tel:" + pasient.getTelefon())) ) .withNavnFastlege(helsepersonellDTO.getFornavn() + " " + helsepersonellDTO.getEtternavn()) - .withNAVKontor(pasientDTO.getNavKontor()); + .withNAVKontor(pasient.getNavKontor()); } XMLHelseOpplysningerArbeidsuforhet.Pasient getXmlObject() { diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Sykemelding.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Sykemelding.java index 4c1bba83796..5d5759e57c2 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Sykemelding.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/Sykemelding.java @@ -1,7 +1,7 @@ package no.nav.registre.testnorge.sykemelding.domain; +import lombok.Data; import lombok.SneakyThrows; -import lombok.ToString; import no.nav.registre.testnorge.sykemelding.external.eiFellesformat.XMLEIFellesformat; import no.nav.registre.testnorge.sykemelding.external.eiFellesformat.XMLMottakenhetBlokk; import no.nav.registre.testnorge.sykemelding.external.msgHead.XMLAddress; @@ -28,10 +28,18 @@ import java.util.List; import java.util.UUID; +import static java.util.Objects.isNull; import static java.util.Objects.nonNull; -@ToString +@Data public class Sykemelding { + private static final String DUMMY_FNR = "12508407724"; + private static final PasientDTO DUMMY_PASIENT = PasientDTO.builder() + .ident(DUMMY_FNR) + .fornavn("Test") + .etternavn("Testesen") + .build(); + private final XMLEIFellesformat fellesformat; private final LocalDate fom; private final LocalDate tom; @@ -39,6 +47,7 @@ public class Sykemelding { @SneakyThrows public Sykemelding(SykemeldingDTO dto, ApplicationInfo applicationInfo) { + var xml = StaticResourceLoader.loadAsString("sykmelding.xml", StandardCharsets.ISO_8859_1); fellesformat = JAXBSykemeldingConverter.getInstance().convertToXMLEIFellesformat(xml); var head = getXMLMsgHead(); @@ -58,34 +67,22 @@ public Sykemelding(SykemeldingDTO dto, ApplicationInfo applicationInfo) { .build()); updatePatient(head.getMsgInfo().getPatient(), dto.getPasient()); var dokument = new Dokument(dto, applicationInfo); - head.getDocument().get(0).getRefDoc().getContent().getAny().set(0, dokument.getXmlObject()); + head.getDocument().getFirst().getRefDoc().getContent().getAny().set(0, dokument.getXmlObject()); fom = dokument.getFom(); tom = dokument.getTom(); - ident = dto.getPasient().getIdent(); + ident = isNull(dto.getPasient()) ? DUMMY_FNR : dto.getPasient().getIdent(); var xmlMottakenhetBlokk = getXMLMottakenhetBlokk(); xmlMottakenhetBlokk.setEdiLoggId(UUID.randomUUID().toString()); xmlMottakenhetBlokk.setAvsenderFnrFraDigSignatur(dto.getHelsepersonell().getIdent()); xmlMottakenhetBlokk.setMottattDatotid( DatatypeFactory.newInstance().newXMLGregorianCalendar( - GregorianCalendar.from(dto.getStartDato().atStartOfDay(ZoneId.systemDefault())) + GregorianCalendar.from(dto.getStartDato().atStartOfDay(ZoneId.of("UTC"))) ) ); } - public LocalDate getFom() { - return fom; - } - - public LocalDate getTom() { - return tom; - } - - public String getIdent() { - return ident; - } - public String toXml() { return JAXBSykemeldingConverter.getInstance().convertToXml(fellesformat); } @@ -99,15 +96,18 @@ private XMLMsgHead getXMLMsgHead() { } private void updatePatient(XMLPatient patient, PasientDTO dto) { - patient.getIdent().forEach(value -> value.setId(dto.getIdent())); - patient.setGivenName(dto.getFornavn()); - patient.setMiddleName(dto.getMellomnavn()); - patient.setFamilyName(dto.getEtternavn()); - patient.setDateOfBirth(dto.getFoedselsdato()); - - AdresseDTO adresse = dto.getAdresse(); - if (adresse != null) { + var pasient = isNull(dto) ? DUMMY_PASIENT : dto; + + patient.getIdent().forEach(value -> value.setId(pasient.getIdent())); + patient.setGivenName(pasient.getFornavn()); + patient.setMiddleName(pasient.getMellomnavn()); + patient.setFamilyName(pasient.getEtternavn()); + patient.setDateOfBirth(pasient.getFoedselsdato()); + + if (nonNull(dto) && nonNull(dto.getAdresse())) { XMLAddress address = patient.getAddress() == null ? new XMLAddress() : patient.getAddress(); + + AdresseDTO adresse = dto.getAdresse(); address.setStreetAdr(adresse.getGate()); address.setPostalCode(adresse.getPostnummer()); address.setCity(adresse.getBy()); diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/UtdypendeOpplysninger.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/UtdypendeOpplysninger.java new file mode 100644 index 00000000000..f41f15e9a57 --- /dev/null +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/domain/UtdypendeOpplysninger.java @@ -0,0 +1,37 @@ +package no.nav.registre.testnorge.sykemelding.domain; + +import no.nav.registre.testnorge.sykemelding.external.xmlstds.XMLCS; +import no.nav.registre.testnorge.sykemelding.external.xmlstds.helseopplysningerarbeidsuforhet._2013_10_01.XMLDynaSvarType; +import no.nav.registre.testnorge.sykemelding.external.xmlstds.helseopplysningerarbeidsuforhet._2013_10_01.XMLHelseOpplysningerArbeidsuforhet; +import no.nav.testnav.libs.dto.sykemelding.v1.UtdypendeOpplysningerDTO; + +import java.util.List; + +public class UtdypendeOpplysninger { + + private final XMLHelseOpplysningerArbeidsuforhet.UtdypendeOpplysninger xmlUtdypendeOpplysninger; + + UtdypendeOpplysninger(List utdypendeOpplysninger) { + xmlUtdypendeOpplysninger = new XMLHelseOpplysningerArbeidsuforhet.UtdypendeOpplysninger() + .withSpmGruppe(utdypendeOpplysninger.stream() + .map(value -> + new XMLHelseOpplysningerArbeidsuforhet.UtdypendeOpplysninger.SpmGruppe() + .withSpmGruppeId(value.getSpmGruppeId()) + .withSpmGruppeTekst(value.getSpmGruppeTekst()) + .withSpmSvar(value.getSpmSvar().stream() + .map(spmSvar -> new XMLDynaSvarType() + .withSpmId(spmSvar.getSpmId()) + .withSpmTekst(spmSvar.getSpmTekst()) + .withSvarTekst(spmSvar.getSvarTekst()) + .withRestriksjon(new XMLDynaSvarType.Restriksjon( + List.of(new XMLCS() + .withV(Integer.toString(spmSvar.getRestriksjon().ordinal())) + .withDN(spmSvar.getRestriksjon().name()))))) + .toList())) + .toList()); + } + + XMLHelseOpplysningerArbeidsuforhet.UtdypendeOpplysninger getXmlObject() { + return xmlUtdypendeOpplysninger; + } +} diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/dto/ReceivedSykemeldingDTO.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/dto/ReceivedSykemeldingDTO.java new file mode 100644 index 00000000000..97158d09d78 --- /dev/null +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/dto/ReceivedSykemeldingDTO.java @@ -0,0 +1,389 @@ +package no.nav.registre.testnorge.sykemelding.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import no.nav.testnav.libs.dto.sykemelding.v1.UtdypendeOpplysningerDTO; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static java.util.Objects.isNull; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ReceivedSykemeldingDTO { + + private Sykemelding sykmelding; + + private String personNrPasient; + private String tlfPasient; + private String personNrLege; + private String legeHelsepersonellkategori; + private String legeHprNr; + private String navLogId; + private String msgId; + private String id; + private String legekontorOrgNr; + private String legekontorHerId; + private String legekontorReshId; + private String legekontorOrgName; + private LocalDateTime mottattDato; + private String rulesetVersion; + private List merknader; + private String partnerreferanse; + private List vedlegg; + private UtenlandskSykmelding utenlandskSykmelding; + private String fellesformat; + private String tssid; + + public List getVedlegg() { + + if (isNull(vedlegg)) { + vedlegg = new ArrayList<>(); + } + return vedlegg; + } + + public List getMerknader() { + + if (isNull(merknader)) { + merknader = new ArrayList<>(); + } + return merknader; + } + + public enum AnnetFravaersArsakType { + GODKJENT_HELSEINSTITUSJON, + BEHANDLING_FORHINDRER_ARBEID, + ARBEIDSRETTET_TILTAK, + MOTTAR_TILSKUDD_GRUNNET_HELSETILSTAND, + NEDVENDIG_KONTROLLUNDENRSOKELSE, + SMITTEFARE, + ABORT, + UFOR_GRUNNET_BARNLOSHET, + DONOR, + BEHANDLING_STERILISERING + } + + public enum ArbeidsgiverType { + EN_ARBEIDSGIVER, + FLERE_ARBEIDSGIVERE, + INGEN_ARBEIDSGIVER + } + + public enum MedisinskArsakType { + TILSTAND_HINDRER_AKTIVITET, + AKTIVITET_FORVERRER_TILSTAND, + AKTIVITET_FORHINDRER_BEDRING, + ANNET + } + + public enum ArbeidsrelatertArsakType { + MANGLENDE_TILRETTELEGGING, + ANNET + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Sykemelding { + + private String id; + private String msgId; + private String pasientAktoerId; + private MedisinskVurdering medisinskVurdering; + private Boolean skjermesForPasient; + private Arbeidsgiver arbeidsgiver; + private List perioder; + private Prognose prognose; + private Map> utdypendeOpplysninger; + private String tiltakArbeidsplassen; + private String tiltakNAV; + private String andreTiltak; + private MeldingTilNAV meldingTilNAV; + private String meldingTilArbeidsgiver; + private KontaktMedpasient kontaktMedPasient; + private LocalDateTime behandletTidspunkt; + private Behandler behandler; + private AvsenderSystem avsenderSystem; + private LocalDate syketilfelleStartDato; + private LocalDateTime signaturDato; + private String navnFastlege; + + public List getPerioder() { + + if (isNull(perioder)) { + perioder = new ArrayList<>(); + } + return perioder; + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SporsmalSvar { + + private String sporsmal; + private String svar; + private List restriksjoner; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class UtenlandskSykmelding { + + private String land; + private Boolean folkeRegistertAdresseErBrakkeEllerTilsvarende; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Merknad { + + private String type; + private String beskrivelse; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class AvsenderSystem { + + private String navn; + private String versjon; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Behandler { + + private String fornavn; + private String mellomnavn; + private String etternavn; + private String aktoerId; + private String fnr; + private String hpr; + private String her; + private Adresse adresse; + private String tlf; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Adresse { + + private String gate; + private Integer postnummer; + private String kommune; + private String postboks; + private String land; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class KontaktMedpasient { + + private LocalDate kontaktDato; + private String begrunnelseIkkeKontakt; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class MeldingTilNAV { + + private Boolean bistandUmiddelbart; + private String beskrivBistand; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Prognose { + + private Boolean arbeidsforEtterPeriode; + private String hensynArbeidsplassen; + private ErIArbeid erIArbeid; + private ErIkkeIArbeid erIkkeIArbeid; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ErIArbeid { + + private Boolean egetArbeidPaSikt; + private Boolean annetArbeidPaSikt; + private LocalDate arbeidFOM; + private LocalDate vurderingsdato; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ErIkkeIArbeid { + + private Boolean arbeidsforPaSikt; + private LocalDate arbeidsforFOM; + private LocalDate vurderingsdato; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Periode { + + private LocalDate fom; + private LocalDate tom; + private AktivitetIkkeMulig aktivitetIkkeMulig; + private String avventendeInnspillTilArbeidsgiver; + private Integer behandlingsdager; + private Gradert gradert; + private Boolean reisetilskudd; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Gradert { + + private Boolean reisetilskudd; + private Integer grad; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class AktivitetIkkeMulig { + + private MedisinskArsak medisinskArsak; + private ArbeidsrelatertArsak arbeidsrelatertArsak; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class MedisinskArsak { + + private String beskrivelse; + private List arsak; + + public List getArsak() { + + if (isNull(arsak)) { + arsak = new ArrayList<>(); + } + return arsak; + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ArbeidsrelatertArsak { + + private String beskrivelse; + private List arsak; + + public List getArsak() { + + if (isNull(arsak)) { + arsak = new ArrayList<>(); + } + return arsak; + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Arbeidsgiver { + + private ArbeidsgiverType harArbeidsgiver; + private String navn; + private String yrkesbetegnelse; + private Integer stillingsprosent; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class MedisinskVurdering { + + private Diagnose hovedDiagnose; + private List biDiagnoser; + private Boolean svangerskap; + private Boolean yrkesskade; + private LocalDate yrkesskadeDato; + private AnnenFraversArsak annenFraversArsak; + + public List getBiDiagnoser() { + + if (isNull(biDiagnoser)) { + biDiagnoser = new ArrayList<>(); + } + return biDiagnoser; + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class AnnenFraversArsak { + + private String beskrivelse; + private List grunn; + + public List getGrunn() { + + if (isNull(grunn)) { + grunn = new ArrayList<>(); + } + return grunn; + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Diagnose { + + private String system; + private String kode; + private String tekst; + } +} diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/mapper/MappingStrategy.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/mapper/MappingStrategy.java new file mode 100644 index 00000000000..53220a44a60 --- /dev/null +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/mapper/MappingStrategy.java @@ -0,0 +1,19 @@ +package no.nav.registre.testnorge.sykemelding.mapper; + +import ma.glasnost.orika.MapperFactory; + +@FunctionalInterface +public interface MappingStrategy { + + /** + * A callback for registering criteria on the provided {@link MapperFactory}. + *

+ *

{@code
+     *
+     * @Override public void register(MapperFactory factory) {
+     * factory.registerMapper(arbeidsfordelingToRestArbeidsfordeling());
+     * }
+     * }
+ */ + void register(MapperFactory factory); +} diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/mapper/SykemeldingValidateMappingStrategy.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/mapper/SykemeldingValidateMappingStrategy.java new file mode 100644 index 00000000000..92683ace21d --- /dev/null +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/mapper/SykemeldingValidateMappingStrategy.java @@ -0,0 +1,276 @@ +package no.nav.registre.testnorge.sykemelding.mapper; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import ma.glasnost.orika.CustomMapper; +import ma.glasnost.orika.MapperFactory; +import ma.glasnost.orika.MappingContext; +import no.nav.registre.testnorge.sykemelding.domain.Sykemelding; +import no.nav.registre.testnorge.sykemelding.dto.ReceivedSykemeldingDTO; +import no.nav.registre.testnorge.sykemelding.external.eiFellesformat.XMLMottakenhetBlokk; +import no.nav.registre.testnorge.sykemelding.external.msgHead.XMLMsgHead; +import no.nav.registre.testnorge.sykemelding.external.xmlstds.XMLCS; +import no.nav.registre.testnorge.sykemelding.external.xmlstds.helseopplysningerarbeidsuforhet._2013_10_01.XMLDynaSvarType; +import no.nav.registre.testnorge.sykemelding.external.xmlstds.helseopplysningerarbeidsuforhet._2013_10_01.XMLHelseOpplysningerArbeidsuforhet; +import no.nav.registre.testnorge.sykemelding.external.xmlstds.helseopplysningerarbeidsuforhet._2013_10_01.XMLHelseOpplysningerArbeidsuforhet.UtdypendeOpplysninger.SpmGruppe; +import no.nav.testnav.libs.dto.sykemelding.v1.UtdypendeOpplysningerDTO.Restriksjon; +import org.springframework.stereotype.Component; + +import javax.xml.datatype.XMLGregorianCalendar; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Collections.emptyList; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; + +@Component +@RequiredArgsConstructor +@Slf4j +public class SykemeldingValidateMappingStrategy implements MappingStrategy { + + private static final String DUMMY_FNR = "12508407724"; + private static final String DUMMY_AKTOER_ID = "123456789"; + private static final String DUMMY_LEGEKONTOR_ORG_NAME = "Testkontoret"; + private static final String DUMMY_GATE = "Testveien 1"; + private static final Integer DUMMY_POSTNUMMER = 1234; + private static final Map> DUMMY_UTDYPENDE_OPPLYSNINGER = + Collections.singletonMap("1", Collections.singletonMap("2", + ReceivedSykemeldingDTO.SporsmalSvar.builder() + .sporsmal("Hva er din hovedplage?") + .svar("Tester") + .restriksjoner(List.of(Restriksjon.SKJERMET_FOR_ARBEIDSGIVER)) + .build())); + + @Override + public void register(MapperFactory factory) { + factory.classMap(Sykemelding.class, ReceivedSykemeldingDTO.class) + .customize(new CustomMapper<>() { + @Override + public void mapAtoB(Sykemelding source, ReceivedSykemeldingDTO target, MappingContext context) { + + var sykemeldingBuilder = ReceivedSykemeldingDTO.Sykemelding.builder(); + + + source.getFellesformat().getAny() + .forEach(any -> { + + target.setMsgId(source.getMsgId()); + target.setNavLogId(source.getMsgId()); + target.setId(source.getMsgId()); + target.setPersonNrPasient(DUMMY_FNR); + target.setLegekontorOrgName(DUMMY_LEGEKONTOR_ORG_NAME); + target.setFellesformat(String.valueOf(source.getFellesformat())); + + if (any instanceof XMLMsgHead xmlMsgHead) { + xmlMsgHead.getDocument().forEach(document -> + document.getRefDoc().getContent().getAny().forEach(refDoc -> { + + if (refDoc instanceof XMLHelseOpplysningerArbeidsuforhet xmlHelseOpplysningerArbeidsuforhet) { + sykemeldingBuilder.syketilfelleStartDato(xmlHelseOpplysningerArbeidsuforhet.getSyketilfelleStartDato()) + .id(source.getMsgId()) + .msgId(source.getMsgId()) + .pasientAktoerId(DUMMY_AKTOER_ID) + .navnFastlege(xmlHelseOpplysningerArbeidsuforhet.getPasient().getNavnFastlege()) + .arbeidsgiver(ReceivedSykemeldingDTO.Arbeidsgiver.builder() + .harArbeidsgiver(mapHarArbeidsgiver(xmlHelseOpplysningerArbeidsuforhet.getArbeidsgiver().getHarArbeidsgiver())) + .yrkesbetegnelse(xmlHelseOpplysningerArbeidsuforhet.getArbeidsgiver().getYrkesbetegnelse()) + .stillingsprosent(xmlHelseOpplysningerArbeidsuforhet.getArbeidsgiver().getStillingsprosent()) + .navn(xmlHelseOpplysningerArbeidsuforhet.getArbeidsgiver().getNavnArbeidsgiver()) + .build()) + .medisinskVurdering(mapMedisinskVurdering(xmlHelseOpplysningerArbeidsuforhet.getMedisinskVurdering())) + .behandler(ReceivedSykemeldingDTO.Behandler.builder() + .fornavn(xmlHelseOpplysningerArbeidsuforhet.getBehandler().getNavn().getFornavn()) + .mellomnavn(xmlHelseOpplysningerArbeidsuforhet.getBehandler().getNavn().getMellomnavn()) + .etternavn(xmlHelseOpplysningerArbeidsuforhet.getBehandler().getNavn().getEtternavn()) + .fnr(xmlHelseOpplysningerArbeidsuforhet.getBehandler().getId().getFirst().getId()) + .aktoerId(DUMMY_AKTOER_ID) + .adresse(ReceivedSykemeldingDTO.Adresse.builder() + .gate(DUMMY_GATE) + .postnummer(DUMMY_POSTNUMMER) + .build()) + .build()) + .avsenderSystem(ReceivedSykemeldingDTO.AvsenderSystem.builder() + .navn(xmlHelseOpplysningerArbeidsuforhet.getAvsenderSystem().getSystemNavn()) + .versjon(xmlHelseOpplysningerArbeidsuforhet.getAvsenderSystem().getSystemVersjon()) + .build()) + .kontaktMedPasient(ReceivedSykemeldingDTO.KontaktMedpasient.builder() + .build()) + .tiltakArbeidsplassen(nonNull(xmlHelseOpplysningerArbeidsuforhet.getTiltak()) ? + xmlHelseOpplysningerArbeidsuforhet.getTiltak().getTiltakArbeidsplassen() : null) + .tiltakNAV(nonNull(xmlHelseOpplysningerArbeidsuforhet.getTiltak()) ? + xmlHelseOpplysningerArbeidsuforhet.getTiltak().getTiltakNAV() : null) + .andreTiltak(nonNull(xmlHelseOpplysningerArbeidsuforhet.getTiltak()) ? + xmlHelseOpplysningerArbeidsuforhet.getTiltak().getAndreTiltak() : null) + .utdypendeOpplysninger(mapUtdypendeOpplysninger(xmlHelseOpplysningerArbeidsuforhet.getUtdypendeOpplysninger())) + .perioder(mapPerioder(xmlHelseOpplysningerArbeidsuforhet.getAktivitet().getPeriode())) + .prognose(mapPrognose(xmlHelseOpplysningerArbeidsuforhet.getPrognose())) + .behandletTidspunkt(LocalDateTime.now()) + .signaturDato(LocalDateTime.now()); + } + })); + } + if (any instanceof XMLMottakenhetBlokk xmlMottakenhetBlokk) { + + target.setMottattDato(convertDateNTime(xmlMottakenhetBlokk.getMottattDatotid())); + + } + var sykemelding = sykemeldingBuilder.build(); + + target.setPersonNrLege(sykemelding.getBehandler().getFnr()); + target.setSykmelding(sykemelding); + }); + } + }) + .register(); + } + + private ReceivedSykemeldingDTO.ArbeidsgiverType mapHarArbeidsgiver(XMLCS harArbeidsgiver) { + + if (isNull(harArbeidsgiver)) { + return ReceivedSykemeldingDTO.ArbeidsgiverType.INGEN_ARBEIDSGIVER; + } + return switch (harArbeidsgiver.getV()) { + case "1" -> ReceivedSykemeldingDTO.ArbeidsgiverType.EN_ARBEIDSGIVER; + case "2" -> ReceivedSykemeldingDTO.ArbeidsgiverType.FLERE_ARBEIDSGIVERE; + default -> ReceivedSykemeldingDTO.ArbeidsgiverType.INGEN_ARBEIDSGIVER; + }; + } + + private List mapPerioder(List perioder) { + + return perioder.stream() + .map(periode -> ReceivedSykemeldingDTO.Periode.builder() + .fom(periode.getPeriodeFOMDato()) + .tom(periode.getPeriodeTOMDato()) + .avventendeInnspillTilArbeidsgiver(nonNull(periode.getAvventendeSykmelding()) ? + periode.getAvventendeSykmelding().getInnspillTilArbeidsgiver() : null) + .gradert(ReceivedSykemeldingDTO.Gradert.builder() + .reisetilskudd(nonNull(periode.getGradertSykmelding()) ? + periode.getGradertSykmelding().isReisetilskudd() : null) + .build()) + .aktivitetIkkeMulig(mapAktivitetIkkeMulig(periode.getAktivitetIkkeMulig())) + .behandlingsdager(nonNull(periode.getBehandlingsdager()) ? + periode.getBehandlingsdager().getAntallBehandlingsdagerUke() : null) + .reisetilskudd(periode.isReisetilskudd()) + .build()) + .toList(); + } + + private ReceivedSykemeldingDTO.Prognose mapPrognose(XMLHelseOpplysningerArbeidsuforhet.Prognose prognose) { + + if (isNull(prognose)) { + return null; + } + + return ReceivedSykemeldingDTO.Prognose.builder() + .arbeidsforEtterPeriode(prognose.isArbeidsforEtterEndtPeriode()) + .hensynArbeidsplassen(prognose.getBeskrivHensynArbeidsplassen()) + .erIArbeid(nonNull(prognose.getErIArbeid()) ? + ReceivedSykemeldingDTO.ErIArbeid.builder() + .annetArbeidPaSikt(prognose.getErIArbeid().isAnnetArbeidPaSikt()) + .arbeidFOM(prognose.getErIArbeid().getArbeidFraDato()) + .vurderingsdato(prognose.getErIArbeid().getVurderingDato()) + .egetArbeidPaSikt(prognose.getErIArbeid().isEgetArbeidPaSikt()) + .build() : null) + .erIkkeIArbeid(nonNull(prognose.getErIkkeIArbeid()) ? + ReceivedSykemeldingDTO.ErIkkeIArbeid.builder() + .arbeidsforFOM(prognose.getErIkkeIArbeid().getArbeidsforFraDato()) + .vurderingsdato(prognose.getErIkkeIArbeid().getVurderingDato()) + .arbeidsforPaSikt(prognose.getErIkkeIArbeid().isArbeidsforPaSikt()) + .build() : null) + .build(); + } + + private Map> mapUtdypendeOpplysninger(XMLHelseOpplysningerArbeidsuforhet.UtdypendeOpplysninger utdypendeOpplysninger) { + + return isNull(utdypendeOpplysninger) || utdypendeOpplysninger.getSpmGruppe().isEmpty() ? DUMMY_UTDYPENDE_OPPLYSNINGER : + utdypendeOpplysninger.getSpmGruppe().stream() + .collect(Collectors.toMap(SpmGruppe::getSpmGruppeId, + gruppe -> gruppe.getSpmSvar().stream() + .collect(Collectors.toMap(XMLDynaSvarType::getSpmId, spmsvar -> ReceivedSykemeldingDTO.SporsmalSvar.builder() + .sporsmal(spmsvar.getSpmTekst()) + .svar(spmsvar.getSvarTekst()) + .restriksjoner(spmsvar.getRestriksjon().getRestriksjonskode().stream() + .map(XMLCS::getDN) + .map(Restriksjon::valueOf) + .toList()) + .build())))); + } + + private ReceivedSykemeldingDTO.AktivitetIkkeMulig mapAktivitetIkkeMulig(XMLHelseOpplysningerArbeidsuforhet.Aktivitet.Periode.AktivitetIkkeMulig aktivitetIkkeMulig) { + + if (isNull(aktivitetIkkeMulig)) { + return null; + } + + var medisinskeArsakTyper = !aktivitetIkkeMulig.getMedisinskeArsaker().getArsakskode().isEmpty() ? + aktivitetIkkeMulig.getMedisinskeArsaker().getArsakskode().stream() + .map(XMLCS::getV) + .map(ReceivedSykemeldingDTO.MedisinskArsakType::valueOf) + .toList() : null; + + var arbeidsforholdArsakTyper = !aktivitetIkkeMulig.getArbeidsplassen().getArsakskode().isEmpty() ? + aktivitetIkkeMulig.getArbeidsplassen().getArsakskode().stream() + .map(XMLCS::getV) + .map(ReceivedSykemeldingDTO.ArbeidsrelatertArsakType::valueOf) + .toList() : null; + + return ReceivedSykemeldingDTO.AktivitetIkkeMulig.builder() + .medisinskArsak(nonNull(aktivitetIkkeMulig.getMedisinskeArsaker()) ? + ReceivedSykemeldingDTO.MedisinskArsak.builder() + .arsak(medisinskeArsakTyper) + .beskrivelse(aktivitetIkkeMulig.getMedisinskeArsaker().getBeskriv()) + .build() : null) + .arbeidsrelatertArsak(nonNull(aktivitetIkkeMulig.getArbeidsplassen()) ? + ReceivedSykemeldingDTO.ArbeidsrelatertArsak.builder() + .arsak(arbeidsforholdArsakTyper) + .beskrivelse(aktivitetIkkeMulig.getArbeidsplassen().getBeskriv()) + .build() : null) + .build(); + } + + private ReceivedSykemeldingDTO.MedisinskVurdering mapMedisinskVurdering(XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering xmlMedisinskVurdering) { + + return ReceivedSykemeldingDTO.MedisinskVurdering.builder() + .hovedDiagnose(ReceivedSykemeldingDTO.Diagnose.builder() + .kode(xmlMedisinskVurdering.getHovedDiagnose().getDiagnosekode().getV()) + .system(xmlMedisinskVurdering.getHovedDiagnose().getDiagnosekode().getS()) + .tekst(xmlMedisinskVurdering.getHovedDiagnose().getDiagnosekode().getDN()) + .build()) + .biDiagnoser(mapBidiagnoser(xmlMedisinskVurdering.getBiDiagnoser())) + .annenFraversArsak(ReceivedSykemeldingDTO.AnnenFraversArsak.builder() + .beskrivelse(xmlMedisinskVurdering.getAnnenFraversArsak().getBeskriv()) + .build()) + .svangerskap(xmlMedisinskVurdering.isSvangerskap()) + .yrkesskade(xmlMedisinskVurdering.isYrkesskade()) + .yrkesskadeDato(xmlMedisinskVurdering.getYrkesskadeDato()) + .build(); + } + + private List mapBidiagnoser(XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering.BiDiagnoser biDiagnoser) { + + if (isNull(biDiagnoser)) { + return emptyList(); + } + + return biDiagnoser.getDiagnosekode().stream() + .map(diagnose -> ReceivedSykemeldingDTO.Diagnose.builder() + .kode(diagnose.getV()) + .system(diagnose.getS()) + .tekst(diagnose.getDN()) + .build()) + .toList(); + } + + private LocalDateTime convertDateNTime(XMLGregorianCalendar xmlGregorianCalendar) { + + return LocalDateTime.of(xmlGregorianCalendar.getYear(), xmlGregorianCalendar.getMonth(), + xmlGregorianCalendar.getDay(), xmlGregorianCalendar.getHour(), + xmlGregorianCalendar.getMinute(), xmlGregorianCalendar.getSecond(), + xmlGregorianCalendar.getMillisecond()); + } +} diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/provider/SykemeldingController.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/provider/SykemeldingController.java index 54a10649acc..820ca806da2 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/provider/SykemeldingController.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/provider/SykemeldingController.java @@ -1,27 +1,41 @@ package no.nav.registre.testnorge.sykemelding.provider; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import no.nav.registre.testnorge.sykemelding.domain.ApplicationInfo; import no.nav.registre.testnorge.sykemelding.domain.Sykemelding; import no.nav.registre.testnorge.sykemelding.service.SykemeldingService; import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingDTO; import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.ValidationResultDTO; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; @RestController @RequestMapping("/api/v1/sykemeldinger") @RequiredArgsConstructor +@Slf4j public class SykemeldingController { - private final SykemeldingService service; + private final SykemeldingService sykemeldingService; private final ApplicationInfo applicationInfo; @PostMapping public SykemeldingResponseDTO create(@RequestBody SykemeldingDTO dto) { - return service.send(new Sykemelding(dto, applicationInfo)); + log.info("Mottatt sykemelding: {}", dto); + + return sykemeldingService.send(new Sykemelding(dto, applicationInfo)); + } + + @PostMapping(value = "/validate") + public Mono validate(@RequestBody SykemeldingDTO dto) { + + log.info("Validering av sykemelding: {}", dto); + + return sykemeldingService.validate(new Sykemelding(dto, applicationInfo)); } } diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/service/SykemeldingService.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/service/SykemeldingService.java index e8a9e4f2302..c695920fef7 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/service/SykemeldingService.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/service/SykemeldingService.java @@ -1,18 +1,33 @@ package no.nav.registre.testnorge.sykemelding.service; import lombok.RequiredArgsConstructor; +import ma.glasnost.orika.MapperFacade; import no.nav.registre.testnorge.sykemelding.consumer.SyfoConsumer; +import no.nav.registre.testnorge.sykemelding.consumer.SyfosmreglerConsumer; import no.nav.registre.testnorge.sykemelding.domain.Sykemelding; +import no.nav.registre.testnorge.sykemelding.dto.ReceivedSykemeldingDTO; import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.ValidationResultDTO; import org.springframework.stereotype.Service; +import reactor.core.publisher.Mono; @Service @RequiredArgsConstructor public class SykemeldingService { + + private final MapperFacade mapperFacade; private final SyfoConsumer syfoConsumer; + private final SyfosmreglerConsumer syfosmreglerConsumer; public SykemeldingResponseDTO send(Sykemelding sykemelding) { return syfoConsumer.send(sykemelding); } + + public Mono validate(Sykemelding sykemelding) { + + var request = mapperFacade.map(sykemelding, ReceivedSykemeldingDTO.class); + + return syfosmreglerConsumer.validate(request); + } } \ No newline at end of file diff --git a/apps/sykemelding-api/src/main/resources/application-local.yml b/apps/sykemelding-api/src/main/resources/application-local.yml index bea43da510a..e67cb424320 100644 --- a/apps/sykemelding-api/src/main/resources/application-local.yml +++ b/apps/sykemelding-api/src/main/resources/application-local.yml @@ -1,3 +1,19 @@ +ibm: + mq: + queueManager: dummy + channel: dummy + connName: dummy + user: dummy + password: dummy + application-name: dummy + use-authentication-m-q-c-s-p: true +consumers: + sykemelding-proxy: + url: https://testnav-sykemelding-proxy.intern.dev.nav.no + cluster: dev-gcp + namespace: dolly + name: testnav-sykemelding-proxy + spring: config: import: "sm://" diff --git a/apps/sykemelding-api/src/main/resources/application.yml b/apps/sykemelding-api/src/main/resources/application.yml index 9e2485911f2..f1e9d0240b5 100644 --- a/apps/sykemelding-api/src/main/resources/application.yml +++ b/apps/sykemelding-api/src/main/resources/application.yml @@ -15,7 +15,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api://${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -55,4 +55,10 @@ ibm: user: ${IBM_MQ_USERNAME} password: ${IBM_MQ_PASSWORD} application-name: testnav-sykemelding-api - use-authentication-m-q-c-s-p: true \ No newline at end of file + use-authentication-m-q-c-s-p: true +consumers: + sykemelding-proxy: + url: http://testnav-sykemelding-proxy.dolly.svc.cluster.local + cluster: dev-gcp + namespace: dolly + name: testnav-sykemelding-proxy \ No newline at end of file diff --git a/apps/sykemelding-api/src/test/java/no/nav/registre/testnorge/sykemelding/mapper/MapperTestUtils.java b/apps/sykemelding-api/src/test/java/no/nav/registre/testnorge/sykemelding/mapper/MapperTestUtils.java new file mode 100644 index 00000000000..8211729e508 --- /dev/null +++ b/apps/sykemelding-api/src/test/java/no/nav/registre/testnorge/sykemelding/mapper/MapperTestUtils.java @@ -0,0 +1,27 @@ +package no.nav.registre.testnorge.sykemelding.mapper; + +import ma.glasnost.orika.CustomConverter; +import ma.glasnost.orika.MapperFacade; +import ma.glasnost.orika.impl.DefaultMapperFactory; + +import static java.util.Objects.nonNull; + +public class MapperTestUtils { + + public static MapperFacade createMapperFacadeForMappingStrategy(MappingStrategy... strategies) { + return createMapperFacadeForMappingStrategy(null, strategies); + } + + public static MapperFacade createMapperFacadeForMappingStrategy(CustomConverter converter, MappingStrategy... strategies) { + DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); + + for (MappingStrategy strategy : strategies) { + strategy.register(mapperFactory); + } + + if (nonNull(converter)) { + mapperFactory.getConverterFactory().registerConverter(converter); + } + return mapperFactory.getMapperFacade(); + } +} \ No newline at end of file diff --git a/apps/sykemelding-api/src/test/java/no/nav/registre/testnorge/sykemelding/mapper/SykemeldingValidateMappingStrategyTest.java b/apps/sykemelding-api/src/test/java/no/nav/registre/testnorge/sykemelding/mapper/SykemeldingValidateMappingStrategyTest.java new file mode 100644 index 00000000000..990c4af8e97 --- /dev/null +++ b/apps/sykemelding-api/src/test/java/no/nav/registre/testnorge/sykemelding/mapper/SykemeldingValidateMappingStrategyTest.java @@ -0,0 +1,249 @@ +package no.nav.registre.testnorge.sykemelding.mapper; + +import ma.glasnost.orika.MapperFacade; +import no.nav.registre.testnorge.sykemelding.domain.ApplicationInfo; +import no.nav.registre.testnorge.sykemelding.domain.Sykemelding; +import no.nav.registre.testnorge.sykemelding.dto.ReceivedSykemeldingDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.AdresseDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.AktivitetDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.ArbeidsgiverDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.DetaljerDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.DiagnoseDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.HelsepersonellDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.OrganisasjonDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.PasientDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.PeriodeDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.UtdypendeOpplysningerDTO; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.web.server.ResponseStatusException; + +import java.time.LocalDate; +import java.util.List; + +import static no.nav.testnav.libs.dto.sykemelding.v1.UtdypendeOpplysningerDTO.Restriksjon.SKJERMET_FOR_ARBEIDSGIVER; +import static no.nav.testnav.libs.dto.sykemelding.v1.UtdypendeOpplysningerDTO.Restriksjon.SKJERMET_FOR_PASIENT; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@ExtendWith(MockitoExtension.class) +class SykemeldingValidateMappingStrategyTest { + + private static final String DUMMY_FNR = "12508407724"; + private final ApplicationInfo applicationInfo = ApplicationInfo.builder() + .name("Test") + .version("1.0.0") + .build(); + private MapperFacade mapperFacade; + + private SykemeldingDTO getSykemeldingOK() { + + return SykemeldingDTO.builder() + .arbeidsgiver(ArbeidsgiverDTO.builder() + .stillingsprosent(100.0F) + .yrkesbetegnelse("8141108") + .navn("Herbert Gran") + .build()) + .detaljer(DetaljerDTO.builder() + .arbeidsforEtterEndtPeriode(false) + .build()) + .hovedDiagnose(DiagnoseDTO.builder() + .diagnose("Diagnostisk prosedyre IKA") + .diagnosekode("F43") + .system("123") + .build()) + .biDiagnoser(List.of(DiagnoseDTO.builder() + .diagnose("Diagnostisk prosedyre bla bla") + .diagnosekode("H14") + .system("456") + .build())) + .helsepersonell(HelsepersonellDTO.builder() + .etternavn("September") + .fornavn("August") + .hprId("9144897") + .ident("20486612345") + .samhandlerType("LEGE") + .build()) + .manglendeTilretteleggingPaaArbeidsplassen(false) + .mottaker(OrganisasjonDTO.builder() + .adresse(AdresseDTO.builder().build()) + .build()) + .pasient(PasientDTO.builder() + .adresse(AdresseDTO.builder() + .by("HONNINGSVÅG") + .gate("Hjellplassen 1") + .land("NOR") + .postnummer("9750") + .build()) + .etternavn("SUM") + .foedselsdato(LocalDate.of(1984, 10, 12)) + .fornavn("TAPPER") + .ident("12508407724") + .navKontor("2019") + .build()) + .perioder(List.of(PeriodeDTO.builder() + .aktivitet(AktivitetDTO.builder() + .behandlingsdager(0) + .grad(0) + .reisetilskudd(false) + .build()) + .fom(LocalDate.of(2024, 11, 21)) + .tom(LocalDate.of(2024, 11, 27)) + .build())) + .sender(OrganisasjonDTO.builder() + .adresse(AdresseDTO.builder() + .by("Oslo") + .gate("Sannergata 2") + .land("NOR") + .postnummer("0557") + .build()) + .build()) + .startDato(LocalDate.of(2024, 11, 28)) + .umiddelbarBistand(false) + .detaljer(DetaljerDTO.builder() + .tiltakArbeidsplass("Beskrivende tiltak fra arbeidsplassen") + .tiltakNav("Beskrivende tiltak fra NAV") + .andreTiltak("Andre tiltak") + .beskrivHensynArbeidsplassen("Beskrivende hensyn til arbeidsplassen") + .arbeidsforEtterEndtPeriode(true) + .build()) + .utdypendeOpplysninger(List.of(UtdypendeOpplysningerDTO.builder() + .spmGruppeId("6.3") + .spmGruppeTekst("Gruppe 6.3") + .spmSvar(List.of(UtdypendeOpplysningerDTO.SvarType.builder() + .spmId("6.3.1") + .spmTekst("Beskriv kort sykehistorie, symptomer og funn i dagens situasjon") + .svarTekst("word word word word") + .restriksjon(SKJERMET_FOR_ARBEIDSGIVER) + .build(), + UtdypendeOpplysningerDTO.SvarType.builder() + .spmId("6.3.2") + .spmTekst("Beskriv kort sykehistorie, symptomer og funn i dagens situasjon") + .svarTekst("word word word word") + .restriksjon(SKJERMET_FOR_PASIENT) + .build())) + .build())) + .build(); + } + + @BeforeEach + void setup() { + + mapperFacade = MapperTestUtils.createMapperFacadeForMappingStrategy(new SykemeldingValidateMappingStrategy()); + } + + @Test + void validateAllFields_OK() { + + var sykemeldingDTO = getSykemeldingOK(); + var sykemelding = new Sykemelding(sykemeldingDTO, applicationInfo); + var target = mapperFacade.map(sykemelding, ReceivedSykemeldingDTO.class); + + assertThat(target.getMsgId(), is(equalTo(sykemelding.getMsgId()))); + + assertThat(target.getSykmelding().getMedisinskVurdering(), allOf( + hasProperty("hovedDiagnose", allOf( + hasProperty("system", is(equalTo("123"))), + hasProperty("kode", is(equalTo("F43"))), + hasProperty("tekst", is(equalTo("Diagnostisk prosedyre IKA"))))), + hasProperty("biDiagnoser", contains(allOf( + hasProperty("system", is(equalTo("456"))), + hasProperty("kode", is(equalTo("H14"))), + hasProperty("tekst", is(equalTo("Diagnostisk prosedyre bla bla")))))), + hasProperty("yrkesskadeDato", is(equalTo(LocalDate.of(2024, 11, 21)))), + hasProperty("svangerskap", is(equalTo(false))), + hasProperty("yrkesskade", is(equalTo(false))), + hasProperty("annenFraversArsak", + hasProperty("beskrivelse", is(equalTo("Medisinsk årsak i kategorien annet")))))); + + assertThat(target.getSykmelding().getArbeidsgiver(), allOf( + hasProperty("harArbeidsgiver", is(equalTo(ReceivedSykemeldingDTO.ArbeidsgiverType.EN_ARBEIDSGIVER))), + hasProperty("navn", is(equalTo(sykemeldingDTO.getArbeidsgiver().getNavn()))), + hasProperty("yrkesbetegnelse", is(equalTo(sykemeldingDTO.getArbeidsgiver().getYrkesbetegnelse()))), + hasProperty("stillingsprosent", is(equalTo(sykemeldingDTO.getArbeidsgiver().getStillingsprosent().intValue()))))); + + assertThat(target.getSykmelding().getBehandler(), allOf( + hasProperty("fornavn", is(equalTo(sykemeldingDTO.getHelsepersonell().getFornavn()))), + hasProperty("mellomnavn", is(equalTo(sykemeldingDTO.getHelsepersonell().getMellomnavn()))), + hasProperty("etternavn", is(equalTo(sykemeldingDTO.getHelsepersonell().getEtternavn()))), + hasProperty("fnr", is(equalTo(sykemeldingDTO.getHelsepersonell().getIdent()))))); + + assertThat(target.getSykmelding().getAvsenderSystem(), allOf( + hasProperty("navn", is(equalTo(applicationInfo.getName()))), + hasProperty("versjon", is(equalTo(applicationInfo.getVersion()))))); + + assertThat(target.getPersonNrPasient(), is(equalTo(DUMMY_FNR))); + assertThat(target.getMottattDato(), is(equalTo(sykemeldingDTO.getStartDato().atStartOfDay()))); + + assertThat(target.getSykmelding().getNavnFastlege(), + is(equalTo(sykemeldingDTO.getHelsepersonell().getFornavn() + " " + sykemeldingDTO.getHelsepersonell().getEtternavn()))); + assertThat(target.getLegekontorOrgNr(), is(equalTo(sykemeldingDTO.getMottaker().getOrgNr()))); + + assertThat(target.getSykmelding().getUtdypendeOpplysninger(), + hasEntry(is("6.3"), allOf( + hasEntry(is("6.3.1"), allOf( + hasProperty("sporsmal", is(equalTo("Beskriv kort sykehistorie, symptomer og funn i dagens situasjon"))), + hasProperty("svar", is(equalTo("word word word word"))), + hasProperty("restriksjoner", is(equalTo(List.of(SKJERMET_FOR_ARBEIDSGIVER)))))), + hasEntry(is("6.3.2"), allOf( + hasProperty("sporsmal", is(equalTo("Beskriv kort sykehistorie, symptomer og funn i dagens situasjon"))), + hasProperty("svar", is(equalTo("word word word word"))), + hasProperty("restriksjoner", is(equalTo(List.of(SKJERMET_FOR_PASIENT))))))))); + + assertThat(target.getSykmelding().getPerioder(), contains(allOf( + hasProperty("fom", is(equalTo(LocalDate.of(2024, 11, 21)))), + hasProperty("tom", is(equalTo(LocalDate.of(2024, 11, 27)))), + hasProperty("gradert", + hasProperty("reisetilskudd", is(equalTo(false)))), + hasProperty("behandlingsdager", is(nullValue()))))); + + assertThat(target.getSykmelding().getPrognose(), allOf( + hasProperty("arbeidsforEtterPeriode", is(equalTo(true))), + hasProperty("hensynArbeidsplassen", is(equalTo("Beskrivende hensyn til arbeidsplassen"))), + hasProperty("erIArbeid", allOf( + hasProperty("egetArbeidPaSikt", is(equalTo(true))), + hasProperty("annetArbeidPaSikt", is(equalTo(true))), + hasProperty("arbeidFOM", is(equalTo(LocalDate.of(2024, 11, 21)))), + hasProperty("vurderingsdato", is(equalTo(LocalDate.of(2024, 11, 21)))))), + hasProperty("erIkkeIArbeid", is(nullValue())))); + + assertThat(target.getSykmelding().getTiltakNAV(), is(equalTo("Beskrivende tiltak fra NAV"))); + assertThat(target.getSykmelding().getTiltakArbeidsplassen(), is(equalTo("Beskrivende tiltak fra arbeidsplassen"))); + assertThat(target.getSykmelding().getAndreTiltak(), is(equalTo("Andre tiltak"))); + + assertThat(target.getPersonNrLege(), is(equalTo(sykemeldingDTO.getHelsepersonell().getIdent()))); + } + + @Test + void validateNoArbeidsgiver_OK() { + + var sykemeldingDTO = getSykemeldingOK(); + sykemeldingDTO.setArbeidsgiver(null); + + var sykemelding = new Sykemelding(sykemeldingDTO, applicationInfo); + var target = mapperFacade.map(sykemelding, ReceivedSykemeldingDTO.class); + + assertThat(target.getSykmelding().getArbeidsgiver(), allOf( + hasProperty("harArbeidsgiver", is(equalTo(ReceivedSykemeldingDTO.ArbeidsgiverType.INGEN_ARBEIDSGIVER))))); + } + + @Test + void validateNoPerioder_Failure() { + + var sykemeldingDTO = getSykemeldingOK(); + sykemeldingDTO.setPerioder(null); + + var exception = assertThrows(ResponseStatusException.class, () -> new Sykemelding(sykemeldingDTO, applicationInfo)); + assertThat(exception.getMessage(), is(equalTo("400 BAD_REQUEST \"Perioder må angis\""))); + } +} \ No newline at end of file diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/AdresseDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/AdresseDTO.java index dc046646336..076118be865 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/AdresseDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/AdresseDTO.java @@ -2,16 +2,15 @@ import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.EqualsAndHashCode; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; -@Value +@Data @Builder @AllArgsConstructor -@NoArgsConstructor(force = true) -@EqualsAndHashCode +@NoArgsConstructor public class AdresseDTO { + private String gate; private String postnummer; private String by; diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/AktivitetDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/AktivitetDTO.java index 59ea89c02ca..3f70e913664 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/AktivitetDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/AktivitetDTO.java @@ -3,16 +3,17 @@ import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; -@Value +@Data @Builder @AllArgsConstructor -@NoArgsConstructor(force = true) +@NoArgsConstructor public class AktivitetDTO { - private final Integer grad; - private final Boolean reisetilskudd; - private final Integer behandlingsdager; - private final Aktivitet aktivitet; + + private Integer grad; + private Boolean reisetilskudd; + private Integer behandlingsdager; + private Aktivitet aktivitet; } diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/ArbeidsgiverDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/ArbeidsgiverDTO.java index 3b96842651c..2e6f6d56855 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/ArbeidsgiverDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/ArbeidsgiverDTO.java @@ -2,16 +2,15 @@ import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.EqualsAndHashCode; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; -@Value +@Data @Builder @AllArgsConstructor -@NoArgsConstructor(force = true) -@EqualsAndHashCode +@NoArgsConstructor public class ArbeidsgiverDTO { + private String navn; private String yrkesbetegnelse; private Float stillingsprosent; diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/DetaljerDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/DetaljerDTO.java index f751dcb3c76..3603fbca382 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/DetaljerDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/DetaljerDTO.java @@ -2,19 +2,18 @@ import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Getter; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Setter; -@Getter -@Setter +@Data +@Builder @NoArgsConstructor @AllArgsConstructor -@Builder public class DetaljerDTO { private String tiltakArbeidsplass; private String tiltakNav; + private String andreTiltak; private Boolean arbeidsforEtterEndtPeriode; private String beskrivHensynArbeidsplassen; } diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/DiagnoseDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/DiagnoseDTO.java index 18ebbed0794..293124b1def 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/DiagnoseDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/DiagnoseDTO.java @@ -1,22 +1,17 @@ package no.nav.testnav.libs.dto.sykemelding.v1; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; -@Value +@Data @Builder @AllArgsConstructor -@NoArgsConstructor(force = true) +@NoArgsConstructor public class DiagnoseDTO { - @JsonProperty - private String diagnose; - @JsonProperty + private String diagnose; private String system; - - @JsonProperty private String diagnosekode; } diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/HelsepersonellDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/HelsepersonellDTO.java index d855e9b7b8e..3962f660f98 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/HelsepersonellDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/HelsepersonellDTO.java @@ -1,28 +1,20 @@ package no.nav.testnav.libs.dto.sykemelding.v1; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.EqualsAndHashCode; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; -@Value +@Data @Builder @AllArgsConstructor -@NoArgsConstructor(force = true) -@EqualsAndHashCode +@NoArgsConstructor public class HelsepersonellDTO { - @JsonProperty + private String ident; - @JsonProperty private String fornavn; - @JsonProperty private String mellomnavn; - @JsonProperty private String etternavn; - @JsonProperty private String hprId; - @JsonProperty private String samhandlerType; } diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/OrganisasjonDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/OrganisasjonDTO.java index 0e423729855..69d3013def3 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/OrganisasjonDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/OrganisasjonDTO.java @@ -2,17 +2,16 @@ import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.EqualsAndHashCode; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; -@Value +@Data @Builder @AllArgsConstructor -@NoArgsConstructor(force = true) -@EqualsAndHashCode +@NoArgsConstructor public class OrganisasjonDTO { - private final String navn; - private final String orgNr; - private final AdresseDTO adresse; + + private String navn; + private String orgNr; + private AdresseDTO adresse; } diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/PasientDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/PasientDTO.java index 5711f9066fd..ad060b2c579 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/PasientDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/PasientDTO.java @@ -2,18 +2,17 @@ import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.EqualsAndHashCode; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; import java.time.LocalDate; -@Value +@Data @Builder @AllArgsConstructor -@NoArgsConstructor(force = true) -@EqualsAndHashCode +@NoArgsConstructor public class PasientDTO { + private String ident; private String fornavn; private String mellomnavn; diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/PeriodeDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/PeriodeDTO.java index 8d79436bb73..99485ed5fd5 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/PeriodeDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/PeriodeDTO.java @@ -2,18 +2,17 @@ import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.EqualsAndHashCode; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; import java.time.LocalDate; -@Value +@Data @Builder @AllArgsConstructor -@NoArgsConstructor(force = true) -@EqualsAndHashCode +@NoArgsConstructor public class PeriodeDTO { + private LocalDate fom; private LocalDate tom; private AktivitetDTO aktivitet; diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/SykemeldingDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/SykemeldingDTO.java index 7b91ea7221a..5b51f04b3cd 100644 --- a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/SykemeldingDTO.java +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/SykemeldingDTO.java @@ -1,59 +1,62 @@ package no.nav.testnav.libs.dto.sykemelding.v1; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.EqualsAndHashCode; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; import java.time.LocalDate; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; -@Value +import static java.util.Objects.isNull; + +@Data @Builder @AllArgsConstructor -@NoArgsConstructor(force = true) -@EqualsAndHashCode +@NoArgsConstructor public class SykemeldingDTO { - @JsonProperty private LocalDate startDato; - @JsonProperty private PasientDTO pasient; - @JsonProperty private HelsepersonellDTO helsepersonell; - @JsonProperty private ArbeidsgiverDTO arbeidsgiver; - @JsonProperty private Boolean manglendeTilretteleggingPaaArbeidsplassen; - @JsonProperty private List perioder; - @JsonProperty private OrganisasjonDTO sender; - @JsonProperty private OrganisasjonDTO mottaker; - @JsonProperty private DiagnoseDTO hovedDiagnose; - @JsonProperty private List biDiagnoser; - @JsonProperty private DetaljerDTO detaljer; - @JsonProperty + private List utdypendeOpplysninger; private Boolean umiddelbarBistand; - @JsonIgnore + public List getPerioder() { + + if (isNull(perioder)) { + perioder = new ArrayList<>(); + } + return perioder; + } + public List getBiDiagnoser() { - if (biDiagnoser == null) { - return Collections.emptyList(); + + if (isNull(biDiagnoser)) { + biDiagnoser = new ArrayList<>(); } return biDiagnoser; } - @JsonIgnore + public List getUtdypendeOpplysninger() { + + if (isNull(utdypendeOpplysninger)) { + utdypendeOpplysninger = new ArrayList<>(); + } + return utdypendeOpplysninger; + } + public Boolean getManglendeTilretteleggingPaaArbeidsplassen() { return manglendeTilretteleggingPaaArbeidsplassen != null && manglendeTilretteleggingPaaArbeidsplassen; } } + diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/UtdypendeOpplysningerDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/UtdypendeOpplysningerDTO.java new file mode 100644 index 00000000000..0131ae0d86e --- /dev/null +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/UtdypendeOpplysningerDTO.java @@ -0,0 +1,48 @@ +package no.nav.testnav.libs.dto.sykemelding.v1; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Objects.isNull; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class UtdypendeOpplysningerDTO { + + private String spmGruppeId; + private String spmGruppeTekst; + private List spmSvar; + + public List getSpmSvar() { + + if (isNull(spmSvar)) { + spmSvar = new ArrayList<>(); + } + return spmSvar; + } + + public enum Restriksjon { + SKJERMET_FOR_ARBEIDSGIVER, + SKJERMET_FOR_PASIENT, + SKJERMET_FOR_NAV + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SvarType { + + private String spmId; + private String spmTekst; + private Restriksjon restriksjon; + private String svarTekst; + } +} diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/ValidationResultDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/ValidationResultDTO.java new file mode 100644 index 00000000000..3b7241057b8 --- /dev/null +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/ValidationResultDTO.java @@ -0,0 +1,47 @@ +package no.nav.testnav.libs.dto.sykemelding.v1; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.http.HttpStatus; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Objects.isNull; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ValidationResultDTO { + + private HttpStatus httpStatus; + private String message; + + private AllowedValues status; + private List ruleHits; + + public List getRuleHits() { + + if (isNull(ruleHits)) { + ruleHits = new ArrayList<>(); + } + return ruleHits; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Items { + + private String ruleName; + private String messageForSender; + private String messageForUser; + private AllowedValues ruleStatus; + } + + public enum AllowedValues {OK, MANUAL_PROCESSING, INVALID} +} diff --git a/proxies/sykemelding-proxy/config.yml b/proxies/sykemelding-proxy/config.yml index e1b061e8484..4d2a78276fc 100644 --- a/proxies/sykemelding-proxy/config.yml +++ b/proxies/sykemelding-proxy/config.yml @@ -40,6 +40,8 @@ spec: - application: testnav-sykemelding-api - application: testnav-sykemelding-api-dev - application: testnav-oversikt-frontend + - application: testnav-sykemelding-api-dev + - application: testnav-sykemelding-api outbound: rules: - application: syfosmregler