From 4f590d594773f629ddd843c6ab7a145442a414ed Mon Sep 17 00:00:00 2001 From: Natalie Uranes Date: Tue, 10 Dec 2024 14:37:20 +0100 Subject: [PATCH] chore: tilbake til gosys endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: tilbake til gosys for nasjonal oppgave * chore: remove get sykmelder request * chore: refactoring to use updated to handle oppgaver --------- Co-authored-by: Jørn-Are Flaten --- .../digitalisering/api/DocumentController.kt | 2 +- .../ferdigstilling/FerdigstillingService.kt | 1 - .../papirsykmelding/NasjonalCommonService.kt | 24 +- .../papirsykmelding/NasjonalOppgaveService.kt | 244 ++++++++++-------- .../NasjonalSykmeldingService.kt | 12 +- .../api/NasjonalOppgaveController.kt | 22 +- .../api/SmregistreringClient.kt | 47 ---- .../db/NasjonalOppgaveRepository.kt | 5 +- .../db/model/NasjonalManuellOppgaveDAO.kt | 12 +- .../OppgaveSecurityService.kt | 31 ++- .../no/nav/sykdig/metrics/MetricRegister.kt | 5 + .../digitalisering/OppgaveDataFetcherTest.kt | 2 +- .../FerdigstillingServiceTest.kt | 94 ++++++- .../NasjonalOppgaveServiceTest.kt | 12 + 14 files changed, 302 insertions(+), 211 deletions(-) diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/api/DocumentController.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/api/DocumentController.kt index 9214392f..32ca0537 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/api/DocumentController.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/api/DocumentController.kt @@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.ResponseBody import org.springframework.web.bind.annotation.RestController -import java.util.UUID +import java.util.* @RestController class DocumentController( diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/ferdigstilling/FerdigstillingService.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/ferdigstilling/FerdigstillingService.kt index 142fd780..05388a43 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/ferdigstilling/FerdigstillingService.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/ferdigstilling/FerdigstillingService.kt @@ -5,7 +5,6 @@ import no.nav.sykdig.applog import no.nav.sykdig.config.kafka.OK_SYKMELDING_TOPIC import no.nav.sykdig.digitalisering.dokarkiv.DokarkivClient import no.nav.sykdig.digitalisering.dokument.DocumentService -import no.nav.sykdig.digitalisering.felles.Periode import no.nav.sykdig.digitalisering.ferdigstilling.mapping.mapToReceivedSykmelding import no.nav.sykdig.digitalisering.ferdigstilling.oppgave.OppgaveClient import no.nav.sykdig.digitalisering.helsenett.SykmelderService diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalCommonService.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalCommonService.kt index 1d373a04..8c23753d 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalCommonService.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalCommonService.kt @@ -125,6 +125,7 @@ class NasjonalCommonService( verdi } } + fun getNavIdent(): Veileder { val authentication = SecurityContextHolder.getContext().authentication as JwtAuthenticationToken return Veileder(authentication.token.claims["NAVident"].toString()) @@ -134,6 +135,7 @@ class NasjonalCommonService( val authentication = SecurityContextHolder.getContext().authentication as JwtAuthenticationToken return authentication.token.claims["preferred_username"].toString() } + private fun toSykmelding(sykmeldingId: String, oppgave: NasjonalManuellOppgaveDAO): Sykmelding { requireNotNull(oppgave.papirSmRegistrering.aktorId) { "PapirSmRegistrering.aktorId er null" } requireNotNull(oppgave.papirSmRegistrering.medisinskVurdering) { "PapirSmRegistrering.medisinskVurdering er null" } @@ -156,17 +158,33 @@ class NasjonalCommonService( meldingTilArbeidsgiver = oppgave.papirSmRegistrering.meldingTilArbeidsgiver, kontaktMedPasient = KontaktMedPasient( kontaktDato = oppgave.papirSmRegistrering.kontaktMedPasient?.kontaktDato, - begrunnelseIkkeKontakt = oppgave.papirSmRegistrering.kontaktMedPasient?.begrunnelseIkkeKontakt + begrunnelseIkkeKontakt = oppgave.papirSmRegistrering.kontaktMedPasient?.begrunnelseIkkeKontakt, ), behandletTidspunkt = LocalDateTime.from(oppgave.papirSmRegistrering.behandletTidspunkt), behandler = oppgave.papirSmRegistrering.behandler, - avsenderSystem = AvsenderSystem( //TODO + avsenderSystem = AvsenderSystem( + //TODO navn = "Navn avsendersystem", - versjon = "0.0" + versjon = "0.0", ), syketilfelleStartDato = oppgave.papirSmRegistrering.syketilfelleStartDato, signaturDato = LocalDateTime.from(oppgave.papirSmRegistrering.behandletTidspunkt), navnFastlege = "Fastlege navn", //TODO ) } + + fun getLoggingMeta(sykmeldingId: String, oppgave: NasjonalManuellOppgaveDAO): LoggingMeta { + return LoggingMeta( + mottakId = sykmeldingId, + dokumentInfoId = oppgave.dokumentInfoId, + msgId = sykmeldingId, + sykmeldingId = sykmeldingId, + journalpostId = oppgave.journalpostId, + ) + } } + +fun isValidOppgaveId(oppgaveId: String): Boolean { + val regex = Regex("^\\d{9}$|^[a-zA-Z0-9]{1,20}$") + return oppgaveId.matches(regex) +} \ No newline at end of file diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalOppgaveService.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalOppgaveService.kt index 2947999e..33c5698f 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalOppgaveService.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalOppgaveService.kt @@ -2,10 +2,12 @@ package no.nav.sykdig.digitalisering.papirsykmelding import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import net.logstash.logback.argument.StructuredArguments import no.nav.sykdig.LoggingMeta import no.nav.sykdig.applog import no.nav.sykdig.digitalisering.exceptions.NoOppgaveException import no.nav.sykdig.digitalisering.ferdigstilling.FerdigstillingService +import no.nav.sykdig.digitalisering.ferdigstilling.GosysService import no.nav.sykdig.digitalisering.ferdigstilling.oppgave.OppgaveClient import no.nav.sykdig.digitalisering.mapAvvisningsgrunn import no.nav.sykdig.digitalisering.papirsykmelding.api.SmregistreringClient @@ -20,6 +22,7 @@ import no.nav.sykdig.digitalisering.papirsykmelding.db.model.NasjonalManuellOppg import no.nav.sykdig.digitalisering.papirsykmelding.db.model.Utfall import no.nav.sykdig.digitalisering.pdl.PersonService import no.nav.sykdig.generated.types.Avvisingsgrunn +import no.nav.sykdig.metrics.MetricRegister import no.nav.sykdig.securelog import org.springframework.http.HttpStatus import org.springframework.http.HttpStatusCode @@ -36,6 +39,8 @@ class NasjonalOppgaveService( private val ferdigstillingService: FerdigstillingService, private val smregistreringClient: SmregistreringClient, private val nasjonalCommonService: NasjonalCommonService, + private val gosysService: GosysService, + private val metricRegister: MetricRegister, ) { val log = applog() val securelog = securelog() @@ -97,7 +102,7 @@ class NasjonalOppgaveService( private fun findByOppgaveId(oppgaveId: String): NasjonalManuellOppgaveDAO? { - if(!isValidOppgaveId(oppgaveId)) + if (!isValidOppgaveId(oppgaveId)) throw IllegalArgumentException("Invalid oppgaveId does not contain only alphanumerical characters. oppgaveId: $oppgaveId") val oppgave = nasjonalOppgaveRepository.findByOppgaveId(oppgaveId.toInt()) ?: return null @@ -172,99 +177,100 @@ class NasjonalOppgaveService( log.info("Finner ikke uløst oppgave med id $oppgaveId") return null } + fun avvisOppgave( oppgaveId: String, request: String, navEnhet: String, authorization: String - ): ResponseEntity { + ): ResponseEntity { val eksisterendeOppgave = getOppgave(oppgaveId, authorization) - if(eksisterendeOppgave == null) { - log.info("Fant ikke oppgave som skulle avvises: $oppgaveId") - return ResponseEntity(HttpStatus.NOT_FOUND) - } + if (eksisterendeOppgave == null) { + log.info("Fant ikke oppgave som skulle avvises: $oppgaveId") + return ResponseEntity(HttpStatus.NOT_FOUND) + } - if(eksisterendeOppgave.ferdigstilt) { - log.info("Oppgave med id $oppgaveId er allerede ferdigstilt") - return ResponseEntity(HttpStatus.NO_CONTENT) - } + if (eksisterendeOppgave.ferdigstilt) { + log.info("Oppgave med id $oppgaveId er allerede ferdigstilt") + return ResponseEntity(HttpStatus.NO_CONTENT) + } - val avvisningsgrunn = mapper.readValue(request, AvvisSykmeldingRequest::class.java).reason - val veilederIdent = nasjonalCommonService.getNavIdent().veilederIdent + val avvisningsgrunn = mapper.readValue(request, AvvisSykmeldingRequest::class.java).reason + val veilederIdent = nasjonalCommonService.getNavIdent().veilederIdent - ferdigstillNasjonalAvvistOppgave(eksisterendeOppgave, navEnhet, avvisningsgrunn, veilederIdent) - oppdaterOppgave( - eksisterendeOppgave.sykmeldingId, - utfall = Utfall.AVVIST.toString(), - ferdigstiltAv = veilederIdent, - avvisningsgrunn = avvisningsgrunn, - null - ) + ferdigstillNasjonalAvvistOppgave(eksisterendeOppgave, navEnhet, avvisningsgrunn, veilederIdent) + oppdaterOppgave( + eksisterendeOppgave.sykmeldingId, + utfall = Utfall.AVVIST.toString(), + ferdigstiltAv = veilederIdent, + avvisningsgrunn = avvisningsgrunn, + null + ) - log.info("Har avvist oppgave med oppgaveId $oppgaveId") - return ResponseEntity(HttpStatus.NO_CONTENT) + log.info("Har avvist oppgave med oppgaveId $oppgaveId") + return ResponseEntity(HttpStatus.NO_CONTENT) - } + } -fun mapToDao( - papirManuellOppgave: PapirManuellOppgave, - existingId: UUID?, - ferdigstilt: Boolean = false -): NasjonalManuellOppgaveDAO { - mapper.registerModules(JavaTimeModule()) - securelog.info("Mapper til DAO: $papirManuellOppgave") - - val nasjonalManuellOppgaveDAO = - NasjonalManuellOppgaveDAO( - sykmeldingId = papirManuellOppgave.sykmeldingId, - journalpostId = papirManuellOppgave.papirSmRegistering.journalpostId, - fnr = papirManuellOppgave.fnr, - aktorId = papirManuellOppgave.papirSmRegistering.aktorId, - dokumentInfoId = papirManuellOppgave.papirSmRegistering.dokumentInfoId, - datoOpprettet = papirManuellOppgave.papirSmRegistering.datoOpprettet?.toLocalDateTime(), - oppgaveId = papirManuellOppgave.oppgaveid, - ferdigstilt = ferdigstilt, - papirSmRegistrering = - PapirSmRegistering( - journalpostId = papirManuellOppgave.papirSmRegistering.journalpostId, - oppgaveId = papirManuellOppgave.papirSmRegistering.oppgaveId, - fnr = papirManuellOppgave.papirSmRegistering.fnr, - aktorId = papirManuellOppgave.papirSmRegistering.aktorId, - dokumentInfoId = papirManuellOppgave.papirSmRegistering.dokumentInfoId, - datoOpprettet = papirManuellOppgave.papirSmRegistering.datoOpprettet, - sykmeldingId = papirManuellOppgave.papirSmRegistering.sykmeldingId, - syketilfelleStartDato = papirManuellOppgave.papirSmRegistering.syketilfelleStartDato, - arbeidsgiver = papirManuellOppgave.papirSmRegistering.arbeidsgiver, - medisinskVurdering = papirManuellOppgave.papirSmRegistering.medisinskVurdering, - skjermesForPasient = papirManuellOppgave.papirSmRegistering.skjermesForPasient, - perioder = papirManuellOppgave.papirSmRegistering.perioder, - prognose = papirManuellOppgave.papirSmRegistering.prognose, - utdypendeOpplysninger = papirManuellOppgave.papirSmRegistering.utdypendeOpplysninger, - tiltakNAV = papirManuellOppgave.papirSmRegistering.tiltakNAV, - tiltakArbeidsplassen = papirManuellOppgave.papirSmRegistering.tiltakArbeidsplassen, - andreTiltak = papirManuellOppgave.papirSmRegistering.andreTiltak, - meldingTilNAV = papirManuellOppgave.papirSmRegistering.meldingTilNAV, - meldingTilArbeidsgiver = papirManuellOppgave.papirSmRegistering.meldingTilArbeidsgiver, - kontaktMedPasient = papirManuellOppgave.papirSmRegistering.kontaktMedPasient, - behandletTidspunkt = papirManuellOppgave.papirSmRegistering.behandletTidspunkt, - behandler = papirManuellOppgave.papirSmRegistering.behandler, - ), - utfall = null, - ferdigstiltAv = null, - datoFerdigstilt = null, - avvisningsgrunn = null, - ) + fun mapToDao( + papirManuellOppgave: PapirManuellOppgave, + existingId: UUID?, + ferdigstilt: Boolean = false + ): NasjonalManuellOppgaveDAO { + mapper.registerModules(JavaTimeModule()) + securelog.info("Mapper til DAO: $papirManuellOppgave") + + val nasjonalManuellOppgaveDAO = + NasjonalManuellOppgaveDAO( + sykmeldingId = papirManuellOppgave.sykmeldingId, + journalpostId = papirManuellOppgave.papirSmRegistering.journalpostId, + fnr = papirManuellOppgave.fnr, + aktorId = papirManuellOppgave.papirSmRegistering.aktorId, + dokumentInfoId = papirManuellOppgave.papirSmRegistering.dokumentInfoId, + datoOpprettet = papirManuellOppgave.papirSmRegistering.datoOpprettet?.toLocalDateTime(), + oppgaveId = papirManuellOppgave.oppgaveid, + ferdigstilt = ferdigstilt, + papirSmRegistrering = + PapirSmRegistering( + journalpostId = papirManuellOppgave.papirSmRegistering.journalpostId, + oppgaveId = papirManuellOppgave.papirSmRegistering.oppgaveId, + fnr = papirManuellOppgave.papirSmRegistering.fnr, + aktorId = papirManuellOppgave.papirSmRegistering.aktorId, + dokumentInfoId = papirManuellOppgave.papirSmRegistering.dokumentInfoId, + datoOpprettet = papirManuellOppgave.papirSmRegistering.datoOpprettet, + sykmeldingId = papirManuellOppgave.papirSmRegistering.sykmeldingId, + syketilfelleStartDato = papirManuellOppgave.papirSmRegistering.syketilfelleStartDato, + arbeidsgiver = papirManuellOppgave.papirSmRegistering.arbeidsgiver, + medisinskVurdering = papirManuellOppgave.papirSmRegistering.medisinskVurdering, + skjermesForPasient = papirManuellOppgave.papirSmRegistering.skjermesForPasient, + perioder = papirManuellOppgave.papirSmRegistering.perioder, + prognose = papirManuellOppgave.papirSmRegistering.prognose, + utdypendeOpplysninger = papirManuellOppgave.papirSmRegistering.utdypendeOpplysninger, + tiltakNAV = papirManuellOppgave.papirSmRegistering.tiltakNAV, + tiltakArbeidsplassen = papirManuellOppgave.papirSmRegistering.tiltakArbeidsplassen, + andreTiltak = papirManuellOppgave.papirSmRegistering.andreTiltak, + meldingTilNAV = papirManuellOppgave.papirSmRegistering.meldingTilNAV, + meldingTilArbeidsgiver = papirManuellOppgave.papirSmRegistering.meldingTilArbeidsgiver, + kontaktMedPasient = papirManuellOppgave.papirSmRegistering.kontaktMedPasient, + behandletTidspunkt = papirManuellOppgave.papirSmRegistering.behandletTidspunkt, + behandler = papirManuellOppgave.papirSmRegistering.behandler, + ), + utfall = null, + ferdigstiltAv = null, + datoFerdigstilt = null, + avvisningsgrunn = null, + ) - if (existingId != null) { - nasjonalManuellOppgaveDAO.apply { - id = existingId + if (existingId != null) { + nasjonalManuellOppgaveDAO.apply { + id = existingId + } } - } - return nasjonalManuellOppgaveDAO -} + return nasjonalManuellOppgaveDAO + } fun mapFromDao( nasjonalManuellOppgaveDAO: NasjonalManuellOppgaveDAO @@ -307,45 +313,59 @@ fun mapToDao( } -fun ferdigstillNasjonalAvvistOppgave( - oppgave: NasjonalManuellOppgaveDAO, - navEnhet: String, - avvisningsgrunn: String?, - veilederIdent: String, -) { + fun ferdigstillNasjonalAvvistOppgave( + oppgave: NasjonalManuellOppgaveDAO, + navEnhet: String, + avvisningsgrunn: String?, + veilederIdent: String, + ) { - if (oppgave.fnr != null) { - val sykmeldt = - personService.getPerson( - id = oppgave.fnr, - callId = oppgave.sykmeldingId, + if (oppgave.fnr != null) { + val sykmeldt = + personService.getPerson( + id = oppgave.fnr, + callId = oppgave.sykmeldingId, + ) + val avvistGrunn = enumValues().find { it.name.equals(avvisningsgrunn, ignoreCase = true) } + ferdigstillingService.ferdigstillNasjonalAvvistJournalpost( + enhet = navEnhet, + oppgave = oppgave, + sykmeldt = sykmeldt, + avvisningsGrunn = avvistGrunn?.let { mapAvvisningsgrunn(it, null) }, + loggingMeta = nasjonalCommonService.getLoggingMeta(oppgave.sykmeldingId, oppgave), ) - val avvistGrunn = enumValues().find { it.name.equals(avvisningsgrunn, ignoreCase = true) } - ferdigstillingService.ferdigstillNasjonalAvvistJournalpost( - enhet = navEnhet, - oppgave = oppgave, - sykmeldt = sykmeldt, - avvisningsGrunn = avvistGrunn?.let { mapAvvisningsgrunn(it, null) }, - loggingMeta = getLoggingMeta(oppgave.sykmeldingId, oppgave), - ) - } else { - log.error("Fant ikke fnr for oppgave med id $oppgave.oppgaveId") + } else { + log.error("Fant ikke fnr for oppgave med id $oppgave.oppgaveId") + } } -} -private fun getLoggingMeta(sykmeldingId: String, oppgave: NasjonalManuellOppgaveDAO): LoggingMeta { - return LoggingMeta( - mottakId = sykmeldingId, - dokumentInfoId = oppgave.dokumentInfoId, - msgId = sykmeldingId, - sykmeldingId = sykmeldingId, - journalpostId = oppgave.journalpostId, - ) -} -} + fun ferdigstillOgSendOppgaveTilGosys(oppgaveId: String, authorization: String) { + val eksisterendeOppgave = getOppgave(oppgaveId, authorization) + + if (eksisterendeOppgave == null) { + log.warn("Fant ikke oppgave med id $oppgaveId") + throw NoOppgaveException("Fant ikke oppgave med id $oppgaveId") + } + + val sykmeldingId = eksisterendeOppgave.sykmeldingId -fun isValidOppgaveId(oppgaveId: String): Boolean { - val regex = Regex("^\\d{9}$|^[a-zA-Z0-9]{1,20}$") - return oppgaveId.matches(regex) + val loggingMeta = nasjonalCommonService.getLoggingMeta(sykmeldingId, eksisterendeOppgave) + + log.info( + "Sender nasjonal oppgave med id $oppgaveId til Gosys {}", + StructuredArguments.fields(loggingMeta) + ) + + val navIdent = nasjonalCommonService.getNavIdent().veilederIdent + gosysService.sendOppgaveTilGosys(oppgaveId, sykmeldingId, navIdent) + oppdaterOppgave(sykmeldingId, Utfall.SENDT_TIL_GOSYS.toString(), navIdent, null, null) + + log.info( + "Ferdig å sende oppgave med id $oppgaveId til Gosys {}", + StructuredArguments.fields(loggingMeta) + ) + + metricRegister.sendtTilGosysNasjonal.increment() + } } diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalSykmeldingService.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalSykmeldingService.kt index 6a0928dd..8a5e0fd3 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalSykmeldingService.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalSykmeldingService.kt @@ -47,16 +47,6 @@ class NasjonalSykmeldingService( val securelog = securelog() - private fun getLoggingMeta(sykmeldingId: String, oppgave: NasjonalManuellOppgaveDAO): LoggingMeta { - return LoggingMeta( - mottakId = sykmeldingId, - dokumentInfoId = oppgave.dokumentInfoId, - msgId = sykmeldingId, - sykmeldingId = sykmeldingId, - journalpostId = oppgave.journalpostId, - ) - } - suspend fun sendPapirsykmelding(smRegistreringManuell: SmRegistreringManuell, navEnhet: String, callId: String, oppgaveId: String, authorization: String): ResponseEntity { val oppgave = nasjonalOppgaveService.getOppgave(oppgaveId, authorization) ?: return ResponseEntity(HttpStatus.NOT_FOUND) if (oppgave.ferdigstilt) { @@ -66,7 +56,7 @@ class NasjonalSykmeldingService( val sykmeldingId = oppgave.sykmeldingId log.info("Forsøker å ferdigstille papirsykmelding med sykmeldingId $sykmeldingId") - val loggingMeta = getLoggingMeta(sykmeldingId, oppgave) + val loggingMeta = nasjonalCommonService.getLoggingMeta(sykmeldingId, oppgave) val sykmelder = getSykmelder(smRegistreringManuell, loggingMeta, callId) val receivedSykmelding = nasjonalCommonService.createReceivedSykmelding(sykmeldingId, oppgave, loggingMeta, smRegistreringManuell, callId, sykmelder) diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/api/NasjonalOppgaveController.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/api/NasjonalOppgaveController.kt index b6200f9b..b8cf88b4 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/api/NasjonalOppgaveController.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/api/NasjonalOppgaveController.kt @@ -42,7 +42,7 @@ class NasjonalOppgaveController( val securelog = securelog() @PostMapping("/oppgave/{oppgaveId}/avvis") - @PreAuthorize("@oppgaveSecurityService.hasAccessToNasjonalOppgave(#oppgaveId, #authorization)") + @PreAuthorize("@oppgaveSecurityService.hasAccessToNasjonalOppgave(#oppgaveId, #authorization, '/oppgave/{oppgaveId}/avvis')") @WithSpan fun avvisOppgave( @PathVariable oppgaveId: String, @@ -55,7 +55,7 @@ class NasjonalOppgaveController( } @GetMapping("/oppgave/{oppgaveId}") - @PostAuthorize("@oppgaveSecurityService.hasAccessToNasjonalOppgave(#oppgaveId, #authorization)") + @PostAuthorize("@oppgaveSecurityService.hasAccessToNasjonalOppgave(#oppgaveId, #authorization, '/oppgave/{oppgaveId}')") @ResponseBody @WithSpan fun getPapirsykmeldingManuellOppgave( @@ -107,7 +107,7 @@ class NasjonalOppgaveController( } @PostMapping("/oppgave/{oppgaveId}/send") - @PreAuthorize("@oppgaveSecurityService.hasAccessToNasjonalOppgave(#oppgaveId, #authorization)") + @PreAuthorize("@oppgaveSecurityService.hasAccessToNasjonalOppgave(#oppgaveId, #authorization, '/oppgave/{oppgaveId}/send')") @ResponseBody @WithSpan suspend fun sendOppgave( @@ -122,7 +122,7 @@ class NasjonalOppgaveController( } @GetMapping("/sykmelding/{sykmeldingId}/ferdigstilt") - @PostAuthorize("@oppgaveSecurityService.hasAccessToNasjonalSykmelding(#sykmeldingId, #authorization)") + @PostAuthorize("@oppgaveSecurityService.hasAccessToNasjonalSykmelding(#sykmeldingId, #authorization, '/sykmelding/{sykmeldingId}/ferdigstilt')") @ResponseBody @WithSpan fun getFerdigstiltSykmelding( @@ -140,18 +140,24 @@ class NasjonalOppgaveController( return ResponseEntity.notFound().build() } - @PostMapping("/oppgave/{oppgaveId}/tilgosys") + @PreAuthorize("@oppgaveSecurityService.hasAccessToNasjonalOppgave(#oppgaveId, #authorization, '/oppgave/{oppgaveId}/tilgosys')") + @WithSpan fun sendOppgaveTilGosys( @PathVariable oppgaveId: String, @RequestHeader("Authorization") authorization: String, ): ResponseEntity { - log.info("papirsykmelding: Sender oppgave med id $oppgaveId til Gosys gjennom syk-dig proxy") - return smregistreringClient.postOppgaveTilGosysRequest(authorization, oppgaveId) + if (oppgaveId.isBlank()) { + log.info("oppgaveId mangler for å kunne sende oppgave til Gosys") + return ResponseEntity.badRequest().build() + } + log.info("papirsykmelding: Sender oppgave med id $oppgaveId til Gosys") + nasjonalOppgaveService.ferdigstillOgSendOppgaveTilGosys(oppgaveId, authorization) + return ResponseEntity.noContent().build() } @PostMapping("/sykmelding/{sykmeldingId}") - @PreAuthorize("@oppgaveSecurityService.hasAccessToNasjonalSykmelding(#sykmeldingId, #authorization)") + @PreAuthorize("@oppgaveSecurityService.hasAccessToNasjonalSykmelding(#sykmeldingId, #authorization, '/sykmelding/{sykmeldingId}')") @WithSpan fun korrigerSykmelding( @PathVariable sykmeldingId: String, diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/api/SmregistreringClient.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/api/SmregistreringClient.kt index cdfc29fe..53436641 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/api/SmregistreringClient.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/api/SmregistreringClient.kt @@ -4,7 +4,6 @@ import no.nav.sykdig.applog import no.nav.sykdig.digitalisering.papirsykmelding.api.model.AvvisSykmeldingRequest import no.nav.sykdig.digitalisering.papirsykmelding.api.model.PapirManuellOppgave import no.nav.sykdig.digitalisering.papirsykmelding.api.model.SmRegistreringManuell -import no.nav.sykdig.digitalisering.papirsykmelding.api.model.Sykmelder import no.nav.sykdig.digitalisering.papirsykmelding.isValidOppgaveId import org.springframework.beans.factory.annotation.Value import org.springframework.http.HttpEntity @@ -78,28 +77,6 @@ class SmregistreringClient( return res } - @Retryable - fun getSykmelderRequest( - authorization: String, - hprNummer: String, - ): ResponseEntity { - val headers = HttpHeaders() - headers.contentType = MediaType.APPLICATION_JSON - headers.setBearerAuth(removeBearerPrefix(authorization)) - - val uri = - UriComponentsBuilder.fromHttpUrl("$url/api/v1/sykmelder/{hprNummer}") - .buildAndExpand(hprNummer) - .toUri() - - return smregisteringRestTemplate.exchange( - uri, - HttpMethod.GET, - HttpEntity(headers), - Sykmelder::class.java, - ) - } - @Retryable fun postSendOppgaveRequest( authorization: String, @@ -148,30 +125,6 @@ class SmregistreringClient( ) } - @Retryable - fun postOppgaveTilGosysRequest( - authorization: String, - oppgaveId: String, - ): ResponseEntity { - val headers = HttpHeaders() - headers.contentType = MediaType.APPLICATION_JSON - headers.setBearerAuth(removeBearerPrefix(authorization)) - val uri = - UriComponentsBuilder.fromHttpUrl("$url/api/v1/oppgave/{oppgaveId}/tilgosys") - .buildAndExpand(oppgaveId) - .toUri() - - val res = - smregisteringRestTemplate.exchange( - uri, - HttpMethod.POST, - HttpEntity(null, headers), - HttpStatusCode::class.java, - ) - log.info("Oppgave $oppgaveId sendt til Gosys med responskode ${res.statusCode}") - return res - } - @Retryable fun postKorrigerSykmeldingRequest( authorization: String, diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/db/NasjonalOppgaveRepository.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/db/NasjonalOppgaveRepository.kt index b693f727..df63e62e 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/db/NasjonalOppgaveRepository.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/db/NasjonalOppgaveRepository.kt @@ -2,16 +2,13 @@ package no.nav.sykdig.digitalisering.papirsykmelding.db import no.nav.sykdig.digitalisering.papirsykmelding.db.model.NasjonalManuellOppgaveDAO import org.springframework.data.repository.CrudRepository -import org.springframework.data.repository.kotlin.CoroutineCrudRepository import org.springframework.stereotype.Repository import org.springframework.transaction.annotation.Transactional -import java.util.Optional -import java.util.UUID +import java.util.* @Transactional @Repository interface NasjonalOppgaveRepository : CrudRepository { fun findBySykmeldingId(sykmeldingId: String): NasjonalManuellOppgaveDAO? fun findByOppgaveId(oppgaveId: Int): NasjonalManuellOppgaveDAO? - fun findByOppgaveIdAndFerdigstiltIsFalse(oppgaveId: Int): NasjonalManuellOppgaveDAO? } diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/db/model/NasjonalManuellOppgaveDAO.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/db/model/NasjonalManuellOppgaveDAO.kt index da0a0dd0..945cb884 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/db/model/NasjonalManuellOppgaveDAO.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/db/model/NasjonalManuellOppgaveDAO.kt @@ -1,22 +1,12 @@ package no.nav.sykdig.digitalisering.papirsykmelding.db.model -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import jakarta.persistence.GeneratedValue import no.nav.sykdig.digitalisering.papirsykmelding.api.model.PapirSmRegistering -import no.nav.sykdig.objectMapper -import org.postgresql.util.PGobject -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.core.convert.converter.Converter import org.springframework.data.annotation.Id -import org.springframework.data.convert.ReadingConverter -import org.springframework.data.convert.WritingConverter -import org.springframework.data.jdbc.core.convert.JdbcCustomConversions import org.springframework.data.relational.core.mapping.Column import org.springframework.data.relational.core.mapping.Table import java.time.LocalDateTime -import java.util.UUID +import java.util.* @Table(name = "nasjonal_manuelloppgave") data class NasjonalManuellOppgaveDAO( diff --git a/src/main/kotlin/no/nav/sykdig/digitalisering/tilgangskontroll/OppgaveSecurityService.kt b/src/main/kotlin/no/nav/sykdig/digitalisering/tilgangskontroll/OppgaveSecurityService.kt index ff9488b5..d2be3a37 100644 --- a/src/main/kotlin/no/nav/sykdig/digitalisering/tilgangskontroll/OppgaveSecurityService.kt +++ b/src/main/kotlin/no/nav/sykdig/digitalisering/tilgangskontroll/OppgaveSecurityService.kt @@ -38,20 +38,34 @@ class OppgaveSecurityService( return tilgang } - fun hasAccessToNasjonalOppgave(oppgaveId: String, authorization: String): Boolean { + fun hasAccessToNasjonalOppgave(oppgaveId: String, authorization: String, requestPath: String): Boolean { securelog.info("sjekker om bruker har tilgang på oppgave $oppgaveId") + val oppgave = nasjonalOppgaveService.getOppgave(oppgaveId, authorization) val navEmail = nasjonalCommonService.getNavEmail() val fnr = oppgave?.fnr if (oppgave != null && fnr != null) { val tilgang = hasAccess(fnr, navEmail) securelog.info("Innlogget bruker: $navEmail har${if (!tilgang) " ikke" else ""} tilgang til oppgave med id $oppgaveId") + auditlog.info( + AuditLogger().createcCefMessage( + fnr = fnr, + navEmail = navEmail, + operation = AuditLogger.Operation.READ, + requestPath = requestPath, + permit = + when (tilgang) { + true -> AuditLogger.Permit.PERMIT + false -> AuditLogger.Permit.DENY + }, + ), + ) return tilgang } return false } - fun hasAccessToNasjonalSykmelding(sykmeldingId: String, authorization: String): Boolean { + fun hasAccessToNasjonalSykmelding(sykmeldingId: String, authorization: String, requestPath: String): Boolean { securelog.info("sjekker om bruker har tilgang på sykmelding $sykmeldingId") val oppgave = nasjonalOppgaveService.findBySykmeldingId(sykmeldingId) val navEmail = nasjonalCommonService.getNavEmail() @@ -59,6 +73,19 @@ class OppgaveSecurityService( if (oppgave != null && fnr != null) { val tilgang = hasAccess(fnr, navEmail) securelog.info("Innlogget bruker: $navEmail har${if (!tilgang) " ikke" else ""} tilgang til oppgave med id $sykmeldingId") + auditlog.info( + AuditLogger().createcCefMessage( + fnr = fnr, + navEmail = navEmail, + operation = AuditLogger.Operation.READ, + requestPath = requestPath, + permit = + when (tilgang) { + true -> AuditLogger.Permit.PERMIT + false -> AuditLogger.Permit.DENY + }, + ), + ) return tilgang } return false diff --git a/src/main/kotlin/no/nav/sykdig/metrics/MetricRegister.kt b/src/main/kotlin/no/nav/sykdig/metrics/MetricRegister.kt index 0d72c674..623d27a2 100644 --- a/src/main/kotlin/no/nav/sykdig/metrics/MetricRegister.kt +++ b/src/main/kotlin/no/nav/sykdig/metrics/MetricRegister.kt @@ -27,6 +27,11 @@ class MetricRegister(private val registry: MeterRegistry) { "${METRICS_NS}_sendt_til_gosys_counter", ) + val sendtTilGosysNasjonal = + registry.counter( + "${METRICS_NS}_sendt_til_gosys_nasjonal_counter", + ) + val avvistSendtTilGosys = registry.counter( "${METRICS_NS}_avvist_sendt_til_gosys_counter", diff --git a/src/test/kotlin/no/nav/sykdig/digitalisering/OppgaveDataFetcherTest.kt b/src/test/kotlin/no/nav/sykdig/digitalisering/OppgaveDataFetcherTest.kt index 07858de0..55b8288d 100644 --- a/src/test/kotlin/no/nav/sykdig/digitalisering/OppgaveDataFetcherTest.kt +++ b/src/test/kotlin/no/nav/sykdig/digitalisering/OppgaveDataFetcherTest.kt @@ -37,7 +37,7 @@ import org.springframework.security.core.context.SecurityContext import org.springframework.security.core.context.SecurityContextHolder import java.time.LocalDate import java.time.OffsetDateTime -import java.util.UUID +import java.util.* @SpringBootTest( classes = [ diff --git a/src/test/kotlin/no/nav/sykdig/digitalisering/ferdigstilling/FerdigstillingServiceTest.kt b/src/test/kotlin/no/nav/sykdig/digitalisering/ferdigstilling/FerdigstillingServiceTest.kt index f5dee95b..b3672c23 100644 --- a/src/test/kotlin/no/nav/sykdig/digitalisering/ferdigstilling/FerdigstillingServiceTest.kt +++ b/src/test/kotlin/no/nav/sykdig/digitalisering/ferdigstilling/FerdigstillingServiceTest.kt @@ -5,9 +5,19 @@ import no.nav.sykdig.SykDigBackendApplication import no.nav.sykdig.digitalisering.createDigitalseringsoppgaveDbModel import no.nav.sykdig.digitalisering.dokarkiv.DokarkivClient import no.nav.sykdig.digitalisering.dokument.DocumentService +import no.nav.sykdig.digitalisering.felles.AktivitetIkkeMulig +import no.nav.sykdig.digitalisering.felles.AvsenderSystem +import no.nav.sykdig.digitalisering.felles.Diagnose +import no.nav.sykdig.digitalisering.felles.KontaktMedPasient +import no.nav.sykdig.digitalisering.felles.Periode +import no.nav.sykdig.digitalisering.felles.SporsmalSvar import no.nav.sykdig.digitalisering.ferdigstilling.mapping.mapToReceivedSykmelding import no.nav.sykdig.digitalisering.ferdigstilling.oppgave.OppgaveClient +import no.nav.sykdig.digitalisering.helsenett.SykmelderService import no.nav.sykdig.digitalisering.model.FerdistilltRegisterOppgaveValues +import no.nav.sykdig.digitalisering.papirsykmelding.api.model.PapirSmRegistering +import no.nav.sykdig.digitalisering.papirsykmelding.db.model.NasjonalManuellOppgaveDAO +import no.nav.sykdig.digitalisering.papirsykmelding.db.model.Utfall import no.nav.sykdig.digitalisering.pdl.Bostedsadresse import no.nav.sykdig.digitalisering.pdl.Navn import no.nav.sykdig.digitalisering.pdl.Person @@ -19,14 +29,7 @@ import no.nav.sykdig.digitalisering.saf.graphql.Journalstatus import no.nav.sykdig.digitalisering.saf.graphql.SafJournalpost import no.nav.sykdig.digitalisering.saf.graphql.SafQueryJournalpost import no.nav.sykdig.digitalisering.saf.graphql.TEMA_SYKMELDING -import no.nav.sykdig.digitalisering.felles.AktivitetIkkeMulig -import no.nav.sykdig.digitalisering.felles.AvsenderSystem -import no.nav.sykdig.digitalisering.felles.Diagnose -import no.nav.sykdig.digitalisering.felles.KontaktMedPasient -import no.nav.sykdig.digitalisering.felles.Periode import no.nav.sykdig.digitalisering.sykmelding.ReceivedSykmelding -import no.nav.sykdig.digitalisering.felles.SporsmalSvar -import no.nav.sykdig.digitalisering.helsenett.SykmelderService import no.nav.sykdig.generated.types.DiagnoseInput import no.nav.sykdig.generated.types.PeriodeInput import no.nav.sykdig.generated.types.PeriodeType @@ -44,10 +47,11 @@ import org.springframework.boot.test.autoconfigure.actuate.observability.AutoCon import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.mock.mockito.MockBean import java.time.LocalDate +import java.time.LocalDateTime import java.time.Month import java.time.OffsetDateTime import java.time.ZoneOffset -import java.util.UUID +import java.util.* @TestInstance(TestInstance.Lifecycle.PER_CLASS) @AutoConfigureObservability @@ -75,8 +79,9 @@ class FerdigstillingServiceTest : IntegrationTest() { @BeforeEach fun setup() { - ferdigstillingService = - FerdigstillingService(safJournalpostGraphQlClient, dokarkivClient, oppgaveClient, sykmeldingOKProducer, dokumentService, sykmelderService) + ferdigstillingService = FerdigstillingService(safJournalpostGraphQlClient, dokarkivClient, oppgaveClient, sykmeldingOKProducer, dokumentService, sykmelderService) + nasjonalOppgaveRepository.deleteAll() + } @Test @@ -416,4 +421,73 @@ class FerdigstillingServiceTest : IntegrationTest() { } assertEquals(exception.message, "Gradert sykmelding må ha grad") } + + @Test + fun `ferdigstill oppgave gosys`() { + val oppgaveId = 444 + nasjonalOppgaveRepository.save(nasjonalOppgave(null, oppgaveId)) + val oppgave = nasjonalOppgaveRepository.findByOppgaveId(oppgaveId) + + requireNotNull(oppgave) + val updatedOppgave = oppgave.copy( + utfall = Utfall.SENDT_TIL_GOSYS.toString(), + ferdigstilt = true, + ferdigstiltAv = "nav-ident@mail.no" + ) + + + val ferdigstiltOppgave = nasjonalOppgaveRepository.save(updatedOppgave) + + requireNotNull(ferdigstiltOppgave) + assertEquals(ferdigstiltOppgave.oppgaveId, 444) + assertEquals(ferdigstiltOppgave.utfall, Utfall.SENDT_TIL_GOSYS.toString()) + assertEquals(ferdigstiltOppgave.ferdigstilt, true) + assertEquals(ferdigstiltOppgave.ferdigstiltAv, "nav-ident@mail.no") + } + + fun nasjonalOppgave( + id: UUID?, + oppgaveId: Int, + ): NasjonalManuellOppgaveDAO { + return NasjonalManuellOppgaveDAO( + id = id, + sykmeldingId = "987", + journalpostId = "123", + fnr = "fnr", + aktorId = "aktor", + dokumentInfoId = "123", + datoOpprettet = LocalDateTime.now(), + oppgaveId = oppgaveId, + ferdigstilt = false, + papirSmRegistrering = + PapirSmRegistering( + journalpostId = "123", + oppgaveId = "123", + fnr = "fnr", + aktorId = "aktor", + dokumentInfoId = "123", + datoOpprettet = OffsetDateTime.now(), + sykmeldingId = "123", + syketilfelleStartDato = LocalDate.now(), + arbeidsgiver = null, + medisinskVurdering = null, + skjermesForPasient = null, + perioder = null, + prognose = null, + utdypendeOpplysninger = null, + tiltakNAV = null, + tiltakArbeidsplassen = null, + andreTiltak = null, + meldingTilNAV = null, + meldingTilArbeidsgiver = null, + kontaktMedPasient = null, + behandletTidspunkt = null, + behandler = null, + ), + utfall = null, + ferdigstiltAv = null, + datoFerdigstilt = null, + avvisningsgrunn = null, + ) + } } diff --git a/src/test/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalOppgaveServiceTest.kt b/src/test/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalOppgaveServiceTest.kt index 2200542b..fa6df95d 100644 --- a/src/test/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalOppgaveServiceTest.kt +++ b/src/test/kotlin/no/nav/sykdig/digitalisering/papirsykmelding/NasjonalOppgaveServiceTest.kt @@ -3,6 +3,7 @@ package no.nav.sykdig.digitalisering.papirsykmelding import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import kotlinx.coroutines.runBlocking import no.nav.sykdig.IntegrationTest +import no.nav.sykdig.LoggingMeta import no.nav.sykdig.digitalisering.SykDigOppgaveService import no.nav.sykdig.digitalisering.dokarkiv.DokarkivClient import no.nav.sykdig.digitalisering.dokument.DocumentService @@ -130,6 +131,7 @@ class NasjonalOppgaveServiceTest : IntegrationTest() { Mockito.`when`(sykmelderService.getSykmelder(org.mockito.kotlin.any(), org.mockito.kotlin.any())).thenReturn(testDataSykmelder()) Mockito.doNothing().`when`(oppgaveClient).ferdigstillOppgave(org.mockito.kotlin.any(), org.mockito.kotlin.any()) Mockito.doNothing().`when`(documentService).updateDocumentTitle(org.mockito.kotlin.any(), org.mockito.kotlin.any(), org.mockito.kotlin.any()) + Mockito.`when`(nasjonaCommonService.getLoggingMeta(org.mockito.kotlin.any(), org.mockito.kotlin.any())).thenReturn(testDataLoggingMeta()) assertTrue(originalOppgave.avvisningsgrunn == null) val avvistOppgave = nasjonalOppgaveService.avvisOppgave(oppgaveId, request, "enhet", "auth") @@ -307,4 +309,14 @@ class NasjonalOppgaveServiceTest : IntegrationTest() { SecurityContextHolder.setContext(securityContext) ReactiveSecurityContextHolder.withSecurityContext(Mono.just(securityContext)) } + + fun testDataLoggingMeta(): LoggingMeta { + return LoggingMeta( + mottakId = "mottakId", + journalpostId = "journalpostId", + dokumentInfoId = "dokumentInfoId", + msgId = "msgId", + sykmeldingId = "sykmeldingId", + ) + } }