Skip to content

Commit

Permalink
FAGSYSTEM-360070 Støtte oppdatering av ident UTEN hendelse (#6604)
Browse files Browse the repository at this point in the history
* FAGSYSTEM-360070 Støtte oppdatering av ident UTEN hendelse

* fikse og legge til test

* ikon på knapp
  • Loading branch information
Watercolours authored Dec 13, 2024
1 parent 8bec594 commit 13372aa
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 26 deletions.
26 changes: 18 additions & 8 deletions apps/etterlatte-behandling/src/main/kotlin/sak/SakRoutes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import no.nav.etterlatte.libs.common.behandling.SakType
import no.nav.etterlatte.libs.common.behandling.SisteIverksatteBehandling
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
import no.nav.etterlatte.libs.common.sak.HentSakerRequest
import no.nav.etterlatte.libs.common.sak.Sak
Expand Down Expand Up @@ -212,9 +213,11 @@ internal fun Route.sakWebRoutes(

post("/oppdater-ident") {
kunSaksbehandlerMedSkrivetilgang { saksbehandler ->
val hendelseId =
call.request.queryParameters["hendelseId"]?.let(UUID::fromString)
?: throw UgyldigForespoerselException("HENDELSE_ID_MANGLER", "HendelseID mangler")
val request = call.receive<OppdaterIdentRequest>()

if (request.hendelseId == null && !request.utenHendelse) {
throw InternfeilException("HendelseID mangler – kan ikke oppdatere ident på sak $sakId")
}

val oppdatertSak =
inTransaction {
Expand All @@ -238,11 +241,13 @@ internal fun Route.sakWebRoutes(
)
}

grunnlagsendringshendelseService.arkiverHendelseMedKommentar(
hendelseId = hendelseId,
kommentar = "Sak er oppdatert med ny ident på bruker (fra=${sak.ident}, til=${oppdatertSak.ident})",
saksbehandler = saksbehandler,
)
if (request.hendelseId != null) {
grunnlagsendringshendelseService.arkiverHendelseMedKommentar(
hendelseId = request.hendelseId,
kommentar = "Sak er oppdatert med ny ident på bruker (fra=${sak.ident}, til=${oppdatertSak.ident})",
saksbehandler = saksbehandler,
)
}

oppdatertSak
}
Expand Down Expand Up @@ -386,6 +391,11 @@ data class EnhetRequest(
val enhet: Enhetsnummer,
)

data class OppdaterIdentRequest(
val hendelseId: UUID?,
val utenHendelse: Boolean = false,
)

data class SakerDto(
val saker: Map<SakId, Sak>,
)
47 changes: 46 additions & 1 deletion apps/etterlatte-behandling/src/test/kotlin/sak/SakRoutesTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.contentType
import io.ktor.server.testing.testApplication
import io.mockk.Called
import io.mockk.clearAllMocks
import io.mockk.coEvery
import io.mockk.every
Expand Down Expand Up @@ -242,9 +243,10 @@ internal class SakRoutesTest {

withTestApplication { client ->
val response =
client.post("/api/sak/$sakId/oppdater-ident?hendelseId=$hendelseId") {
client.post("/api/sak/$sakId/oppdater-ident") {
header(HttpHeaders.Authorization, "Bearer $token")
contentType(ContentType.Application.Json)
setBody(OppdaterIdentRequest(hendelseId))
}
assertEquals(200, response.status.value)
}
Expand All @@ -263,6 +265,49 @@ internal class SakRoutesTest {
}
}

@Test
fun `Oppdater ident på sak - uten hendelse`() {
val nyIdent = KONTANT_FOT
val sakId = SakId(Random.nextLong())
val sak =
Sak(
"ident",
SakType.OMSTILLINGSSTOENAD,
sakId,
Enheter.defaultEnhet.enhetNr,
)

every { sakService.finnSak(any()) } returns sak
every { sakService.oppdaterIdentForSak(any(), any()) } returns sak.copy(ident = nyIdent.value)
val behandlingOgSak = BehandlingOgSak(UUID.randomUUID(), sakId)
every { behandlingService.hentAapneBehandlingerForSak(sakId) } returns listOf(behandlingOgSak)

withTestApplication { client ->
val response =
client.post("/api/sak/$sakId/oppdater-ident") {
header(HttpHeaders.Authorization, "Bearer $token")
contentType(ContentType.Application.Json)
setBody(OppdaterIdentRequest(null, utenHendelse = true))
}
assertEquals(200, response.status.value)
}

verify(exactly = 1) {
sakService.finnSak(sakId)
sakService.oppdaterIdentForSak(sak, any())
behandlingService.hentAapneBehandlingerForSak(sakId)
behandlingService.avbrytBehandling(
behandlingOgSak.behandlingId,
any(),
AarsakTilAvbrytelse.ENDRET_FOLKEREGISTERIDENT,
any(),
)
}
verify {
grunnlagsendringshendelseService wasNot Called
}
}

private fun withTestApplication(block: suspend (client: HttpClient) -> Unit) {
val user =
mockk<SaksbehandlerMedEnheterOgRoller>().also { every { it.name() } returns this::class.java.simpleName }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,46 @@ import { ISakMedUtlandstilknytning } from '~shared/types/sak'
import { ApiErrorAlert } from '~ErrorBoundary'
import { useNavigate } from 'react-router-dom'
import { FeatureToggle, useFeaturetoggle } from '~useUnleash'
import { usePerson } from '~shared/statusbar/usePerson'
import { ArrowsCirclepathIcon } from '@navikt/aksel-icons'

export const OppdaterIdentModal = ({
sak,
hendelse,
}: {
sak: ISakMedUtlandstilknytning
hendelse: Grunnlagsendringshendelse
hendelse: Grunnlagsendringshendelse | null
}) => {
const samsvar = hendelse.samsvarMellomKildeOgGrunnlag as Folkeregisteridentifikatorsamsvar
const samsvar = hendelse?.samsvarMellomKildeOgGrunnlag as Folkeregisteridentifikatorsamsvar

const person = usePerson()
const navigate = useNavigate()
const [isOpen, setIsOpen] = useState(false)

const [oppdaterIdentResult, apiOppdaterIdentPaaSak] = useApiCall(oppdaterIdentPaaSak)
const kanOppdatereIdentPaaSak = useFeaturetoggle(FeatureToggle.pensjon_etterlatte_oppdater_ident_paa_sak)

const oppdaterIdent = () => {
apiOppdaterIdentPaaSak({ sakId: sak.id, hendelseId: hendelse.id }, (sak) => {
apiOppdaterIdentPaaSak({ sakId: sak.id, hendelseId: hendelse?.id, utenHendelse: hendelse === null }, (sak) => {
setTimeout(() => navigate('/person', { state: { fnr: sak.ident } }), 3000)
})
}

if (!kanOppdatereIdentPaaSak) {
return null
} else if (!!person?.foedselsnummer && person.foedselsnummer === sak.ident) {
return (
<Alert variant="warning" size="small">
Saken ser ut til å være koblet til siste gjeldende fødselsnummer. Hendelsen kan arkiveres.
</Alert>
)
}

return (
<>
<Button onClick={() => setIsOpen(true)}>Oppdater ident</Button>
<div>
<Button onClick={() => setIsOpen(true)} icon={<ArrowsCirclepathIcon />}>
Oppdater ident
</Button>

<Modal
open={isOpen}
Expand All @@ -57,15 +68,24 @@ export const OppdaterIdentModal = ({
<Tag variant="error">{sak.ident}</Tag>
</div>

<div>
<Heading size="xsmall">Ident i Grunnlag</Heading>
<Tag variant="error">{samsvar.fraGrunnlag}</Tag>
</div>
{!!samsvar ? (
<>
<div>
<Heading size="xsmall">Ident i Grunnlag</Heading>
<Tag variant="error">{samsvar.fraGrunnlag}</Tag>
</div>

<div>
<Heading size="xsmall">Ident i PDL</Heading>
<Tag variant="success">{samsvar.fraPdl}</Tag>
</div>
<div>
<Heading size="xsmall">Ident i PDL</Heading>
<Tag variant="success">{samsvar.fraPdl}</Tag>
</div>
</>
) : (
<div>
<Heading size="xsmall">Gjeldende ident i PDL</Heading>
<Tag variant="success">{person?.foedselsnummer}</Tag>
</div>
)}
</HStack>

<Alert variant="warning">
Expand All @@ -91,6 +111,6 @@ export const OppdaterIdentModal = ({
)}
</Modal.Body>
</Modal>
</>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { Vedtaksloesning } from '~shared/types/IDetaljertBehandling'
import { SakTypeTag } from '~shared/tags/SakTypeTag'
import { UtenlandstilknytningTypeTag } from '~shared/tags/UtenlandstilknytningTypeTag'
import { OpprettSaksgrunnlag } from '~components/person/sakOgBehandling/OpprettSaksgrunnlag'
import { OppdaterIdentModal } from '~components/person/hendelser/OppdaterIdentModal'
import { usePerson } from '~shared/statusbar/usePerson'

const ETTERLATTEREFORM_DATO = '2024-01'

Expand All @@ -27,6 +29,7 @@ interface Props {

export const SakOversiktHeader = ({ sak, behandlinger, fnr }: Props) => {
const innloggetSaksbehandler = useInnloggetSaksbehandler()
const person = usePerson()

const [navkontorResult, hentNavkontor] = useApiCall(hentNavkontorForPerson)
const [yrkesskadefordelResult, hentYrkesskadefordel] = useApiCall(hentMigrertYrkesskadeFordel)
Expand Down Expand Up @@ -114,6 +117,8 @@ export const SakOversiktHeader = ({ sak, behandlinger, fnr }: Props) => {
})}

{!behandlinger.length && <OpprettSaksgrunnlag sak={sak} />}

{!!person && person.foedselsnummer !== sak.ident && <OppdaterIdentModal sak={sak} hendelse={null} />}
</VStack>
)
}
11 changes: 9 additions & 2 deletions apps/etterlatte-saksbehandling-ui/client/src/shared/api/sak.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ export const byttEnhetPaaSak = async (args: { sakId: number; enhet: string }): P
return apiClient.post(`sak/${args.sakId}/endre-enhet`, { enhet: args.enhet })
}

export const oppdaterIdentPaaSak = async (args: { sakId: number; hendelseId: string }): Promise<ApiResponse<ISak>> => {
return apiClient.post(`sak/${args.sakId}/oppdater-ident?hendelseId=${args.hendelseId}`, {})
export const oppdaterIdentPaaSak = async (args: {
sakId: number
hendelseId?: string
utenHendelse: boolean
}): Promise<ApiResponse<ISak>> => {
return apiClient.post(`sak/${args.sakId}/oppdater-ident`, {
hendelseId: args.hendelseId,
utenHendelse: args.utenHendelse,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@ import { DoedsdatoTag } from '~shared/tags/DoedsdatoTag'
import { PersonLink } from '~components/person/lenker/PersonLink'
import { VergemaalTag } from '~shared/tags/VergemaalTag'
import { Navbar } from '~shared/header/Navbar'
import { useAppDispatch } from '~store/Store'
import { settPerson } from '~store/reducers/PersonReducer'

export const StatusBar = ({ ident }: { ident: string | null | undefined }) => {
const dispatch = useAppDispatch()

const [result, hentPerson] = useApiCall(hentPersonNavnogFoedsel)

useEffect(() => {
if (ident) hentPerson(ident)
if (ident) {
hentPerson(ident, (person) => {
dispatch(settPerson(person))
})
}
}, [ident])

const gender = (fnr: string): GenderList => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useAppSelector } from '~store/Store'
import { IPdlPersonNavnFoedsel } from '~shared/types/Person'

export function usePerson(): IPdlPersonNavnFoedsel | null {
return useAppSelector((state) => state.personReducer.person)
}
2 changes: 2 additions & 0 deletions apps/etterlatte-saksbehandling-ui/client/src/store/Store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { oppgaveReducer } from '~store/reducers/OppgaveReducer'
import { personopplysningerReducer } from '~store/reducers/PersonopplysningerReducer'
import { aktivitetsplikt12mndReducer } from '~store/reducers/Aktivitetsplikt12mnd'
import { unleashReducer } from '~store/reducers/UnleashReducer'
import { personReducer } from '~store/reducers/PersonReducer'

const reducer = {
menuReducer: menuReducer,
Expand All @@ -28,6 +29,7 @@ const reducer = {
tilbakekrevingReducer: tilbakekrevingReducer,
journalfoeringOppgaveReducer: journalfoeringOppgaveReducer,
sjekklisteReducer: sjekklisteReducer,
personReducer: personReducer,
personopplysningerReducer: personopplysningerReducer,
aktivitetsplikt12mndReducer: aktivitetsplikt12mndReducer,
unleashReducer: unleashReducer,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { createAction, createReducer } from '@reduxjs/toolkit'
import { IPdlPersonNavnFoedsel } from '~shared/types/Person'

export const settPerson = createAction<IPdlPersonNavnFoedsel | null>('person/set')
export const resetPerson = createAction('person/reset')

const initialState: { person: IPdlPersonNavnFoedsel | null } = {
person: null,
}

export const personReducer = createReducer(initialState, (builder) => {
builder.addCase(settPerson, (state, action) => {
state.person = action.payload
})
builder.addCase(resetPerson, (state) => {
state.person = null
})
})

0 comments on commit 13372aa

Please sign in to comment.