diff --git a/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktDao.kt b/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktDao.kt index 803a47f48ab..c9a8404d625 100644 --- a/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktDao.kt +++ b/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktDao.kt @@ -73,7 +73,7 @@ class AktivitetspliktDao( } } - fun hentAktiviteterForBehandling(behandlingId: UUID): List = + fun hentAktiviteterForBehandling(behandlingId: UUID): List = connectionAutoclosing.hentConnection { with(it) { val stmt = @@ -90,7 +90,7 @@ class AktivitetspliktDao( } } - fun hentAktiviteterForSak(sakId: SakId): List = + fun hentAktiviteterForSak(sakId: SakId): List = connectionAutoclosing.hentConnection { with(it) { val stmt = @@ -269,8 +269,106 @@ class AktivitetspliktDao( } } + fun hentHendelserForBehandling(behandlingId: UUID): List = + connectionAutoclosing.hentConnection { + with(it) { + val stmt = + prepareStatement( + """ + SELECT id, sak_id, behandling_id, dato, opprettet, endret, beskrivelse + FROM aktivitetsplikt_hendelse + WHERE behandling_id = ? + """.trimMargin(), + ) + stmt.setObject(1, behandlingId) + + stmt.executeQuery().toList { toHendelse() } + } + } + + fun hentHendelserForSak(sakId: SakId): List = + connectionAutoclosing.hentConnection { + with(it) { + val stmt = + prepareStatement( + """ + SELECT id, sak_id, behandling_id, dato, opprettet, endret, beskrivelse + FROM aktivitetsplikt_hendelse + WHERE sak_id = ? + """.trimMargin(), + ) + stmt.setSakId(1, sakId) + + stmt.executeQuery().toList { toHendelse() } + } + } + + fun upsertHendelse( + behandlingId: UUID?, + hendelse: LagreAktivitetspliktHendelse, + kilde: Grunnlagsopplysning.Kilde, + ) = connectionAutoclosing.hentConnection { + with(it) { + val stmt = + prepareStatement( + """ + INSERT INTO aktivitetsplikt_hendelse(id, sak_id, behandling_id, dato, opprettet, endret, beskrivelse) + VALUES (?, ?, ?, ?, ?, ?, ?) + ON CONFLICT (id) DO UPDATE SET + dato = excluded.dato, + endret = excluded.endret, + beskrivelse = excluded.beskrivelse + """.trimMargin(), + ) + stmt.setObject(1, hendelse.id ?: UUID.randomUUID()) + stmt.setSakId(2, hendelse.sakId) + stmt.setObject(3, behandlingId) + stmt.setDate(4, Date.valueOf(hendelse.dato)) + stmt.setString(5, kilde.toJson()) + stmt.setString(6, kilde.toJson()) + stmt.setString(7, hendelse.beskrivelse) + + stmt.executeUpdate() + } + } + + fun slettHendelse(hendelseId: UUID) = + connectionAutoclosing.hentConnection { + with(it) { + val stmt = + prepareStatement( + """ + DELETE FROM aktivitetsplikt_hendelse + WHERE id = ? + """.trimMargin(), + ) + stmt.setObject(1, hendelseId) + + stmt.executeUpdate() + } + } + + fun kopierHendelser( + forrigeBehandlingId: UUID, + nyBehandlingId: UUID, + ) = connectionAutoclosing.hentConnection { + with(it) { + val stmt = + prepareStatement( + """ + INSERT INTO aktivitetsplikt_hendelse (id, sak_id, behandling_id, dato, opprettet, endret, beskrivelse) + (SELECT gen_random_uuid(), sak_id, ?, dato, opprettet, endret, beskrivelse FROM aktivitetsplikt_hendelse WHERE behandling_id = ?) + """.trimMargin(), + ) + stmt.setObject(1, nyBehandlingId) + stmt.setObject(2, forrigeBehandlingId) + + stmt.executeUpdate() + } + } + private fun ResultSet.toAktivitet() = - AktivitetspliktAktivitet( + AktivitetspliktAktivitetPeriode( id = getUUID("id"), sakId = SakId(getLong("sak_id")), type = AktivitetspliktAktivitetType.valueOf(getString("aktivitet_type")), @@ -280,9 +378,35 @@ class AktivitetspliktDao( endret = objectMapper.readValue(getString("endret")), beskrivelse = getString("beskrivelse"), ) + + private fun ResultSet.toHendelse() = + AktivitetspliktAktivitetHendelse( + id = getUUID("id"), + sakId = SakId(getLong("sak_id")), + behandlingId = getString("behandling_id")?.let { UUID.fromString(it) }, + dato = getDate("dato").toLocalDate(), + opprettet = objectMapper.readValue(getString("opprettet")), + endret = objectMapper.readValue(getString("endret")), + beskrivelse = getString("beskrivelse"), + ) } data class AktivitetspliktAktivitet( + val hendelser: List, + val perioder: List, +) + +data class AktivitetspliktAktivitetHendelse( + val id: UUID, + val sakId: SakId, + val behandlingId: UUID?, + val dato: LocalDate, + val opprettet: Grunnlagsopplysning.Kilde, + val endret: Grunnlagsopplysning.Kilde?, + val beskrivelse: String, +) + +data class AktivitetspliktAktivitetPeriode( val id: UUID, val sakId: SakId, val type: AktivitetspliktAktivitetType, @@ -318,6 +442,13 @@ data class LagreAktivitetspliktAktivitet( val beskrivelse: String, ) +data class LagreAktivitetspliktHendelse( + val id: UUID? = null, + val sakId: SakId, + val dato: LocalDate, + val beskrivelse: String, +) + enum class AktivitetspliktAktivitetType { ARBEIDSTAKER, SELVSTENDIG_NAERINGSDRIVENDE, diff --git a/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktRoute.kt b/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktRoute.kt index e501568a747..c233f328940 100644 --- a/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktRoute.kt +++ b/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktRoute.kt @@ -87,6 +87,13 @@ internal fun Route.aktivitetspliktRoutes( } } + route("/aktivitet-og-hendelser") { + get { + logger.info("Henter aktiviteter og hendelser for behandlingId=$behandlingId") + call.respond(inTransaction { aktivitetspliktService.hentAktiviteterHendelser(behandlingId = behandlingId) }) + } + } + route("/aktivitet") { get { logger.info("Henter aktiviteter for behandlingId=$behandlingId") @@ -172,6 +179,62 @@ internal fun Route.aktivitetspliktRoutes( } } + route("/aktivitet-og-hendelser") { + get { + logger.info("Henter aktiviteter og hendelser for sak=$sakId") + call.respond(inTransaction { aktivitetspliktService.hentAktiviteterHendelser(sakId = sakId) }) + } + } + + route("hendelse") { + get { + kunSaksbehandler { + logger.info("Henter hendelser for sak $sakId") + val dto = + inTransaction { + runBlocking { + // TODO + aktivitetspliktService.hentAktiviteter( + sakId = sakId, + ) + } + } + call.respond(dto) + } + } + post { + kunSkrivetilgang { + logger.info("Oppretter eller oppdaterer hendelser for sakId=$sakId") + val aktivitet = call.receive() + + val aktiviteter = + inTransaction { + // TODO + aktivitetspliktService.upsertAktivitet(aktivitet, brukerTokenInfo, sakId = sakId) + aktivitetspliktService.hentAktiviteter(sakId = sakId) + } + call.respond(aktiviteter) + } + } + + route("/{$AKTIVITET_ID_CALL_PARAMETER}") { + delete { + kunSkrivetilgang { + logger.info("Sletter aktivitet $aktivitetId for sakId $sakId") + + val aktiviteter = + inTransaction { + // TODO + aktivitetspliktService.slettAktivitet(aktivitetId, brukerTokenInfo, sakId = sakId) + aktivitetspliktService.hentAktiviteter(sakId = sakId) + } + + call.respond(aktiviteter) + } + } + } + } + route("statistikk/{$BEHANDLINGID_CALL_PARAMETER}") { get { kunSystembruker { diff --git a/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktService.kt b/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktService.kt index 4e5fd32aa0f..b81b1c94e3e 100644 --- a/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktService.kt +++ b/apps/etterlatte-behandling/src/main/kotlin/behandling/aktivitetsplikt/AktivitetspliktService.kt @@ -32,6 +32,7 @@ import no.nav.etterlatte.libs.common.behandling.Persongalleri import no.nav.etterlatte.libs.common.behandling.Prosesstype import no.nav.etterlatte.libs.common.behandling.Revurderingaarsak import no.nav.etterlatte.libs.common.behandling.tilVirkningstidspunkt +import no.nav.etterlatte.libs.common.feilhaandtering.GenerellIkkeFunnetException import no.nav.etterlatte.libs.common.feilhaandtering.IkkeFunnetException import no.nav.etterlatte.libs.common.feilhaandtering.InternfeilException import no.nav.etterlatte.libs.common.feilhaandtering.UgyldigForespoerselException @@ -173,10 +174,28 @@ class AktivitetspliktService( return varigUnntak != null } + fun hentAktiviteterHendelser( + behandlingId: UUID? = null, + sakId: SakId? = null, + ): AktivitetspliktAktivitet = + ( + if (behandlingId != null) { + val perioder = aktivitetspliktDao.hentAktiviteterForBehandling(behandlingId) + val hendelser = aktivitetspliktDao.hentHendelserForBehandling(behandlingId) + AktivitetspliktAktivitet(hendelser, perioder) + } else if (sakId != null) { + val perioder = aktivitetspliktDao.hentAktiviteterForSak(sakId) + val hendelser = aktivitetspliktDao.hentHendelserForSak(sakId) + AktivitetspliktAktivitet(hendelser, perioder) + } else { + throw ManglerSakEllerBehandlingIdException() + } + ) + fun hentAktiviteter( behandlingId: UUID? = null, sakId: SakId? = null, - ): List = + ): List = ( if (behandlingId != null) { aktivitetspliktDao.hentAktiviteterForBehandling(behandlingId) @@ -247,6 +266,73 @@ class AktivitetspliktService( } } + fun hentHendelser( + behandlingId: UUID? = null, + sakId: SakId? = null, + ): List = + ( + if (behandlingId != null) { + aktivitetspliktDao.hentHendelserForBehandling(behandlingId) + } else if (sakId != null) { + aktivitetspliktDao.hentHendelserForSak(sakId) + } else { + throw ManglerSakEllerBehandlingIdException() + } + ) + + fun upsertHendelse( + hendelse: LagreAktivitetspliktHendelse, + brukerTokenInfo: BrukerTokenInfo, + behandlingId: UUID? = null, + sakId: SakId? = null, + ) { + val kilde = Grunnlagsopplysning.Saksbehandler.create(brukerTokenInfo.ident()) + + if (behandlingId != null) { + val behandling = + requireNotNull(behandlingService.hentBehandling(behandlingId)) { "Fant ikke behandling $behandlingId" } + if (!behandling.status.kanEndres()) { + throw BehandlingKanIkkeEndres() + } + if (hendelse.sakId != behandling.sak.id) { + throw SakidTilhoererIkkeBehandlingException() + } + aktivitetspliktDao.upsertHendelse(behandlingId, hendelse, kilde) + + runBlocking { sendDtoTilStatistikk(hendelse.sakId, brukerTokenInfo, behandlingId) } + } else if (sakId != null) { + if (hendelse.sakId != sakId) { + throw SakidTilhoererIkkeBehandlingException() + } + aktivitetspliktDao.upsertHendelse(null, hendelse, kilde) + } else { + throw ManglerSakEllerBehandlingIdException() + } + } + + fun slettHendelse( + hendelseId: UUID, + brukerTokenInfo: BrukerTokenInfo, + sakId: SakId, + ) { + val hendelseForSak = + aktivitetspliktDao.hentHendelserForSak(sakId).firstOrNull { it.id == hendelseId } ?: throw GenerellIkkeFunnetException() + + if (hendelseForSak.behandlingId != null) { + val behandling = + requireNotNull( + behandlingService.hentBehandling(hendelseForSak.behandlingId), + ) { "Fant ikke behandling ${hendelseForSak.behandlingId}" } + if (!behandling.status.kanEndres()) { + throw BehandlingKanIkkeEndres() + } + aktivitetspliktDao.slettHendelse(hendelseId) + runBlocking { sendDtoTilStatistikk(behandling.sak.id, brukerTokenInfo, hendelseForSak.behandlingId) } + } else { + aktivitetspliktDao.slettHendelse(hendelseId) + } + } + fun upsertAktivitetsgradForOppgave( aktivitetsgrad: LagreAktivitetspliktAktivitetsgrad, oppgaveId: UUID, diff --git a/apps/etterlatte-behandling/src/main/resources/db/migration/V195__add_aktivitetsplikt_hendelse_table.sql b/apps/etterlatte-behandling/src/main/resources/db/migration/V195__add_aktivitetsplikt_hendelse_table.sql new file mode 100644 index 00000000000..2297fa4d192 --- /dev/null +++ b/apps/etterlatte-behandling/src/main/resources/db/migration/V195__add_aktivitetsplikt_hendelse_table.sql @@ -0,0 +1,11 @@ +CREATE TABLE aktivitetsplikt_hendelse +( + id UUID UNIQUE, + sak_id BIGINT NOT NULL, + behandling_id UUID, + dato DATE, + opprettet TEXT, + endret TEXT, + beskrivelse TEXT, + CONSTRAINT fk_sak_id FOREIGN KEY (sak_id) REFERENCES sak (id) +); \ No newline at end of file diff --git a/apps/etterlatte-behandling/src/test/kotlin/behandling/aktivitetsplikt/AktivitetspliktDaoTest.kt b/apps/etterlatte-behandling/src/test/kotlin/behandling/aktivitetsplikt/AktivitetspliktDaoTest.kt index 451df53c31e..677bd31e5bb 100644 --- a/apps/etterlatte-behandling/src/test/kotlin/behandling/aktivitetsplikt/AktivitetspliktDaoTest.kt +++ b/apps/etterlatte-behandling/src/test/kotlin/behandling/aktivitetsplikt/AktivitetspliktDaoTest.kt @@ -59,6 +59,75 @@ class AktivitetspliktDaoTest( } } + @Test + fun `skal opprette ny hendelse`() { + val behandlingId = UUID.randomUUID() + val nyHendelse = opprettHendelse(sakSkrivDao.opprettSak("Person1", SakType.OMSTILLINGSSTOENAD, Enheter.defaultEnhet.enhetNr)) + + dao.upsertHendelse(behandlingId, nyHendelse, kilde) shouldBe 1 + + val hentHendelser = dao.hentHendelserForBehandling(behandlingId) + hentHendelser.first().asClue { hendelse -> + hendelse.sakId shouldBe nyHendelse.sakId + hendelse.dato shouldBe nyHendelse.dato + hendelse.opprettet shouldBe kilde + hendelse.endret shouldBe kilde + hendelse.beskrivelse shouldBe nyHendelse.beskrivelse + hendelse.behandlingId shouldBe behandlingId + } + } + + @Test + fun `skal opprette ny hendelse for Sak`() { + val sak = sakSkrivDao.opprettSak("Person1", SakType.OMSTILLINGSSTOENAD, Enheter.defaultEnhet.enhetNr) + val nyHendelse = opprettHendelse(sak) + + dao.upsertHendelse(null, nyHendelse, kilde) shouldBe 1 + + val hentHendelser = dao.hentHendelserForSak(sak.id) + hentHendelser.first().asClue { hendelse -> + hendelse.sakId shouldBe nyHendelse.sakId + hendelse.dato shouldBe nyHendelse.dato + hendelse.opprettet shouldBe kilde + hendelse.endret shouldBe kilde + hendelse.beskrivelse shouldBe nyHendelse.beskrivelse + hendelse.behandlingId shouldBe null + } + } + + @Nested + inner class OppdaterHendelse { + @Test + fun `skal oppdatere eksisterende hendelse`() { + val behandlingId = UUID.randomUUID() + val nyHendelse = opprettHendelse(sakSkrivDao.opprettSak("Person1", SakType.OMSTILLINGSSTOENAD, Enheter.defaultEnhet.enhetNr)) + dao.upsertHendelse(behandlingId, nyHendelse, kilde) + val gammelHendelse = dao.hentHendelserForBehandling(behandlingId).first() + val oppdaterHendelse = + nyHendelse.copy( + id = gammelHendelse.id, + dato = gammelHendelse.dato.plusYears(1), + beskrivelse = "Ny beskrivelse", + ) + dao.upsertHendelse( + behandlingId, + oppdaterHendelse, + kilde.copy("Z1111111"), + ) shouldBe 1 + + val hendelser = dao.hentHendelserForBehandling(behandlingId) + hendelser shouldHaveSize 1 + hendelser.first().asClue { oppdatertAktivitet -> + oppdatertAktivitet.id shouldBe gammelHendelse.id + oppdatertAktivitet.sakId shouldBe gammelHendelse.sakId + oppdatertAktivitet.dato shouldBe oppdaterHendelse.dato + oppdatertAktivitet.opprettet shouldBe gammelHendelse.opprettet + oppdatertAktivitet.endret shouldNotBe gammelHendelse.endret + oppdatertAktivitet.beskrivelse shouldBe oppdaterHendelse.beskrivelse + } + } + } + @Nested inner class OppdaterAktivitet { @Test @@ -144,6 +213,21 @@ class AktivitetspliktDaoTest( } } + @Nested + inner class SlettHendelse { + @Test + fun `skal slette hendelse`() { + val behandlingId = UUID.randomUUID() + val nyHendelse = opprettHendelse(sakSkrivDao.opprettSak("Person1", SakType.OMSTILLINGSSTOENAD, Enheter.defaultEnhet.enhetNr)) + dao.upsertHendelse(behandlingId, nyHendelse, kilde) + val hendelse = dao.hentHendelserForBehandling(behandlingId).first() + + dao.slettHendelse(hendelse.id) + + dao.hentHendelserForBehandling(behandlingId) shouldHaveSize 0 + } + } + @Nested inner class KopierAktiviteter { @Test @@ -174,6 +258,34 @@ class AktivitetspliktDaoTest( } } + @Nested + inner class KopierHendelser { + @Test + fun `skal kopiere hendelser fra tidligere behandling`() { + val forrigeBehandling = UUID.randomUUID() + val nyBehandling = UUID.randomUUID() + val nyHendelse = opprettHendelse(sakSkrivDao.opprettSak("Person1", SakType.OMSTILLINGSSTOENAD, Enheter.defaultEnhet.enhetNr)) + dao.upsertHendelse(forrigeBehandling, nyHendelse, kilde) + dao.upsertHendelse(forrigeBehandling, nyHendelse, kilde) + dao.upsertHendelse(forrigeBehandling, nyHendelse, kilde) + dao.hentHendelserForBehandling(forrigeBehandling) shouldHaveSize 3 + dao.hentHendelserForBehandling(nyBehandling) shouldHaveSize 0 + + dao.kopierHendelser(forrigeBehandling, nyBehandling) shouldBe 3 + + dao.hentHendelserForBehandling(nyBehandling).asClue { + it shouldHaveSize 3 + it.forEach { aktivitet -> + aktivitet.sakId shouldBe nyHendelse.sakId + aktivitet.dato shouldBe nyHendelse.dato + aktivitet.opprettet shouldBe kilde + aktivitet.endret shouldBe kilde + aktivitet.beskrivelse shouldBe nyHendelse.beskrivelse + } + } + } + } + companion object { fun opprettAktivitet(sak: Sak) = LagreAktivitetspliktAktivitet( @@ -183,6 +295,13 @@ class AktivitetspliktDaoTest( beskrivelse = "Beskrivelse", ) + fun opprettHendelse(sak: Sak) = + LagreAktivitetspliktHendelse( + sakId = sak.id, + dato = LocalDate.now(), + beskrivelse = "Beskrivelse", + ) + val kilde = Grunnlagsopplysning.Saksbehandler("Z123456", Tidspunkt.now()) } } diff --git a/apps/etterlatte-behandling/src/test/kotlin/behandling/aktivitetsplikt/AktivitetspliktServiceTest.kt b/apps/etterlatte-behandling/src/test/kotlin/behandling/aktivitetsplikt/AktivitetspliktServiceTest.kt index 28eed414bbc..32144d6d2e3 100644 --- a/apps/etterlatte-behandling/src/test/kotlin/behandling/aktivitetsplikt/AktivitetspliktServiceTest.kt +++ b/apps/etterlatte-behandling/src/test/kotlin/behandling/aktivitetsplikt/AktivitetspliktServiceTest.kt @@ -102,7 +102,7 @@ class AktivitetspliktServiceTest { @Test fun `Skal returnere liste med aktiviteter`() { val behandlingId = UUID.randomUUID() - val aktivitet = mockk() + val aktivitet = mockk() every { aktivitetspliktDao.hentAktiviteterForBehandling(behandlingId) } returns listOf(aktivitet) val result = service.hentAktiviteter(behandlingId) diff --git a/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/AktivitetOgHendelse.tsx b/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/AktivitetOgHendelse.tsx new file mode 100644 index 00000000000..ff5933c11b9 --- /dev/null +++ b/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/AktivitetOgHendelse.tsx @@ -0,0 +1,107 @@ +import { IBehandlingReducer } from '~store/reducers/BehandlingReducer' +import React, { useEffect, useState } from 'react' +import { useInnloggetSaksbehandler } from '~components/behandling/useInnloggetSaksbehandler' +import { behandlingErRedigerbar } from '~components/behandling/felles/utils' +import { Button, HStack } from '@navikt/ds-react' +import { PlusIcon } from '@navikt/aksel-icons' +import { IAktivitetHendelse, IAktivitetPeriode } from '~shared/types/Aktivitetsplikt' +import { NyHendelse } from '~components/behandling/aktivitetsplikt/NyHendelse' +import { NyAktivitet } from '~components/behandling/aktivitetsplikt/NyAktivitet' + +export const NyAktivitetHendelse = ({ + oppdaterAktiviteter, + redigerAktivitet, + redigerHendelse, + setHendelser, + avbrytRedigering, + sakId, + behandling = undefined, +}: { + oppdaterAktiviteter: (aktiviteter: IAktivitetPeriode[]) => void + redigerAktivitet: IAktivitetPeriode | undefined + redigerHendelse: IAktivitetHendelse | undefined + setHendelser: (aktiviteter: IAktivitetHendelse[]) => void + avbrytRedigering: () => void + sakId: number + behandling?: IBehandlingReducer +}) => { + const [visForm, setVisForm] = useState(false) + const innloggetSaksbehandler = useInnloggetSaksbehandler() + + const redigerbar = behandling + ? behandlingErRedigerbar(behandling.status, behandling.sakEnhetId, innloggetSaksbehandler.skriveEnheter) + : true + + useEffect(() => { + if (redigerAktivitet) { + setVisForm('AKTIVITET') + } + if (redigerHendelse) { + setVisForm('HENDELSE') + } + }, [redigerAktivitet, redigerHendelse]) + + function avbryt() { + avbrytRedigering() + setVisForm(false) + } + + function oppdaterHendelser(hendelser: IAktivitetHendelse[]) { + setVisForm(false) + setHendelser(hendelser) + } + + function oppdaterAktiviteterOgSkjema(aktiviteter: IAktivitetPeriode[]) { + setVisForm(false) + oppdaterAktiviteter(aktiviteter) + } + + return ( + <> + {visForm === 'AKTIVITET' && ( + + )} + {visForm === 'HENDELSE' && ( + + )} + {!visForm && redigerbar && ( + + + + + )} + + ) +} diff --git a/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/Aktivitetsplikt.tsx b/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/Aktivitetsplikt.tsx index 99a74ee208a..4a6207461c6 100644 --- a/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/Aktivitetsplikt.tsx +++ b/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/Aktivitetsplikt.tsx @@ -96,7 +96,7 @@ export const Aktivitetsplikt = (props: { behandling: IDetaljertBehandling }) => {isValidDateOfDeath(avdoedesDoedsdato!!) && ( - + )} { - const [hentet, hent] = useApiCall(hentAktiviteterForBehandling) - const [hentetForSak, hentForSak] = useApiCall(hentAktiviteterForSak) + const [hentet, hent] = useApiCall(hentAktiviteterOgHendelserForBehandling) + const [hentetForSak, hentForSak] = useApiCall(hentAktiviteterOgHendelserForSak) const [slettet, slett] = useApiCall(slettAktivitet) + const [slettetHendelse, slettHendelse] = useApiCall(slettAktivitetHendelse) const [slettetForSak, slettForSak] = useApiCall(slettAktivitetForSak) + const [slettetHendelseForSak, slettHendelseForSak] = useApiCall(slettAktivitetHendelseForSak) const seksMndEtterDoedsfall = addMonths(doedsdato, 6) const tolvMndEtterDoedsfall = addMonths(doedsdato, 12) - - const [aktiviteter, setAktiviteter] = useState([]) - const [rediger, setRediger] = useState(undefined) + const [aktiviteter, setAktiviteter] = useState([]) + const [hendelser, setHendelser] = useState([]) + const [rediger, setRediger] = useState(undefined) + const [redigerHendelse, setRedigerHendelse] = useState(undefined) const [aktivitetsTypeProps, setAktivitetsTypeProps] = useState([]) const [sluttdato, setSluttdato] = useState(addYears(doedsdato, 3)) useEffect(() => { if (behandling) { hent({ behandlingId: behandling.id }, (aktiviteter) => { - oppdaterAktiviteter(aktiviteter) + oppdaterAktiviteter(aktiviteter.perioder) + setHendelser(aktiviteter.hendelser) }) - } else if (sakId) { + } else { hentForSak({ sakId: sakId }, (aktiviteter) => { - oppdaterAktiviteter(aktiviteter) + oppdaterAktiviteter(aktiviteter.perioder) + setHendelser(aktiviteter.hendelser) }) } - }, []) + }, [behandling, sakId]) - const oppdaterAktiviteter = (aktiviteter: IAktivitet[]) => { + const oppdaterAktiviteter = (aktiviteter: IAktivitetPeriode[]) => { setAktivitetsTypeProps([...new Set(aktiviteter.map((a) => a.type))].map(mapAktivitetstypeProps)) setAktiviteter(aktiviteter) } @@ -67,13 +74,30 @@ export const AktivitetspliktTidslinje = ({ behandling, doedsdato, sakId }: Props slett({ behandlingId: behandling.id, aktivitetId: aktivitetId }, (aktiviteter) => { oppdaterAktiviteter(aktiviteter) }) - } else if (sakId) { + } else { slettForSak({ sakId: sakId, aktivitetId: aktivitetId }, (aktiviteter) => { oppdaterAktiviteter(aktiviteter) }) } } + const fjernHendelse = (hendelseId: string) => { + if (behandling) { + slettHendelse({ behandlingId: behandling.id, hendelseId: hendelseId }, (hendelser) => { + setHendelser(hendelser) + }) + } else { + slettHendelseForSak({ sakId: sakId, hendelseId: hendelseId }, (hendelser) => { + setHendelser(hendelser) + }) + } + } + + function avbrytRedigering() { + setRediger(undefined) + setRedigerHendelse(undefined) + } + return ( @@ -89,7 +113,50 @@ export const AktivitetspliktTidslinje = ({ behandling, doedsdato, sakId }: Props 12 måneder etter dødsfall: {formaterDato(tolvMndEtterDoedsfall)} - + {hendelser.map((hendelse) => ( + + {hendelse.beskrivelse} + + + + Lagt til {formaterDatoMedTidspunkt(new Date(hendelse.opprettet.tidspunkt))} av{' '} + {hendelse.opprettet.ident} + + + + + Sist endret {formaterDatoMedTidspunkt(new Date(hendelse.endret.tidspunkt))} av {hendelse.endret.ident} + + + + {isPending(slettetHendelse) || isPending(slettetHendelseForSak) ? ( + + ) : ( + + + + + )} + {isFailureHandler({ + apiResult: slettetHendelse, + errorMessage: 'En feil har oppstått', + })} + + ))} {aktiviteter.length === 0 && ( @@ -161,12 +228,15 @@ export const AktivitetspliktTidslinje = ({ behandling, doedsdato, sakId }: Props - {aktiviteter.length > 0 && ( @@ -184,8 +254,12 @@ export const AktivitetspliktTidslinje = ({ behandling, doedsdato, sakId }: Props {isFailureHandler({ - errorMessage: 'En feil oppsto ved henting av aktiviteter', - apiResult: hentet || hentetForSak, + errorMessage: 'En feil oppsto ved henting av tidslinje', + apiResult: hentet, + })} + {isFailureHandler({ + errorMessage: 'En feil oppsto ved henting av tidslinje', + apiResult: hentetForSak, })} ) diff --git a/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/NyAktivitet.tsx b/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/NyAktivitet.tsx index 378c1941ffa..93a5be81556 100644 --- a/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/NyAktivitet.tsx +++ b/apps/etterlatte-saksbehandling-ui/client/src/components/behandling/aktivitetsplikt/NyAktivitet.tsx @@ -1,54 +1,53 @@ import { IBehandlingReducer } from '~store/reducers/BehandlingReducer' import { useApiCall } from '~shared/hooks/useApiCall' -import React, { useEffect, useState } from 'react' -import { useInnloggetSaksbehandler } from '~components/behandling/useInnloggetSaksbehandler' -import { behandlingErRedigerbar } from '~components/behandling/felles/utils' +import React, { useEffect } from 'react' import { useForm } from 'react-hook-form' import { formatISO } from 'date-fns' import { isFailure, isPending } from '~shared/api/apiUtils' import { Alert, Button, Heading, HStack, Select, Textarea, VStack } from '@navikt/ds-react' -import { PlusIcon } from '@navikt/aksel-icons' -import { AktivitetspliktType, IAktivitet, IOpprettAktivitet } from '~shared/types/Aktivitetsplikt' +import { AktivitetspliktType, IAktivitetPeriode, IOpprettAktivitet } from '~shared/types/Aktivitetsplikt' import { opprettAktivitet, opprettAktivitetForSak } from '~shared/api/aktivitetsplikt' import { ControlledDatoVelger } from '~shared/components/datoVelger/ControlledDatoVelger' import { mapAktivitetstypeProps } from '~components/behandling/aktivitetsplikt/AktivitetspliktTidslinje' -interface AktivitetDefaultValue { - id: string | undefined - type: AktivitetspliktType | '' - datoFom?: Date - datoTom?: Date | null - beskrivelse: string +function dtoTilSkjema(periode: IAktivitetPeriode): AktivitetSkjemaValue { + return { + id: periode.id, + type: periode.type, + datoFom: periode.fom ? new Date(periode.fom) : undefined, + datoTom: periode.tom ? new Date(periode.tom) : null, + behandlingId: periode.behandlingId, + sakId: periode.sakId, + beskrivelse: periode.beskrivelse, + } } -const aktivitetDefaultValue: AktivitetDefaultValue = { - id: undefined, - type: '', - datoFom: undefined, - datoTom: undefined, - beskrivelse: '', +interface AktivitetSkjemaValue { + id?: string + type?: AktivitetspliktType + datoFom?: Date + datoTom?: Date | null + sakId: number + behandlingId?: string + beskrivelse?: string } export const NyAktivitet = ({ oppdaterAktiviteter, + sakId, + avbryt, redigerAktivitet, behandling = undefined, - sakId = undefined, }: { - oppdaterAktiviteter: (aktiviteter: IAktivitet[]) => void - redigerAktivitet: IAktivitet | undefined + oppdaterAktiviteter: (aktiviteter: IAktivitetPeriode[]) => void + sakId: number + avbryt: () => void + redigerAktivitet: IAktivitetPeriode | undefined behandling?: IBehandlingReducer - sakId?: number }) => { const [opprettAktivitetResponse, opprettAktivitetRequest] = useApiCall(opprettAktivitet) const [opprettAktivitetForSakResponse, opprettAktivitetForSakRequest] = useApiCall(opprettAktivitetForSak) - const [visForm, setVisForm] = useState(false) - const innloggetSaksbehandler = useInnloggetSaksbehandler() - - const redigerbar = behandling - ? behandlingErRedigerbar(behandling.status, behandling.sakEnhetId, innloggetSaksbehandler.skriveEnheter) - : true - + const defaultValue: AktivitetSkjemaValue = { sakId, behandlingId: behandling?.id } const { getValues, register, @@ -56,24 +55,17 @@ export const NyAktivitet = ({ control, reset, formState: { errors }, - } = useForm({ - defaultValues: aktivitetDefaultValue, + } = useForm({ + defaultValues: redigerAktivitet ? dtoTilSkjema(redigerAktivitet) : defaultValue, }) useEffect(() => { if (redigerAktivitet) { - reset({ - id: redigerAktivitet.id, - type: redigerAktivitet.type, - datoFom: new Date(redigerAktivitet.fom), - datoTom: redigerAktivitet.tom ? new Date(redigerAktivitet.tom) : null, - beskrivelse: redigerAktivitet.beskrivelse, - }) - setVisForm(true) + reset(dtoTilSkjema(redigerAktivitet)) } }, [redigerAktivitet]) - const submitAktivitet = (data: AktivitetDefaultValue) => { + const submitAktivitet = (data: AktivitetSkjemaValue) => { const { id, type, datoFom, datoTom, beskrivelse } = data const opprettAktivitet: IOpprettAktivitet = { @@ -81,8 +73,8 @@ export const NyAktivitet = ({ sakId: behandling ? behandling.sakId : sakId!!, type: type as AktivitetspliktType, fom: formatISO(datoFom!, { representation: 'date' }), - tom: datoTom ? formatISO(datoTom!, { representation: 'date' }) : undefined, - beskrivelse: beskrivelse, + tom: datoTom ? formatISO(datoTom, { representation: 'date' }) : undefined, + beskrivelse: beskrivelse!, } if (behandling) { @@ -92,8 +84,7 @@ export const NyAktivitet = ({ request: opprettAktivitet, }, (aktiviteter) => { - reset(aktivitetDefaultValue) - setVisForm(false) + reset({}) oppdaterAktiviteter(aktiviteter) } ) @@ -104,8 +95,7 @@ export const NyAktivitet = ({ request: opprettAktivitet, }, (aktiviteter) => { - reset(aktivitetDefaultValue) - setVisForm(false) + reset({}) oppdaterAktiviteter(aktiviteter) } ) @@ -114,92 +104,72 @@ export const NyAktivitet = ({ return ( <> - {visForm && ( -
- - {getValues('id') ? 'Endre' : 'Ny'} aktivitet - - - - - - - - -