From d54e7f2920f9fbd57e8fb26a229ffee59d57f761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Oliver=20S=C3=B8berg?= Date: Wed, 12 Feb 2025 17:54:17 +0100 Subject: [PATCH 1/5] EY-5031 Tilbakestille mottakere fra oppdatert grunnlag --- .../no/nav/etterlatte/ApplicationContext.kt | 2 ++ .../no/nav/etterlatte/brev/BrevRoute.kt | 6 ++++ .../no/nav/etterlatte/brev/BrevService.kt | 34 +++++++++++++++++++ .../brev/hentinformasjon/BrevdataFacade.kt | 33 ++++++++++++++++++ .../no/nav/etterlatte/brev/BrevServiceTest.kt | 2 ++ .../brev/mottaker/BrevMottakerWrapper.tsx | 21 +++++++++++- .../client/src/shared/api/brev.ts | 6 ++++ .../src/main/kotlin/route/RouteUtils.kt | 2 +- 8 files changed, 104 insertions(+), 2 deletions(-) diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/ApplicationContext.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/ApplicationContext.kt index 1438e3c7d7e..1965a203db6 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/ApplicationContext.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/ApplicationContext.kt @@ -207,6 +207,8 @@ internal class ApplicationContext { brevdistribuerer, dokdistKanalKlient, oppgaveService, + brevdataFacade, + adresseService, ) val clamAvClient = ClamAvClient(httpClient(), env.requireEnvValue(CLAMAV_ENDPOINT_URL)) diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt index b4d32200a2a..9a1dcfe0d81 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt @@ -109,6 +109,12 @@ fun Route.brevRoute( } } + post("tilbakestill") { + withSakId(tilgangssjekker, skrivetilgang = true) { + service.tilbakestillMottakere(brevId, brukerTokenInfo) + } + } + put("{mottakerId}/hoved") { withSakId(tilgangssjekker, skrivetilgang = true) { val mottakerId = diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt index 55b8f2259e2..0dff1e904b3 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt @@ -1,11 +1,13 @@ package no.nav.etterlatte.brev +import no.nav.etterlatte.brev.adresse.AdresseService import no.nav.etterlatte.brev.behandling.opprettAvsenderRequest import no.nav.etterlatte.brev.db.BrevRepository import no.nav.etterlatte.brev.distribusjon.BestemDistribusjonskanalRequest import no.nav.etterlatte.brev.distribusjon.BestemDistribusjonskanalResponse import no.nav.etterlatte.brev.distribusjon.Brevdistribuerer import no.nav.etterlatte.brev.distribusjon.DokDistKanalKlient +import no.nav.etterlatte.brev.hentinformasjon.BrevdataFacade import no.nav.etterlatte.brev.model.Brev import no.nav.etterlatte.brev.model.BrevDistribusjonResponse import no.nav.etterlatte.brev.model.BrevID @@ -45,6 +47,8 @@ class BrevService( private val distribuerer: Brevdistribuerer, private val dokDistKanalKlient: DokDistKanalKlient, private val oppgaveService: OppgaveService, + private val brevdataFacade: BrevdataFacade, + private val adresseService: AdresseService, ) { private val logger = LoggerFactory.getLogger(this::class.java) private val sikkerlogger = sikkerlogger() @@ -297,6 +301,30 @@ class BrevService( } } + suspend fun tilbakestillMottakere( + brevId: BrevID, + bruker: BrukerTokenInfo, + ): List { + val brev = sjekkOmBrevKanEndres(brevId) + logger.info("Tilbakestiller mottakere for brev=$brevId") + val personerISakOgSak = brevdataFacade.hentPersonerISakforBrev(brev.sakId, brev.behandlingId, bruker) + brev.mottakere.forEach { mottaker -> + db.slettMottaker(brev.id, mottaker.id, bruker) + } + val mottakere = adresseService.hentMottakere(personerISakOgSak.sak.sakType, personerISakOgSak.personerISak, bruker) + if (mottakere.isEmpty()) { + throw KanIkkeTilbakestilleUtenNyeMottakere() + } + if (!mottakere.any { it.type == MottakerType.HOVED }) { + throw KanIkkeSletteHovedmottaker() + } + mottakere.forEach { mottaker -> + db.oppdaterMottaker(brev.id, mottaker, bruker) + } + + return db.hentBrev(brevId).mottakere + } + fun oppdaterMottaker( brevId: BrevID, mottaker: Mottaker, @@ -487,6 +515,12 @@ class BrevKanIkkeEndres( class MaksAntallMottakere : UgyldigForespoerselException("MAKS_ANTALL_MOTTAKERE", "Maks 2 mottakere tillatt") +class KanIkkeTilbakestilleUtenNyeMottakere : + UgyldigForespoerselException( + code = "KAN_IKKE_SLETTE_MOTTAKERE_UTEN_NY", + detail = "Kan ikke tilbakestille mottakere hvis det ikke er nye", + ) + class KanIkkeSletteHovedmottaker : UgyldigForespoerselException( code = "KAN_IKKE_SLETTE_HOVEDMOTTAKER", diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/hentinformasjon/BrevdataFacade.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/hentinformasjon/BrevdataFacade.kt index 87e493a3197..94cbaa70005 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/hentinformasjon/BrevdataFacade.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/hentinformasjon/BrevdataFacade.kt @@ -32,6 +32,11 @@ import org.slf4j.Logger import org.slf4j.LoggerFactory import java.util.UUID +data class PersonerISakOgSak( + val personerISak: PersonerISak, + val sak: Sak, +) + class BrevdataFacade( private val vedtaksvurderingService: VedtaksvurderingService, private val grunnlagService: GrunnlagService, @@ -39,6 +44,34 @@ class BrevdataFacade( ) { private val logger: Logger = LoggerFactory.getLogger(BrevdataFacade::class.java) + suspend fun hentPersonerISakforBrev( + sakId: SakId, + behandlingId: UUID?, + brukerTokenInfo: BrukerTokenInfo, + ): PersonerISakOgSak = + coroutineScope { + val sakDeferred = async { behandlingService.hentSak(sakId, brukerTokenInfo) } + val vedtakDeferred = behandlingId?.let { async { vedtaksvurderingService.hentVedtak(it, brukerTokenInfo) } } + val vedtakType = vedtakDeferred?.await()?.type + val grunnlag = grunnlagService.hentGrunnlag(vedtakType, sakId, brukerTokenInfo, behandlingId) + val sak = sakDeferred.await() + val brevutfallDeferred = behandlingId?.let { async { behandlingService.hentBrevutfall(it, brukerTokenInfo) } } + + val brevutfallDto = brevutfallDeferred?.await() + val verge = grunnlagService.hentVergeForSak(sak.sakType, brevutfallDto, grunnlag) + val personerISak = + PersonerISak( + innsender = grunnlag.mapInnsender(), + soeker = grunnlag.mapSoeker(brevutfallDto?.aldersgruppe), + avdoede = grunnlag.mapAvdoede(), + verge = verge, + ) + PersonerISakOgSak( + personerISak = personerISak, + sak = sak, + ) + } + suspend fun hentGenerellBrevData( sakId: SakId, behandlingId: UUID?, diff --git a/apps/etterlatte-brev-api/src/test/kotlin/no/nav/etterlatte/brev/BrevServiceTest.kt b/apps/etterlatte-brev-api/src/test/kotlin/no/nav/etterlatte/brev/BrevServiceTest.kt index 9e539bd8f91..7d300e68d16 100644 --- a/apps/etterlatte-brev-api/src/test/kotlin/no/nav/etterlatte/brev/BrevServiceTest.kt +++ b/apps/etterlatte-brev-api/src/test/kotlin/no/nav/etterlatte/brev/BrevServiceTest.kt @@ -69,6 +69,8 @@ internal class BrevServiceTest { mockk(), mockk(), mockk(), + mockk(), + mockk(), ) private val bruker = simpleSaksbehandler("Z123456") diff --git a/apps/etterlatte-saksbehandling-ui/client/src/components/person/brev/mottaker/BrevMottakerWrapper.tsx b/apps/etterlatte-saksbehandling-ui/client/src/components/person/brev/mottaker/BrevMottakerWrapper.tsx index f85cc66b290..db03749e774 100644 --- a/apps/etterlatte-saksbehandling-ui/client/src/components/person/brev/mottaker/BrevMottakerWrapper.tsx +++ b/apps/etterlatte-saksbehandling-ui/client/src/components/person/brev/mottaker/BrevMottakerWrapper.tsx @@ -3,7 +3,7 @@ import { BrevMottakerPanel } from '~components/person/brev/mottaker/BrevMottaker import { Alert, Button, HStack, VStack } from '@navikt/ds-react' import React, { useState } from 'react' import { useApiCall } from '~shared/hooks/useApiCall' -import { opprettMottaker } from '~shared/api/brev' +import { opprettMottaker, tilbakestillMottakere } from '~shared/api/brev' import { isPending } from '~shared/api/apiUtils' import { PlusIcon } from '@navikt/aksel-icons' @@ -11,6 +11,13 @@ export const BrevMottakerWrapper = ({ brev, kanRedigeres }: { brev: IBrev; kanRe const [mottakere, setMottakere] = useState(brev.mottakere) const [opprettMottakerResult, apiOpprettMottaker] = useApiCall(opprettMottaker) + const [tilbakestillMottakereResult, apiTilbakestillMottaker] = useApiCall(tilbakestillMottakere) + + const tilbakestillMottakereWrapper = () => { + apiTilbakestillMottaker({ brevId: brev.id, sakId: brev.sakId }, (mottakereres) => { + setMottakere([...mottakereres]) + }) + } const opprettNyMottaker = () => { apiOpprettMottaker({ brevId: brev.id, sakId: brev.sakId }, (mottaker) => { @@ -53,6 +60,18 @@ export const BrevMottakerWrapper = ({ brev, kanRedigeres }: { brev: IBrev; kanRe )} + {kanRedigeres && ( + + + + )} ) } diff --git a/apps/etterlatte-saksbehandling-ui/client/src/shared/api/brev.ts b/apps/etterlatte-saksbehandling-ui/client/src/shared/api/brev.ts index a5202992a53..6909236699c 100644 --- a/apps/etterlatte-saksbehandling-ui/client/src/shared/api/brev.ts +++ b/apps/etterlatte-saksbehandling-ui/client/src/shared/api/brev.ts @@ -43,6 +43,12 @@ export const opprettVedtaksbrev = async (args: { export const opprettMottaker = async (props: { brevId: number; sakId: number }): Promise> => apiClient.post(`/brev/${props.brevId}/mottaker?sakId=${props.sakId}`, {}) +export const tilbakestillMottakere = async (props: { + brevId: number + sakId: number +}): Promise> => + apiClient.post(`/brev/${props.brevId}/mottaker/tilbakestill?sakId=${props.sakId}`, {}) + export const oppdaterMottaker = async (props: { brevId: number sakId: number diff --git a/libs/etterlatte-ktor/src/main/kotlin/route/RouteUtils.kt b/libs/etterlatte-ktor/src/main/kotlin/route/RouteUtils.kt index 374d2fae49e..8a6e4ba0786 100644 --- a/libs/etterlatte-ktor/src/main/kotlin/route/RouteUtils.kt +++ b/libs/etterlatte-ktor/src/main/kotlin/route/RouteUtils.kt @@ -116,7 +116,7 @@ suspend inline fun PipelineContext<*, ApplicationCall>.withSakId( val sakId = try { call.parameters[SAKID_CALL_PARAMETER]?.tilSakId() - } catch (e: Exception) { + } catch (_: Exception) { throw UgyldigForespoerselException("SAKID_IKKE_TALL", "Kunne ikke lese ut sakId-parameter") } if (sakId == null) { From 32432c75abf96b789fad63a1bd818d223a6da3dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Oliver=20S=C3=B8berg?= Date: Thu, 13 Feb 2025 09:12:29 +0100 Subject: [PATCH 2/5] Lagre hendelse opprett mottaker --- .../src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt | 2 +- .../main/kotlin/no/nav/etterlatte/brev/BrevService.kt | 9 ++++++--- .../kotlin/no/nav/etterlatte/brev/db/BrevRepository.kt | 2 ++ .../kotlin/no/nav/etterlatte/brev/BrevServiceTest.kt | 8 ++++---- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt index 9a1dcfe0d81..b206ee1a6bc 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt @@ -94,7 +94,7 @@ fun Route.brevRoute( route("mottaker") { post { withSakId(tilgangssjekker, skrivetilgang = true) { - val mottaker = service.opprettMottaker(brevId) + val mottaker = service.opprettMottaker(brevId, brukerTokenInfo) call.respond(mottaker) } diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt index 0dff1e904b3..d1f700b5f44 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt @@ -262,7 +262,10 @@ class BrevService( .also { logger.info("Vedlegg payload for brev (id=$id) oppdatert") } } - fun opprettMottaker(brevId: BrevID): Mottaker { + fun opprettMottaker( + brevId: BrevID, + brukerTokenInfo: BrukerTokenInfo, + ): Mottaker { val brev = sjekkOmBrevKanEndres(brevId) if (brev.mottakere.size > 1) { @@ -274,7 +277,7 @@ class BrevService( logger.info("Oppretter ny mottaker på brev=$brevId") db - .opprettMottaker(brevId, nyMottaker) + .opprettMottaker(brevId, nyMottaker, brukerTokenInfo) .also { logger.info("Ny mottaker opprettet på brev id=$brevId") } return nyMottaker @@ -319,7 +322,7 @@ class BrevService( throw KanIkkeSletteHovedmottaker() } mottakere.forEach { mottaker -> - db.oppdaterMottaker(brev.id, mottaker, bruker) + db.opprettMottaker(brev.id, mottaker, bruker) } return db.hentBrev(brevId).mottakere diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/db/BrevRepository.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/db/BrevRepository.kt index 053805e7ce1..87f7ee718ff 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/db/BrevRepository.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/db/BrevRepository.kt @@ -170,8 +170,10 @@ class BrevRepository( fun opprettMottaker( id: BrevID, mottaker: Mottaker, + bruker: BrukerTokenInfo, ) = using(sessionOf(ds)) { it.opprettMottaker(id, mottaker) + it.lagreHendelse(id, Status.OPPRETTET, mottaker.toJson(), bruker) } fun oppdaterMottaker( diff --git a/apps/etterlatte-brev-api/src/test/kotlin/no/nav/etterlatte/brev/BrevServiceTest.kt b/apps/etterlatte-brev-api/src/test/kotlin/no/nav/etterlatte/brev/BrevServiceTest.kt index 7d300e68d16..588c5a7ab54 100644 --- a/apps/etterlatte-brev-api/src/test/kotlin/no/nav/etterlatte/brev/BrevServiceTest.kt +++ b/apps/etterlatte-brev-api/src/test/kotlin/no/nav/etterlatte/brev/BrevServiceTest.kt @@ -268,13 +268,13 @@ internal class BrevServiceTest { every { db.hentBrev(any()) } returns brev - val faktiskMottaker = brevService.opprettMottaker(brev.id) + val faktiskMottaker = brevService.opprettMottaker(brev.id, bruker) faktiskMottaker.type shouldBe MottakerType.KOPI verify { db.hentBrev(brev.id) - db.opprettMottaker(brev.id, match { it.type == MottakerType.KOPI }) + db.opprettMottaker(brev.id, match { it.type == MottakerType.KOPI }, bruker) } } @@ -290,7 +290,7 @@ internal class BrevServiceTest { every { db.hentBrev(any()) } returns brev - assertThrows { brevService.opprettMottaker(brev.id) } + assertThrows { brevService.opprettMottaker(brev.id, bruker) } verify { db.hentBrev(brev.id) @@ -305,7 +305,7 @@ internal class BrevServiceTest { every { db.hentBrev(any()) } returns brev assertThrows { - brevService.opprettMottaker(brev.id) + brevService.opprettMottaker(brev.id, bruker) } verify { From 1825a41d1767bbff1d9ab983e271f1158300c9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Oliver=20S=C3=B8berg?= Date: Thu, 13 Feb 2025 12:46:46 +0100 Subject: [PATCH 3/5] =?UTF-8?q?Flytt=20logikk=20s=C3=A5=20ingen=20sletting?= =?UTF-8?q?=20kj=C3=B8rer=20f=C3=B8r=20validering=20av=20nye=20mottakere?= =?UTF-8?q?=20er=20OK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/no/nav/etterlatte/brev/BrevService.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt index d1f700b5f44..eb94b23402c 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt @@ -311,17 +311,18 @@ class BrevService( val brev = sjekkOmBrevKanEndres(brevId) logger.info("Tilbakestiller mottakere for brev=$brevId") val personerISakOgSak = brevdataFacade.hentPersonerISakforBrev(brev.sakId, brev.behandlingId, bruker) - brev.mottakere.forEach { mottaker -> - db.slettMottaker(brev.id, mottaker.id, bruker) - } - val mottakere = adresseService.hentMottakere(personerISakOgSak.sak.sakType, personerISakOgSak.personerISak, bruker) - if (mottakere.isEmpty()) { + val nyeMottakere = adresseService.hentMottakere(personerISakOgSak.sak.sakType, personerISakOgSak.personerISak, bruker) + if (nyeMottakere.isEmpty()) { throw KanIkkeTilbakestilleUtenNyeMottakere() } - if (!mottakere.any { it.type == MottakerType.HOVED }) { + if (!nyeMottakere.any { it.type == MottakerType.HOVED }) { throw KanIkkeSletteHovedmottaker() } - mottakere.forEach { mottaker -> + // bare slett hvis testene går gjennom + brev.mottakere.forEach { mottaker -> + db.slettMottaker(brev.id, mottaker.id, bruker) + } + nyeMottakere.forEach { mottaker -> db.opprettMottaker(brev.id, mottaker, bruker) } From baa403f646c18cb97f3ae913a8d8458d2ceeaf87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Oliver=20S=C3=B8berg?= Date: Thu, 13 Feb 2025 13:07:21 +0100 Subject: [PATCH 4/5] Glemte callrespond, som gir 404? rart.. --- .../src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt index b206ee1a6bc..b3ebd40c2f3 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevRoute.kt @@ -111,7 +111,7 @@ fun Route.brevRoute( post("tilbakestill") { withSakId(tilgangssjekker, skrivetilgang = true) { - service.tilbakestillMottakere(brevId, brukerTokenInfo) + call.respond(service.tilbakestillMottakere(brevId, brukerTokenInfo)) } } From 7cc2b1e7b0d4914969ed219221bfe0c52200908e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Oliver=20S=C3=B8berg?= Date: Thu, 13 Feb 2025 13:14:13 +0100 Subject: [PATCH 5/5] Sjekke at antall mottakere blir maks 2 --- .../src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt index eb94b23402c..c7cac284ba9 100644 --- a/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt +++ b/apps/etterlatte-brev-api/src/main/kotlin/no/nav/etterlatte/brev/BrevService.kt @@ -315,6 +315,9 @@ class BrevService( if (nyeMottakere.isEmpty()) { throw KanIkkeTilbakestilleUtenNyeMottakere() } + if (nyeMottakere.size > 2) { + throw MaksAntallMottakere() + } if (!nyeMottakere.any { it.type == MottakerType.HOVED }) { throw KanIkkeSletteHovedmottaker() }