From a38d7715fe306eadfa9faff97e9e705a54a8f650 Mon Sep 17 00:00:00 2001 From: Ramin Esfandiari Date: Fri, 27 Sep 2024 07:39:50 +0200 Subject: [PATCH] Tilrettelegger for kopiering av journalpost for ytelser uten barn (#1239) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * WIP Støtte for å kopiere journalpost * Testjobb * Fikser kopiering av journalpost * Refaktorerer ut krav for kopiering. * Fjerner ubrukt felt. * Fjerner rapid og ubrukte klasser. * Fikser circular reference. * Lagrer journalpostkopi gjennom hendelseMottaker. * Etterspørr datoOpprettet ved kall mot SAF. * Legger på TODO... * Fjerner konsumering fra punsjbolle topic. * Fikser feilhåndtering ved kopiering av journalpost. * Rydder opp kode * Bruker enum for string verdier. * Fjerner ubrukt variabel. * Bruker enum for string verdier. * Forenkler logikk. * Returnerer mer detaljert respons ved kopiering av JP. * Tilrettelegger for kopiering av JP for alle ytelser. * Lagt til støtte for å kopiere journalpost (#1117) * WIP Støtte for å kopiere journalpost * Testjobb * Fikser kopiering av journalpost * Refaktorerer ut krav for kopiering. * Fjerner ubrukt felt. * Fjerner rapid og ubrukte klasser. * Fikser circular reference. * Lagrer journalpostkopi gjennom hendelseMottaker. * Etterspørr datoOpprettet ved kall mot SAF. * Legger på TODO... * Fjerner konsumering fra punsjbolle topic. * Fikser feilhåndtering ved kopiering av journalpost. * Rydder opp kode * Bruker enum for string verdier. * Fjerner ubrukt variabel. * Bruker enum for string verdier. * Forenkler logikk. * Returnerer mer detaljert respons ved kopiering av JP. --------- Co-authored-by: Ramin Esfandiari Co-authored-by: Ramin Esfandiari * Fjerner `fra` felt i kopiering som fører forvirring. Det er kun personen vi kopierer til som er viktig. til person kan være samme person som er registrert på orginal eller en annen person som det skal kopieres til. * Sjekker null eller tom * Legger til støtte for resterende ytelser for kopiering --------- Co-authored-by: albrektsson Co-authored-by: Emil Albrektsson <61695840+albrektsson@users.noreply.github.com> --- .../integrasjoner/k9sak/K9SakServiceImpl.kt | 1 + .../k9punsj/journalpost/JournalpostRoutes.kt | 2 +- .../JournalpostkopieringService.kt | 41 ++---- .../journalpost/dto/KopierJournalpostDto.kt | 60 ++++++-- .../journalpost/dto/KopierJournalpostInfo.kt | 1 - .../journalpost/KopierJournalpostRouteTest.kt | 128 ++++++++++++++++-- 6 files changed, 180 insertions(+), 53 deletions(-) diff --git a/src/main/kotlin/no/nav/k9punsj/integrasjoner/k9sak/K9SakServiceImpl.kt b/src/main/kotlin/no/nav/k9punsj/integrasjoner/k9sak/K9SakServiceImpl.kt index 1841a5609..8c50f0882 100644 --- a/src/main/kotlin/no/nav/k9punsj/integrasjoner/k9sak/K9SakServiceImpl.kt +++ b/src/main/kotlin/no/nav/k9punsj/integrasjoner/k9sak/K9SakServiceImpl.kt @@ -52,6 +52,7 @@ import no.nav.k9punsj.omsorgspengerutbetaling.tilOmsUtvisning import no.nav.k9punsj.opplaeringspenger.tilOlpvisning import no.nav.k9punsj.pleiepengerlivetssluttfase.tilPlsvisning import no.nav.k9punsj.pleiepengersyktbarn.tilPsbvisning +import no.nav.k9punsj.utils.PeriodeUtils.somK9Periode import no.nav.k9punsj.utils.objectMapper import org.intellij.lang.annotations.Language import org.json.JSONArray diff --git a/src/main/kotlin/no/nav/k9punsj/journalpost/JournalpostRoutes.kt b/src/main/kotlin/no/nav/k9punsj/journalpost/JournalpostRoutes.kt index 8753b9a11..9625cfe0c 100644 --- a/src/main/kotlin/no/nav/k9punsj/journalpost/JournalpostRoutes.kt +++ b/src/main/kotlin/no/nav/k9punsj/journalpost/JournalpostRoutes.kt @@ -409,7 +409,7 @@ internal class JournalpostRoutes( val journalpostId = request.pathVariable("journalpost_id") val dto = request.body(BodyExtractors.toMono(KopierJournalpostDto::class.java)).awaitFirst() - val identListe = mutableListOf(dto.fra, dto.til) + val identListe = mutableListOf(dto.til) dto.barn?.let { identListe.add(it) } dto.annenPart?.let { identListe.add(it) } diff --git a/src/main/kotlin/no/nav/k9punsj/journalpost/JournalpostkopieringService.kt b/src/main/kotlin/no/nav/k9punsj/journalpost/JournalpostkopieringService.kt index 3f44971d3..8a61f9388 100644 --- a/src/main/kotlin/no/nav/k9punsj/journalpost/JournalpostkopieringService.kt +++ b/src/main/kotlin/no/nav/k9punsj/journalpost/JournalpostkopieringService.kt @@ -52,11 +52,8 @@ class JournalpostkopieringService( periodeDto = safJournalpost.datoOpprettet.toLocalDate().somPeriodeDto() ) - val saksnummer = hentEllerOpprettSaksnummer( - journalpostId = journalpostId.toString(), - kopierJournalpostDto = kopierJournalpostDto, - k9SakGrunnlag = k9SakGrunnlag - ) + val saksnummer = k9SakService.hentEllerOpprettSaksnummer(k9SakGrunnlag) + logger.info("Kopierer journalpost: $journalpostId til saksnummer: $saksnummer") val tilPersonFnr = kopierJournalpostDto.til val nyJournalpostId = dokarkivGateway.knyttTilAnnenSak( @@ -81,7 +78,6 @@ class JournalpostkopieringService( return KopierJournalpostInfo( nyJournalpostId = nyJournalpostId.toString(), saksnummer = saksnummer, - fra = kopierJournalpostDto.fra, til = tilPersonFnr, pleietrengende = kopierJournalpostDto.barn, annenPart = kopierJournalpostDto.annenPart, @@ -119,9 +115,13 @@ class JournalpostkopieringService( } ?: throw KanIkkeKopieresErrorResponse("Mangler ytelse for journalpost.") val støttedeYtelseTyperForKopiering = listOf( - FagsakYtelseType.OMSORGSPENGER_KS, FagsakYtelseType.PLEIEPENGER_SYKT_BARN, - FagsakYtelseType.PLEIEPENGER_NÆRSTÅENDE + FagsakYtelseType.PLEIEPENGER_NÆRSTÅENDE, + FagsakYtelseType.OMSORGSPENGER, + FagsakYtelseType.OMSORGSPENGER_KS, + FagsakYtelseType.OMSORGSPENGER_AO, + FagsakYtelseType.OMSORGSPENGER_MA, + FagsakYtelseType.OPPLÆRINGSPENGER ) if (!støttedeYtelseTyperForKopiering.contains(k9FagsakYtelseType)) { @@ -131,28 +131,7 @@ class JournalpostkopieringService( return Pair(safJournalpost, k9FagsakYtelseType) } - private suspend fun hentEllerOpprettSaksnummer( - journalpostId: String, - kopierJournalpostDto: KopierJournalpostDto, - k9SakGrunnlag: HentK9SaksnummerGrunnlag, - ): String { - - // Sjekker om journalposten kopieres til samme person og logger hvis så er tilfelle - if (kopierJournalpostDto.fra == kopierJournalpostDto.til) { - val saksnummer = k9SakService.hentEllerOpprettSaksnummer(k9SakGrunnlag) - logger.info("Kopierer journalpost: $journalpostId til samme person med saksnummer: $saksnummer") - return saksnummer // Bruker eksisterende saksnummer for samme person - } - - // Hvis journalposten kopieres til en annen person, Hent eller opprett nytt saksnummer - val saksnummer = k9SakService.hentEllerOpprettSaksnummer( - k9SakGrunnlag.copy(søker = kopierJournalpostDto.til) - ) - logger.info("Kopierer journalpost: $journalpostId til ny person med saksnummer: $saksnummer") - return saksnummer - } - - class KanIkkeKopieresErrorResponse(feil: String) : - ErrorResponseException(HttpStatus.CONFLICT, ProblemDetail.forStatusAndDetail(HttpStatus.CONFLICT, feil), null) + class KanIkkeKopieresErrorResponse(feil: String, status: HttpStatus = HttpStatus.CONFLICT) : + ErrorResponseException(status, ProblemDetail.forStatusAndDetail(status, feil), null) } diff --git a/src/main/kotlin/no/nav/k9punsj/journalpost/dto/KopierJournalpostDto.kt b/src/main/kotlin/no/nav/k9punsj/journalpost/dto/KopierJournalpostDto.kt index 8a14cad5a..006a3830e 100644 --- a/src/main/kotlin/no/nav/k9punsj/journalpost/dto/KopierJournalpostDto.kt +++ b/src/main/kotlin/no/nav/k9punsj/journalpost/dto/KopierJournalpostDto.kt @@ -6,25 +6,65 @@ import no.nav.k9punsj.felles.PunsjFagsakYtelseType import no.nav.k9punsj.felles.PunsjFagsakYtelseType.Companion.somPunsjFagsakYtelseType import no.nav.k9punsj.felles.dto.PeriodeDto import no.nav.k9punsj.integrasjoner.k9sak.dto.HentK9SaksnummerGrunnlag +import no.nav.k9punsj.journalpost.JournalpostkopieringService +import org.springframework.http.HttpStatus +import java.time.LocalDate data class KopierJournalpostDto( - val fra: String, val til: String, val barn: String?, val annenPart: String?, + val behandlingsÅr: Int?, val ytelse: PunsjFagsakYtelseType? ) { init { - require(barn != null || annenPart != null) { - "Må sette minst en av barn og annenPart" + when { + ytelse == null && barn.isNullOrBlank() && annenPart.isNullOrBlank() -> { + throw JournalpostkopieringService.KanIkkeKopieresErrorResponse( + "Må sette minst barn eller annenPart", + HttpStatus.BAD_REQUEST + ) + } + + ytelse != null && gjelderYtelseMedBarn() && barn.isNullOrBlank() && annenPart.isNullOrBlank() -> { + throw JournalpostkopieringService.KanIkkeKopieresErrorResponse( + "Må sette minst barn eller annenPart", + HttpStatus.BAD_REQUEST + ) + } + + ytelse != null && gjelderYtelseMedBehandlingsÅr() && behandlingsÅr == null -> { + throw JournalpostkopieringService.KanIkkeKopieresErrorResponse( + "Må sette behandlingsÅr", + HttpStatus.BAD_REQUEST + ) + } } } - fun somK9SakGrunnlag(k9FagsakYtelseType: FagsakYtelseType, periodeDto: PeriodeDto?): HentK9SaksnummerGrunnlag = HentK9SaksnummerGrunnlag( - søknadstype = ytelse ?: k9FagsakYtelseType.somPunsjFagsakYtelseType(), - søker = fra.somIdentitetsnummer().toString(), - pleietrengende = barn?.somIdentitetsnummer().toString(), - annenPart = annenPart?.somIdentitetsnummer().toString(), - periode = periodeDto - ) + private fun gjelderYtelseMedBarn(): Boolean = listOf( + PunsjFagsakYtelseType.PLEIEPENGER_SYKT_BARN, + PunsjFagsakYtelseType.PLEIEPENGER_LIVETS_SLUTTFASE, + PunsjFagsakYtelseType.OMSORGSPENGER_KRONISK_SYKT_BARN, + PunsjFagsakYtelseType.OMSORGSPENGER_ALENE_OMSORGEN, + PunsjFagsakYtelseType.OMSORGSPENGER_MIDLERTIDIG_ALENE, + ).contains(ytelse) + + private fun gjelderYtelseMedBehandlingsÅr(): Boolean = listOf( + PunsjFagsakYtelseType.OMSORGSPENGER_UTBETALING, + PunsjFagsakYtelseType.OMSORGSPENGER + ).contains(ytelse) + + fun somK9SakGrunnlag(k9FagsakYtelseType: FagsakYtelseType, periodeDto: PeriodeDto?): HentK9SaksnummerGrunnlag { + val periode = if (ytelse == null || !gjelderYtelseMedBehandlingsÅr()) periodeDto + else PeriodeDto(LocalDate.of(behandlingsÅr!!, 1, 1), LocalDate.of(behandlingsÅr, 12, 31)) + + return HentK9SaksnummerGrunnlag( + søknadstype = ytelse ?: k9FagsakYtelseType.somPunsjFagsakYtelseType(), + søker = til.somIdentitetsnummer().toString(), + pleietrengende = barn?.somIdentitetsnummer().toString(), + annenPart = annenPart?.somIdentitetsnummer().toString(), + periode = periode + ) + } } diff --git a/src/main/kotlin/no/nav/k9punsj/journalpost/dto/KopierJournalpostInfo.kt b/src/main/kotlin/no/nav/k9punsj/journalpost/dto/KopierJournalpostInfo.kt index 0c7b4e667..a97c06fea 100644 --- a/src/main/kotlin/no/nav/k9punsj/journalpost/dto/KopierJournalpostInfo.kt +++ b/src/main/kotlin/no/nav/k9punsj/journalpost/dto/KopierJournalpostInfo.kt @@ -5,7 +5,6 @@ import no.nav.k9punsj.felles.PunsjFagsakYtelseType data class KopierJournalpostInfo( val nyJournalpostId: String, val saksnummer: String, - val fra: String, val til: String, val pleietrengende: String? = null, val annenPart: String? = null, diff --git a/src/test/kotlin/no/nav/k9punsj/journalpost/KopierJournalpostRouteTest.kt b/src/test/kotlin/no/nav/k9punsj/journalpost/KopierJournalpostRouteTest.kt index 14276cdaa..87f743ce2 100644 --- a/src/test/kotlin/no/nav/k9punsj/journalpost/KopierJournalpostRouteTest.kt +++ b/src/test/kotlin/no/nav/k9punsj/journalpost/KopierJournalpostRouteTest.kt @@ -9,6 +9,14 @@ import no.nav.k9punsj.domenetjenester.SoknadService import no.nav.k9punsj.felles.Identitetsnummer.Companion.somIdentitetsnummer import no.nav.k9punsj.felles.JournalpostId.Companion.somJournalpostId import no.nav.k9punsj.felles.PunsjFagsakYtelseType +import no.nav.k9punsj.felles.PunsjFagsakYtelseType.OMSORGSPENGER +import no.nav.k9punsj.felles.PunsjFagsakYtelseType.OMSORGSPENGER_ALENE_OMSORGEN +import no.nav.k9punsj.felles.PunsjFagsakYtelseType.OMSORGSPENGER_KRONISK_SYKT_BARN +import no.nav.k9punsj.felles.PunsjFagsakYtelseType.OMSORGSPENGER_MIDLERTIDIG_ALENE +import no.nav.k9punsj.felles.PunsjFagsakYtelseType.OMSORGSPENGER_UTBETALING +import no.nav.k9punsj.felles.PunsjFagsakYtelseType.PLEIEPENGER_LIVETS_SLUTTFASE +import no.nav.k9punsj.felles.PunsjFagsakYtelseType.PLEIEPENGER_SYKT_BARN +import no.nav.k9punsj.felles.PunsjFagsakYtelseType.UKJENT import no.nav.k9punsj.fordel.FordelPunsjEventDto import no.nav.k9punsj.fordel.HendelseMottaker import no.nav.k9punsj.fordel.K9FordelType @@ -24,13 +32,16 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource import org.junit.jupiter.params.provider.ValueSource import org.mockito.Mockito import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.actuate.metrics.MetricsEndpoint import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.http.HttpHeaders +import org.springframework.http.HttpStatus import org.springframework.web.reactive.function.BodyInserters import java.time.LocalDate import java.time.LocalDateTime @@ -79,6 +90,101 @@ internal class KopierJournalpostRouteTest : AbstractContainerBaseTest() { cleanUpDB() } + @ParameterizedTest + @EnumSource(PunsjFagsakYtelseType::class) + fun `Forventer ingen valideringfeil`(ytelseType: PunsjFagsakYtelseType) { + val søkerAktørId = "27519339353" + + when (ytelseType) { + PLEIEPENGER_SYKT_BARN, PLEIEPENGER_LIVETS_SLUTTFASE, OMSORGSPENGER_MIDLERTIDIG_ALENE, OMSORGSPENGER_KRONISK_SYKT_BARN, OMSORGSPENGER_ALENE_OMSORGEN -> { + val barnEllerAnnenPart = "05032435485" + KopierJournalpostDto( + til = søkerAktørId, + barn = barnEllerAnnenPart, + annenPart = null, + behandlingsÅr = null, + ytelse = null + ) + KopierJournalpostDto( + til = søkerAktørId, + barn = barnEllerAnnenPart, + annenPart = null, + behandlingsÅr = null, + ytelse = null + ) + KopierJournalpostDto( + til = søkerAktørId, + barn = null, + annenPart = barnEllerAnnenPart, + behandlingsÅr = null, + ytelse = null + ) + } + + else -> {} + } + when (ytelseType) { + OMSORGSPENGER, OMSORGSPENGER_UTBETALING -> { + val behandlingsÅr = 2024 + KopierJournalpostDto( + til = søkerAktørId, + barn = null, + annenPart = null, + behandlingsÅr = behandlingsÅr, + ytelse = ytelseType + ) + } + + else -> {} + } + } + + fun `Forventer valideringfeil ved kopiering`() { + val søkerAktørId = "27519339353" + + // Må sette minst barn eller annenPart uten ytelse satt + assertThrows { + KopierJournalpostDto( + til = søkerAktørId, + barn = null, + annenPart = null, + behandlingsÅr = null, + ytelse = null + ) + }.also { + assertThat(it.body.status).isEqualTo(HttpStatus.BAD_REQUEST.value()) + assertThat(it.body.detail).isEqualTo("Må sette minst barn eller annenPart") + } + + // Må sette minst barn eller annenPart med ytelse satt + assertThrows { + KopierJournalpostDto( + til = søkerAktørId, + barn = null, + annenPart = null, + behandlingsÅr = null, + ytelse = PLEIEPENGER_SYKT_BARN + ) + }.also { + assertThat(it.body.status).isEqualTo(HttpStatus.BAD_REQUEST.value()) + assertThat(it.body.detail).isEqualTo("Må sette minst barn eller annenPart") + } + + // Må sette behandlingsÅr med ytelse satt + assertThrows { + KopierJournalpostDto( + til = søkerAktørId, + barn = null, + annenPart = null, + behandlingsÅr = null, + ytelse = OMSORGSPENGER_UTBETALING + ) + }.also { + assertThat(it.body.status).isEqualTo(HttpStatus.BAD_REQUEST.value()) + assertThat(it.body.detail).isEqualTo("Må sette behandlingsÅr") + } + } + @Test fun `Mapper kopierjournalpostinfo med barn og sender inn`(): Unit = runBlocking { val journalpostId = IdGenerator.nesteId() @@ -131,10 +237,10 @@ internal class KopierJournalpostRouteTest : AbstractContainerBaseTest() { val journalpost = journalpostRepository.hent(journalpostId) val kopierJournalpostDto = KopierJournalpostDto( - fra = journalpost.aktørId.toString(), til = journalpost.aktørId.toString(), barn = barn, annenPart = null, + behandlingsÅr = null, ytelse = null ) @@ -146,16 +252,17 @@ internal class KopierJournalpostRouteTest : AbstractContainerBaseTest() { .exchange() .expectStatus().isCreated .expectBody() - .json(""" + .json( + """ { "nyJournalpostId":"$nyJournalpostId", "saksnummer":"$saksnummer", - "fra":"$søkerAktørId", "til":"$søkerAktørId", "pleietrengende":"$barn", "annenPart":null, "ytelse":"PSB" - }""".trimIndent()) + }""".trimIndent() + ) val journalpostKopi = journalpostRepository.hentHvis(nyJournalpostId) Assertions.assertNotNull(journalpostKopi) @@ -207,18 +314,18 @@ internal class KopierJournalpostRouteTest : AbstractContainerBaseTest() { aktørId = søkerAktørId, journalpostId = journalpostId, type = K9FordelType.PAPIRSØKNAD.kode, - ytelse = PunsjFagsakYtelseType.UKJENT.kode + ytelse = UKJENT.kode ) hendelseMottaker.prosesser(melding) val journalpost = journalpostRepository.hent(journalpostId) val kopierJournalpostDto = KopierJournalpostDto( - fra = journalpost.aktørId.toString(), til = journalpost.aktørId.toString(), barn = barn, annenPart = null, - ytelse = PunsjFagsakYtelseType.PLEIEPENGER_SYKT_BARN + behandlingsÅr = null, + ytelse = PLEIEPENGER_SYKT_BARN ) webTestClient @@ -229,16 +336,17 @@ internal class KopierJournalpostRouteTest : AbstractContainerBaseTest() { .exchange() .expectStatus().isCreated .expectBody() - .json(""" + .json( + """ { "nyJournalpostId":"$nyJournalpostId", "saksnummer":"$saksnummer", - "fra":"$søkerAktørId", "til":"$søkerAktørId", "pleietrengende":"$barn", "annenPart":null, "ytelse":"PSB" - }""".trimIndent()) + }""".trimIndent() + ) val journalpostKopi = journalpostRepository.hentHvis(nyJournalpostId) Assertions.assertNotNull(journalpostKopi)