From 61df36c0ec1a71f5e97ab3d851529e1ff60bf1b8 Mon Sep 17 00:00:00 2001 From: Mikael Bjerga <6940327+bjerga@users.noreply.github.com> Date: Fri, 26 Jul 2024 08:34:40 +0200 Subject: [PATCH] =?UTF-8?q?Nytt=20skjema:=20Bruk=20orgnr=20og=20fnr=20fra?= =?UTF-8?q?=20foresp=C3=B8rsel=20(#634)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/innsending/InnsendingRoute.kt | 26 +++++-- .../innsending/InnsendingService.kt | 74 ++++++++++--------- .../integrasjonstest/InnsendingIT.kt | 8 +- .../integrasjonstest/InnsendingServiceIT.kt | 3 - 4 files changed, 61 insertions(+), 50 deletions(-) diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt index 7dcfc7a54..0751dcad2 100644 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt +++ b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt @@ -26,6 +26,7 @@ import no.nav.helsearbeidsgiver.inntektsmelding.api.auth.lesFnrFraAuthToken import no.nav.helsearbeidsgiver.inntektsmelding.api.logger import no.nav.helsearbeidsgiver.inntektsmelding.api.response.JsonErrorResponse import no.nav.helsearbeidsgiver.inntektsmelding.api.response.RedisTimeoutResponse +import no.nav.helsearbeidsgiver.inntektsmelding.api.response.ValideringErrorResponse import no.nav.helsearbeidsgiver.inntektsmelding.api.sikkerLogger import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respond import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondBadRequest @@ -76,18 +77,31 @@ fun Route.innsendingRoute( } }.let { json -> runCatching { - json.fromJson(SkjemaInntektsmelding.serializer()).convert( - sykmeldingsperioder = emptyList(), - aarsakInnsending = AarsakInnsending.Ny, - ) + json + .fromJson(SkjemaInntektsmelding.serializer()) + .also { + val valideringsfeil = it.valider() + if (valideringsfeil.isNotEmpty()) { + val response = ValideringErrorResponse(valideringsfeil) + + respondBadRequest(response, ValideringErrorResponse.serializer()) + return@measureTimeMillis + } + }.convert( + sykmeldingsperioder = emptyList(), + aarsakInnsending = AarsakInnsending.Ny, + ) }.getOrElse { - json.fromJson(Innsending.serializer()) + json + .fromJson(Innsending.serializer()) + .also { + it.validate() + } } } tilgangskontroll.validerTilgangTilForespoersel(call.request, forespoerselId) - request.validate() val innloggerFnr = call.request.lesFnrFraAuthToken() producer.publish(transaksjonId, forespoerselId, request, innloggerFnr) diff --git a/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/InnsendingService.kt b/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/InnsendingService.kt index 64cb2b9a0..fae1ac68b 100644 --- a/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/InnsendingService.kt +++ b/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/InnsendingService.kt @@ -22,7 +22,7 @@ import no.nav.helsearbeidsgiver.felles.rapidsrivers.model.Fail import no.nav.helsearbeidsgiver.felles.rapidsrivers.publish import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisKey import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore -import no.nav.helsearbeidsgiver.felles.rapidsrivers.service.ServiceMed2Steg +import no.nav.helsearbeidsgiver.felles.rapidsrivers.service.ServiceMed3Steg import no.nav.helsearbeidsgiver.felles.utils.Log import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer @@ -32,31 +32,31 @@ import no.nav.helsearbeidsgiver.utils.log.MdcUtils import no.nav.helsearbeidsgiver.utils.log.logger import no.nav.helsearbeidsgiver.utils.log.sikkerLogger import no.nav.helsearbeidsgiver.utils.wrapper.Fnr -import no.nav.helsearbeidsgiver.utils.wrapper.Orgnr import java.util.UUID data class Steg0( val transaksjonId: UUID, val forespoerselId: UUID, - val orgnr: Orgnr, - val sykmeldtFnr: Fnr, val avsenderFnr: Fnr, val skjema: JsonElement, ) -sealed class Steg1 { +data class Steg1( + val forespoersel: Forespoersel, +) + +sealed class Steg2 { data class Komplett( - val forespoersel: Forespoersel, val aarsakInnsending: AarsakInnsending, val orgNavn: String, val sykmeldt: PersonDato, val avsender: PersonDato, - ) : Steg1() + ) : Steg2() - data object Delvis : Steg1() + data object Delvis : Steg2() } -data class Steg2( +data class Steg3( val inntektsmelding: Inntektsmelding, val erDuplikat: Boolean, ) @@ -64,7 +64,7 @@ data class Steg2( class InnsendingService( private val rapid: RapidsConnection, override val redisStore: RedisStore, -) : ServiceMed2Steg() { +) : ServiceMed3Steg() { override val logger = logger() override val sikkerLogger = sikkerLogger() @@ -72,8 +72,6 @@ class InnsendingService( override val startKeys = setOf( Key.FORESPOERSEL_ID, - Key.ORGNRUNDERENHET, - Key.IDENTITETSNUMMER, Key.ARBEIDSGIVER_ID, Key.SKJEMA_INNTEKTSMELDING, ) @@ -93,21 +91,23 @@ class InnsendingService( Steg0( transaksjonId = Key.UUID.les(UuidSerializer, melding), forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding), - orgnr = Key.ORGNRUNDERENHET.les(Orgnr.serializer(), melding), - sykmeldtFnr = Key.IDENTITETSNUMMER.les(Fnr.serializer(), melding), avsenderFnr = Key.ARBEIDSGIVER_ID.les(Fnr.serializer(), melding), skjema = Key.SKJEMA_INNTEKTSMELDING.les(JsonElement.serializer(), melding), ) - override fun lesSteg1(melding: Map): Steg1 { - val forespoersel = runCatching { Key.FORESPOERSEL_SVAR.les(Forespoersel.serializer(), melding) } + override fun lesSteg1(melding: Map): Steg1 = + Steg1( + forespoersel = Key.FORESPOERSEL_SVAR.les(Forespoersel.serializer(), melding), + ) + + override fun lesSteg2(melding: Map): Steg2 { val tidligereInntektsmelding = runCatching { Key.LAGRET_INNTEKTSMELDING.les(ResultJson.serializer(), melding) } val tidligereEksternInntektsmelding = runCatching { Key.EKSTERN_INNTEKTSMELDING.les(ResultJson.serializer(), melding) } val orgNavn = runCatching { Key.VIRKSOMHET.les(String.serializer(), melding) } val sykmeldt = runCatching { Key.ARBEIDSTAKER_INFORMASJON.les(PersonDato.serializer(), melding) } val avsender = runCatching { Key.ARBEIDSGIVER_INFORMASJON.les(PersonDato.serializer(), melding) } - val results = listOf(forespoersel, tidligereInntektsmelding, tidligereEksternInntektsmelding, orgNavn, sykmeldt, avsender) + val results = listOf(tidligereInntektsmelding, tidligereEksternInntektsmelding, orgNavn, sykmeldt, avsender) return if (results.all { it.isSuccess }) { val aarsakInnsending = @@ -117,22 +117,21 @@ class InnsendingService( AarsakInnsending.Endring } - Steg1.Komplett( - forespoersel = forespoersel.getOrThrow(), + Steg2.Komplett( aarsakInnsending = aarsakInnsending, orgNavn = orgNavn.getOrThrow(), sykmeldt = sykmeldt.getOrThrow(), avsender = avsender.getOrThrow(), ) } else if (results.any { it.isSuccess }) { - Steg1.Delvis + Steg2.Delvis } else { throw results.firstNotNullOf { it.exceptionOrNull() } } } - override fun lesSteg2(melding: Map): Steg2 = - Steg2( + override fun lesSteg3(melding: Map): Steg3 = + Steg3( inntektsmelding = Key.INNTEKTSMELDING_DOKUMENT.les(Inntektsmelding.serializer(), melding), erDuplikat = Key.ER_DUPLIKAT_IM.les(Boolean.serializer(), melding), ) @@ -145,7 +144,12 @@ class InnsendingService( Key.UUID to steg0.transaksjonId.toJson(), Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), ).also { loggBehovPublisert(BehovType.HENT_TRENGER_IM, it) } + } + override fun utfoerSteg1( + steg0: Steg0, + steg1: Steg1, + ) { rapid .publish( Key.EVENT_NAME to eventName.toJson(), @@ -163,7 +167,7 @@ class InnsendingService( Key.BEHOV to BehovType.VIRKSOMHET.toJson(), Key.UUID to steg0.transaksjonId.toJson(), Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), - Key.ORGNRUNDERENHET to steg0.orgnr.toJson(), + Key.ORGNRUNDERENHET to steg1.forespoersel.orgnr.toJson(), ).also { loggBehovPublisert(BehovType.VIRKSOMHET, it) } rapid @@ -172,23 +176,24 @@ class InnsendingService( Key.BEHOV to BehovType.FULLT_NAVN.toJson(), Key.UUID to steg0.transaksjonId.toJson(), Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), - Key.IDENTITETSNUMMER to steg0.sykmeldtFnr.toJson(), + Key.IDENTITETSNUMMER to steg1.forespoersel.fnr.toJson(), Key.ARBEIDSGIVER_ID to steg0.avsenderFnr.toJson(), ).also { loggBehovPublisert(BehovType.FULLT_NAVN, it) } } - override fun utfoerSteg1( + override fun utfoerSteg2( steg0: Steg0, steg1: Steg1, + steg2: Steg2, ) { - if (steg1 is Steg1.Komplett) { + if (steg2 is Steg2.Komplett) { val skjema = runCatching { steg0.skjema .fromJson(SkjemaInntektsmelding.serializer()) .convert( sykmeldingsperioder = steg1.forespoersel.sykmeldingsperioder, - aarsakInnsending = steg1.aarsakInnsending, + aarsakInnsending = steg2.aarsakInnsending, ) }.getOrElse { steg0.skjema.fromJson(Innsending.serializer()) @@ -198,9 +203,9 @@ class InnsendingService( mapInntektsmelding( forespoersel = steg1.forespoersel, skjema = skjema, - fulltnavnArbeidstaker = steg1.sykmeldt.navn, - virksomhetNavn = steg1.orgNavn, - innsenderNavn = steg1.avsender.navn, + fulltnavnArbeidstaker = steg2.sykmeldt.navn, + virksomhetNavn = steg2.orgNavn, + innsenderNavn = steg2.avsender.navn, ) if (inntektsmelding.bestemmendeFraværsdag.isBefore(inntektsmelding.inntektsdato)) { @@ -221,25 +226,26 @@ class InnsendingService( } } - override fun utfoerSteg2( + override fun utfoerSteg3( steg0: Steg0, steg1: Steg1, steg2: Steg2, + steg3: Steg3, ) { val resultJson = ResultJson( - success = steg2.inntektsmelding.toJson(Inntektsmelding.serializer()), + success = steg3.inntektsmelding.toJson(Inntektsmelding.serializer()), ).toJson(ResultJson.serializer()) redisStore.set(RedisKey.of(steg0.transaksjonId), resultJson) - if (!steg2.erDuplikat) { + if (!steg3.erDuplikat) { val publisert = rapid.publish( Key.EVENT_NAME to EventName.INNTEKTSMELDING_MOTTATT.toJson(), Key.UUID to steg0.transaksjonId.toJson(), Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), - Key.INNTEKTSMELDING_DOKUMENT to steg2.inntektsmelding.toJson(Inntektsmelding.serializer()), + Key.INNTEKTSMELDING_DOKUMENT to steg3.inntektsmelding.toJson(Inntektsmelding.serializer()), ) MdcUtils.withLogFields( diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt index 71dd90549..547806ebe 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt @@ -28,8 +28,6 @@ import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.maxMekker import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer import no.nav.helsearbeidsgiver.utils.json.toJson -import no.nav.helsearbeidsgiver.utils.test.wrapper.genererGyldig -import no.nav.helsearbeidsgiver.utils.wrapper.Fnr import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance @@ -72,8 +70,6 @@ class InnsendingIT : EndToEndTest() { Key.UUID to transaksjonId.toJson(), Key.DATA to "".toJson(), Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), - Key.ORGNRUNDERENHET to Mock.skjema.orgnrUnderenhet.toJson(), - Key.IDENTITETSNUMMER to Mock.skjema.identitetsnummer.toJson(), Key.ARBEIDSGIVER_ID to Mock.skjema.identitetsnummer.toJson(), Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(Innsending.serializer()), ) @@ -169,8 +165,6 @@ class InnsendingIT : EndToEndTest() { Key.UUID to transaksjonId.toJson(), Key.DATA to "".toJson(), Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), - Key.ORGNRUNDERENHET to Mock.skjema.orgnrUnderenhet.toJson(), - Key.IDENTITETSNUMMER to bjarneBetjent.ident!!.toJson(), Key.ARBEIDSGIVER_ID to maxMekker.ident!!.toJson(), Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(Innsending.serializer()), ) @@ -249,7 +243,7 @@ class InnsendingIT : EndToEndTest() { const val OPPGAVE_ID = "neglisjert-sommer" val forespoerselId: UUID = UUID.randomUUID() - val skjema = mockInnsending().copy(identitetsnummer = Fnr.genererGyldig().verdi) + val skjema = mockInnsending().copy(identitetsnummer = bjarneBetjent.ident!!) private val forespoersel = skjema.tilForespoersel(UUID.randomUUID()) diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt index e0cad062e..e3cf9cc54 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt @@ -70,8 +70,6 @@ class InnsendingServiceIT : EndToEndTest() { Key.UUID to transaksjonId.toJson(), Key.DATA to "".toJson(), Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), - Key.ORGNRUNDERENHET to Mock.orgnr.toJson(), - Key.IDENTITETSNUMMER to Mock.fnr.toJson(), Key.ARBEIDSGIVER_ID to Mock.fnrAg.toJson(), Key.SKJEMA_INNTEKTSMELDING to gyldigInnsendingRequest.toJson(Innsending.serializer()), ) @@ -216,7 +214,6 @@ class InnsendingServiceIT : EndToEndTest() { const val OPPGAVE_ID = "kunstig-demon" val orgnr = Orgnr.genererGyldig() - val fnr = Fnr.genererGyldig() val fnrAg = Fnr.genererGyldig() val forespoerselId: UUID = UUID.randomUUID() val vedtaksperiodeId: UUID = UUID.randomUUID()