Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1308a45
- Refactor Consumers and RouteLocatorConfig to support new services: …
stigus Sep 19, 2025
6ffdd0a
Add support for routing `syfosmregler` and `tsm-input-dolly` services…
stigus Sep 19, 2025
7440613
Update syfosmregler validation URL; comment out auth filter in TSM ro…
stigus Sep 19, 2025
6c3b525
Enable auth filter for TSM route in RouteLocatorConfig
stigus Sep 22, 2025
0c30235
Enable auth filter for TSM route in RouteLocatorConfig
stigus Sep 22, 2025
f162832
Merge branch 'refs/heads/master' into feature/ny-sykemelding-frontend
stigus Sep 22, 2025
f7909ee
Add support for TSM sykemelding processing and routing; refactor syke…
stigus Sep 22, 2025
e324ba4
Merge branch 'master' into feature/ny-sykemelding-frontend
stigus Sep 22, 2025
00b23ed
Merge branch 'master' into feature/ny-sykemelding-frontend
stigus Sep 23, 2025
dd2e8ae
Refactor Sykemelding handling to remove unused MapperFacade; add supp…
stigus Sep 23, 2025
a2ace89
Merge branch 'refs/heads/master' into feature/ny-sykemelding-frontend
stigus Sep 24, 2025
ff35096
Add TSM sykemelding delete command and integrate deletion logic in Sy…
stigus Sep 24, 2025
9c2a9af
Deploy backend test
stigus Sep 25, 2025
e3e7089
Fix missing newline at EOF in SykemeldingProxyApplicationStarter.
stigus Sep 25, 2025
28aff41
Add reordered proxy rules for sykemelding and other services in confi…
stigus Sep 25, 2025
1466f6b
Simplify status messages in SykemeldingClient by removing redundant p…
stigus Sep 25, 2025
8d6aed2
Refactor Sykemelding classes and logic: replace `TsmSykemelding` with…
stigus Sep 25, 2025
7b1682f
- Add support for "Ny Sykemelding" in Sykemelding UI and backend inte…
stigus Sep 25, 2025
ec9429b
- Add support for "Ny Sykemelding" in Sykemelding UI and backend inte…
stigus Sep 25, 2025
a65f32a
Merge branch 'master' into feature/ny-sykemelding-frontend
stigus Sep 25, 2025
9fe26e3
- Replace `defaultSelected` fallback value in Datepicker component wi…
stigus Sep 25, 2025
9a85674
- Remove unused `data` prop from `Visning` component in `MiljoTabs`.
stigus Sep 25, 2025
665a5f9
- Remove unused `ident` prop from `VisningAvBestilling` in `Visning` …
stigus Sep 25, 2025
45b52c4
- Fix typo in help text for "Ny Sykemelding" component.
stigus Sep 25, 2025
7b231b7
Refactor sykemelding handling: adjust error logging, update DTO struc…
stigus Sep 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions apps/dolly-backend/config.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,12 @@ spec:
outbound:
rules:
- application: generer-navn-service
- application: testnav-arbeidsplassencv-proxy
- application: testnav-arbeidssoekerregisteret-proxy
- application: testnav-bruker-service-dev
- application: testnav-inntektsmelding-service
- application: testnav-kodeverk-service
- application: testnav-miljoer-service
- application: testnav-organisasjon-forvalter
- application: testnav-organisasjon-service
- application: testnav-nom-proxy
- application: testnav-pdl-forvalter-dev
- application: testnav-person-service
- application: testnav-skattekort-service
Expand All @@ -45,12 +42,16 @@ spec:
- application: testnav-synt-sykemelding-api
- application: testnav-synt-sykemelding-api-dev
- application: testnav-tps-messaging-service
- application: testnav-yrkesskade-proxy
- application: testnorge-profil-api-dev
- application: etterlatte-testdata
namespace: etterlatte
- application: logging
namespace: nais-system
- application: testnav-yrkesskade-proxy
- application: testnav-nom-proxy
- application: testnav-sykemelding-proxy
- application: testnav-arbeidsplassencv-proxy
- application: testnav-arbeidssoekerregisteret-proxy
external:
- host: testnav-arena-forvalteren-proxy.dev-fss-pub.nais.io
- host: testnav-brregstub-proxy.dev-fss-pub.nais.io
Expand Down
9 changes: 5 additions & 4 deletions apps/dolly-backend/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,28 @@ spec:
outbound:
rules:
- application: generer-navn-service
- application: testnav-arbeidsplassencv-proxy
- application: testnav-arbeidssoekerregisteret-proxy
- application: testnav-bruker-service
- application: testnav-inntektsmelding-service
- application: testnav-kodeverk-service
- application: testnav-miljoer-service
- application: testnav-organisasjon-forvalter
- application: testnav-organisasjon-service
- application: testnav-nom-proxy
- application: testnav-pdl-forvalter
- application: testnav-person-service
- application: testnav-skattekort-service
- application: testnav-sykemelding-api
- application: testnav-synt-sykemelding-api
- application: testnav-tps-messaging-service
- application: testnav-yrkesskade-proxy
- application: testnorge-profil-api
- application: etterlatte-testdata
namespace: etterlatte
- application: logging
namespace: nais-system
- application: testnav-yrkesskade-proxy
- application: testnav-nom-proxy
- application: testnav-arbeidsplassencv-proxy
- application: testnav-arbeidssoekerregisteret-proxy
- application: testnav-sykemelding-proxy
external:
- host: testnav-arena-forvalteren-proxy.dev-fss-pub.nais.io
- host: testnav-brregstub-proxy.dev-fss-pub.nais.io
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ public static void main(String[] args) {
.initializers(new NaisEnvironmentApplicationContextInitializer())
.run(args);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.core.util.Json;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MappingContext;
import no.nav.dolly.bestilling.ClientRegister;
import no.nav.dolly.bestilling.personservice.PersonServiceConsumer;
import no.nav.dolly.bestilling.sykemelding.domain.DetaljertSykemeldingRequest;
import no.nav.dolly.bestilling.sykemelding.domain.TsmSykemeldingRequest;
import no.nav.dolly.bestilling.sykemelding.dto.NySykemeldingResponse;
import no.nav.dolly.bestilling.sykemelding.dto.SykemeldingResponse;
import no.nav.dolly.config.ApplicationConfig;
import no.nav.dolly.consumer.kodeverk.KodeverkConsumer;
Expand All @@ -21,8 +24,8 @@
import no.nav.dolly.domain.resultset.dolly.DollyPerson;
import no.nav.dolly.domain.resultset.sykemelding.RsSykemelding;
import no.nav.dolly.errorhandling.ErrorStatusDecoder;
import no.nav.dolly.service.TransaksjonMappingService;
import no.nav.dolly.service.TransactionHelperService;
import no.nav.dolly.service.TransaksjonMappingService;
Comment on lines 25 to +28
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

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

[nitpick] Import statements are not in alphabetical order. Consider placing imports in consistent alphabetical order for better code organization.

Suggested change
import no.nav.dolly.service.TransactionHelperService;
import no.nav.dolly.service.TransaksjonMappingService;
import no.nav.dolly.service.TransaksjonMappingService;
import no.nav.dolly.service.TransactionHelperService;

Copilot uses AI. Check for mistakes.

import no.nav.testnav.libs.reactivecore.web.WebClientError;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.stereotype.Service;
Expand All @@ -32,9 +35,9 @@
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static no.nav.dolly.domain.resultset.SystemTyper.SYKEMELDING;
import static no.nav.dolly.errorhandling.ErrorStatusDecoder.encodeStatus;
Expand All @@ -47,6 +50,7 @@
public class SykemeldingClient implements ClientRegister {

private final SykemeldingConsumer sykemeldingConsumer;
private final TsmSykemeldingConsumer tsmSykemeldingConsumer;
private final ErrorStatusDecoder errorStatusDecoder;
private final TransaksjonMappingService transaksjonMappingService;
private final MapperFacade mapperFacade;
Expand All @@ -58,134 +62,161 @@ public class SykemeldingClient implements ClientRegister {
private final ApplicationConfig applicationConfig;

@Override
public Mono<BestillingProgress> gjenopprett(RsDollyUtvidetBestilling bestilling, DollyPerson dollyPerson, BestillingProgress progress, boolean isOpprettEndre) {

return Mono.just(bestilling)
.filter(bestillling -> nonNull(bestillling.getSykemelding()))
.map(RsDollyUtvidetBestilling::getSykemelding)
.flatMap(sykemelding -> transaksjonMappingService.existAlready(SYKEMELDING, dollyPerson.getIdent(), null, bestilling.getId())
.flatMap(exists -> {

if (BooleanUtils.isTrue(exists) && !isOpprettEndre) {
return setProgress(progress, "OK");

} else {
return setProgress(progress, getGenereringStartet())
.then(getPerson(dollyPerson.getIdent())
.flatMap(persondata ->
postDetaljertSykemelding(sykemelding, persondata)
.filter(Objects::nonNull)
.flatMap(status -> saveTransaksjonId(status, bestilling.getId())
.thenReturn(status))
.map(this::getStatus))
.timeout(Duration.ofSeconds(applicationConfig.getClientTimeout()))
.onErrorResume(error -> Mono.just(encodeStatus(WebClientError.describe(error).getMessage())))
.collect(Collectors.joining())
.flatMap(status -> oppdaterStatus(progress, status)));
}
}));
}
public Mono<BestillingProgress> gjenopprett(RsDollyUtvidetBestilling bestilling,
DollyPerson dollyPerson,
BestillingProgress progress,
boolean isOpprettEndre) {

private Mono<BestillingProgress> oppdaterStatus(BestillingProgress progress, String status) {
RsSykemelding sykemelding = bestilling.getSykemelding();

return transactionHelperService.persister(progress, BestillingProgress::getSykemeldingStatus,
BestillingProgress::setSykemeldingStatus, status);
if (isNull(sykemelding)) {
return Mono.just(progress);
}

if (sykemelding.hasNySykemelding()) {
var nySykemelding = sykemelding.getNySykemelding();
return setProgress(progress, getGenereringStartet())
.then(postNySykemelding(nySykemelding, dollyPerson.getIdent())
.map(this::getStatus)
.timeout(Duration.ofSeconds(applicationConfig.getClientTimeout()))
.onErrorResume(error ->
Mono.just(encodeStatus(WebClientError.describe(error).getMessage()))))
.flatMap(status -> oppdaterStatus(progress, status));
}

if (sykemelding.hasDetaljertSykemelding()) {

return transaksjonMappingService.existAlready(
SYKEMELDING, dollyPerson.getIdent(), null, bestilling.getId())
.flatMap(exists -> {
if (BooleanUtils.isTrue(exists) && !isOpprettEndre) {
return setProgress(progress, "OK");
}
return setProgress(progress, getGenereringStartet())
.then(getPerson(dollyPerson.getIdent())
.flatMap(persondata ->
postDetaljertSykemelding(sykemelding, persondata)
.flatMap(resp -> saveTransaksjonId(resp, bestilling.getId())
.thenReturn(resp))
.map(this::getStatus))
.timeout(Duration.ofSeconds(applicationConfig.getClientTimeout()))
.onErrorResume(error ->
Mono.just(encodeStatus(WebClientError.describe(error).getMessage())))
.collect(Collectors.joining()))
.flatMap(status -> oppdaterStatus(progress, status));
});
}
return Mono.just(progress);
}

@Override
public void release(List<String> identer) {
identer.forEach(ident -> tsmSykemeldingConsumer.deleteTsmSykemeldinger(ident)
.doOnError(WebClientError.logTo(log))
.subscribe());
}

// Sletting er ikke støttet
private Mono<BestillingProgress> oppdaterStatus(BestillingProgress progress, String status) {
return transactionHelperService.persister(
progress,
BestillingProgress::getSykemeldingStatus,
BestillingProgress::setSykemeldingStatus,
status);
}

private String getStatus(SykemeldingResponse status) {

log.info("Sykemelding response for {} mottatt, status: {}", status.getIdent(), status.getStatus());
return status.getStatus().is2xxSuccessful() ? "OK" :
errorStatusDecoder.getErrorText(status.getStatus(), status.getAvvik());
return status.getStatus().is2xxSuccessful()
? "OK"
: errorStatusDecoder.getErrorText(status.getStatus(), status.getAvvik());
}

private Mono<BestillingProgress> setProgress(BestillingProgress progress, String status) {
private String getStatus(NySykemeldingResponse status) {
log.info("Ny sykemelding response for {} mottatt, {}", status.ident(), Json.pretty(status));
return isNull(status.error())
? "OK"
: status.error();
}

return transactionHelperService.persister(progress, BestillingProgress::getSykemeldingStatus,
BestillingProgress::setSykemeldingStatus, status);
private Mono<BestillingProgress> setProgress(BestillingProgress progress, String status) {
return transactionHelperService.persister(
progress,
BestillingProgress::getSykemeldingStatus,
BestillingProgress::setSykemeldingStatus,
status);
}

private Flux<PdlPersonBolk.Data> getPerson(String ident) {

return personServiceConsumer.getPdlPersoner(List.of(ident))
.filter(pdlPersonBolk -> nonNull(pdlPersonBolk.getData()))
.map(PdlPersonBolk::getData);
}

private Mono<Norg2EnhetResponse> getNorgenhet(PdlPersonBolk.Data persondata) {

var geografiskOmrade = persondata.getHentGeografiskTilknytningBolk().stream()
.map(PdlPersonBolk.GeografiskTilknytningBolk::getGeografiskTilknytning)
.map(geografiskTilknytning -> nonNull(geografiskTilknytning) &&
isNotBlank(geografiskTilknytning.getGtType()) ?
switch (geografiskTilknytning.getGtType()) {
case "KOMMUNE" -> geografiskTilknytning.getGtKommune();
case "BYDEL" -> geografiskTilknytning.getGtBydel();
.map(gt -> nonNull(gt) && isNotBlank(gt.getGtType()) ?
switch (gt.getGtType()) {
case "KOMMUNE" -> gt.getGtKommune();
case "BYDEL" -> gt.getGtBydel();
default -> null;
} : null)
.collect(Collectors.joining());

return isNotBlank(geografiskOmrade) ? norg2Consumer.getNorgEnhet(geografiskOmrade) : Mono.empty();
}

private Mono<SykemeldingResponse> postDetaljertSykemelding(RsSykemelding sykemelding,
PdlPersonBolk.Data persondata) {

return Mono.just(sykemelding)
.filter(RsSykemelding::hasDetaljertSykemelding)
.map(RsSykemelding::getDetaljertSykemelding)
.flatMap(detaljert ->
Mono.zip(kodeverkConsumer.getKodeverkByName("Postnummer"), getNorgenhet(persondata))
.flatMap(kodeverk -> {

var detaljertSykemeldingRequest =
mapperFacade.map(detaljert,
DetaljertSykemeldingRequest.class);

var req = mapperFacade.map(detaljert, DetaljertSykemeldingRequest.class);
var context = new MappingContext.Factory().getContext();
context.setProperty("postnummer", kodeverk.getT1());
context.setProperty("norg2Enhet", kodeverk.getT2());

detaljertSykemeldingRequest.setPasient(mapperFacade.map(persondata,
DetaljertSykemeldingRequest.Pasient.class, context));

return sykemeldingConsumer.postDetaljertSykemelding(detaljertSykemeldingRequest);
req.setPasient(mapperFacade.map(
persondata,
DetaljertSykemeldingRequest.Pasient.class,
context));
return sykemeldingConsumer.postDetaljertSykemelding(req);
}));
}

private Mono<TransaksjonMapping> saveTransaksjonId(SykemeldingResponse sykemelding, Long bestillingId) {
private Mono<NySykemeldingResponse> postNySykemelding(RsSykemelding.RsNySykemelding rsNySykemelding,
String ident) {

if (sykemelding.getStatus().is2xxSuccessful()) {
var aktivitet = rsNySykemelding.getAktivitet().stream()
.map(a -> new TsmSykemeldingRequest.Aktivitet(a.getFom(), a.getTom()))
.collect(Collectors.toList());

log.info("Lagrer transaksjon for {} i q1 ", sykemelding.getIdent());
TsmSykemeldingRequest request = new TsmSykemeldingRequest(ident, aktivitet);

sykemelding.getSykemeldingRequest().setSykemeldingId(sykemelding.getMsgId());
return tsmSykemeldingConsumer.postTsmSykemelding(request);
}

private Mono<TransaksjonMapping> saveTransaksjonId(SykemeldingResponse response, Long bestillingId) {
if (response.getStatus().is2xxSuccessful()) {
response.getSykemeldingRequest().setSykemeldingId(response.getMsgId());
return transaksjonMappingService.save(TransaksjonMapping.builder()
.ident(sykemelding.getIdent())
.ident(response.getIdent())
.bestillingId(bestillingId)
.transaksjonId(toJson(sykemelding.getSykemeldingRequest()))
.transaksjonId(toJson(response.getSykemeldingRequest()))
.datoEndret(LocalDateTime.now())
.system(SYKEMELDING.name())
.miljoe("q1")
.build());
} else {
return Mono.empty();
}
return Mono.empty();
}

private String toJson(Object object) {

try {
return objectMapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
log.error("Feilet å konvertere transaksjonsId for sykemelding");
return null;
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
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;
import no.nav.dolly.bestilling.sykemelding.command.SyfosmreglerSykemeldingPostCommand;
import no.nav.dolly.bestilling.sykemelding.domain.DetaljertSykemeldingRequest;
import no.nav.dolly.bestilling.sykemelding.dto.SykemeldingResponse;
import no.nav.dolly.config.Consumers;
Expand Down Expand Up @@ -40,13 +40,13 @@ public SykemeldingConsumer(
.build();
}

@Timed(name = "providers", tags = {"operation", "detaljertsykemelding_opprett"})
@Timed(name = "providers", tags = { "operation", "detaljertsykemelding_opprett" })
public Mono<SykemeldingResponse> postDetaljertSykemelding(DetaljertSykemeldingRequest detaljertSykemeldingRequest) {

log.info("Detaljert Sykemelding sendt {}", Json.pretty(detaljertSykemeldingRequest));

return tokenService.exchange(serverProperties)
.flatMap(token -> new SykemeldingPostCommand(webClient, detaljertSykemeldingRequest,
.flatMap(token -> new SyfosmreglerSykemeldingPostCommand(webClient, detaljertSykemeldingRequest,
token.getTokenValue()).call());
}

Expand Down
Loading