Skip to content

Commit

Permalink
La saksbehandler krympe vedtaksperioden, men krev en begrunnelse
Browse files Browse the repository at this point in the history
Begrunnelsen ender opp i vedtaksbrevet for å informere bruker om hvorfor vedtaksperioden er kortere enn perioden de søkte på. Dette kan for eksempel komme av at bruker har begynt på arbeidstiltak senere enn perioden det er søkt for. Begrunnelsen er en standardtekst og per nå er det bare lagt opp til at bare endring i tiltaksdeltagelse er årsak til endring av vedtaksperiode. Dette vil endre seg etterhvert som de andre vilkårene blir periodisert.
  • Loading branch information
Henreich committed Jan 23, 2025
1 parent b88a5a8 commit c885732
Show file tree
Hide file tree
Showing 20 changed files with 640 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ private class BrevFørstegangsvedtakInnvilgelseDTO(
val datoForUtsending: String,
val sats: Int,
val satsBarn: Int,
val tilleggstekst: String? = null,
)

internal suspend fun Rammevedtak.toInnvilgetSøknadsbrev(
Expand Down Expand Up @@ -53,5 +54,6 @@ internal suspend fun Rammevedtak.toInnvilgetSøknadsbrev(
datoForUtsending = vedtaksdato.format(norskDatoFormatter),
sats = Satser.sats(periode.fraOgMed).sats,
satsBarn = Satser.sats(periode.fraOgMed).satsBarnetillegg,
tilleggstekst = this.behandling.tilleggstekstBrev?.tekst,
).let { serialize(it) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class BehandlingPostgresRepo(
"sendt_til_beslutning" to behandling.sendtTilBeslutning,
"sendt_til_datadeling" to behandling.sendtTilDatadeling,
"behandlingstype" to behandling.behandlingstype.toDbValue(),
"tilleggstekst_brev" to behandling.tilleggstekstBrev?.toDbJson(),
),
).asUpdate,
)
Expand Down Expand Up @@ -209,6 +210,7 @@ class BehandlingPostgresRepo(
"sendt_til_datadeling" to behandling.sendtTilDatadeling,
"sist_endret" to behandling.sistEndret,
"behandlingstype" to behandling.behandlingstype.toDbValue(),
"tilleggstekst_brev" to behandling.tilleggstekstBrev?.toDbJson(),
),
).asUpdate,
)
Expand Down Expand Up @@ -247,6 +249,7 @@ class BehandlingPostgresRepo(
val opprettet = localDateTime("opprettet")
val iverksattTidspunkt = localDateTimeOrNull("iverksatt_tidspunkt")
val sistEndret = localDateTime("sist_endret")
val tilleggstekstBrev = stringOrNull("tilleggstekst_brev")?.toTilleggstekstBrev()
return Behandling(
id = id,
sakId = sakId,
Expand All @@ -266,6 +269,7 @@ class BehandlingPostgresRepo(
sendtTilDatadeling = localDateTimeOrNull("sendt_til_datadeling"),
sistEndret = sistEndret,
behandlingstype = string("behandlingstype").toBehandlingstype(),
tilleggstekstBrev = tilleggstekstBrev,
)
}

Expand All @@ -288,7 +292,8 @@ class BehandlingPostgresRepo(
iverksatt_tidspunkt,
sendt_til_beslutning,
sendt_til_datadeling,
behandlingstype
behandlingstype,
tilleggstekst_brev
) values (
:id,
:sak_id,
Expand All @@ -305,7 +310,8 @@ class BehandlingPostgresRepo(
:iverksatt_tidspunkt,
:sendt_til_beslutning,
:sendt_til_datadeling,
:behandlingstype
:behandlingstype,
to_jsonb(:tilleggstekst_brev::jsonb)
)
""".trimIndent()

Expand All @@ -326,7 +332,8 @@ class BehandlingPostgresRepo(
iverksatt_tidspunkt = :iverksatt_tidspunkt,
sendt_til_beslutning = :sendt_til_beslutning,
sendt_til_datadeling = :sendt_til_datadeling,
behandlingstype = :behandlingstype
behandlingstype = :behandlingstype,
tilleggstekst_brev = to_jsonb(:tilleggstekst_brev::jsonb)
where id = :id
and sist_endret = :sist_endret_old
""".trimIndent()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package no.nav.tiltakspenger.vedtak.repository.behandling

import no.nav.tiltakspenger.saksbehandling.domene.behandling.TilleggstekstBrev

enum class SubsumsjonDb {
TILTAKSDELTAGELSE,
}

fun SubsumsjonDb.toDomain(): TilleggstekstBrev.Subsumsjon =
when (this) {
SubsumsjonDb.TILTAKSDELTAGELSE -> TilleggstekstBrev.Subsumsjon.TILTAKSDELTAGELSE
}

fun TilleggstekstBrev.Subsumsjon.toDb(): SubsumsjonDb =
when (this) {
TilleggstekstBrev.Subsumsjon.TILTAKSDELTAGELSE -> SubsumsjonDb.TILTAKSDELTAGELSE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package no.nav.tiltakspenger.vedtak.repository.behandling

import no.nav.tiltakspenger.libs.json.deserialize
import no.nav.tiltakspenger.libs.json.serialize
import no.nav.tiltakspenger.saksbehandling.domene.behandling.TilleggstekstBrev
import java.security.InvalidParameterException

data class TilleggstekstBrevDbJson(
val subsumsjon: SubsumsjonDb,
val tekst: String,
)

internal fun String.toTilleggstekstBrev(): TilleggstekstBrev =
try {
val tilleggstekstBrevJson = deserialize<TilleggstekstBrevDbJson>(this)

TilleggstekstBrev(
subsumsjon = tilleggstekstBrevJson.subsumsjon.toDomain(),
tekst = tilleggstekstBrevJson.tekst,
)
} catch (exception: Exception) {
throw InvalidParameterException("Det oppstod en feil ved parsing av json: " + exception.message)
}

internal fun TilleggstekstBrev.toDbJson(): String =
serialize(
TilleggstekstBrevDbJson(
subsumsjon = subsumsjon.toDb(),
tekst = tekst,
),
)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ internal data class BehandlingDTO(
val vilkårssett: VilkårssettDTO,
val stønadsdager: StønadsdagerDTO,
val attesteringer: List<AttesteringDTO>,
val tilleggstekstBrev: TilleggstekstBrevDTO?,
val kreverBegrunnelse: Boolean,
)

internal fun Behandling.toDTO() =
Expand All @@ -36,4 +38,6 @@ internal fun Behandling.toDTO() =
vilkårssett = this.vilkårssett.toDTO(),
stønadsdager = this.stønadsdager.toDTO(),
behandlingstype = behandlingstype,
tilleggstekstBrev = this.tilleggstekstBrev?.toDTO(),
kreverBegrunnelse = this.erBegrunnelsePåkrevd,
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import io.ktor.server.routing.post
import mu.KotlinLogging
import no.nav.tiltakspenger.libs.auth.core.TokenService
import no.nav.tiltakspenger.libs.auth.ktor.withSaksbehandler
import no.nav.tiltakspenger.libs.common.BehandlingId
import no.nav.tiltakspenger.libs.common.CorrelationId
import no.nav.tiltakspenger.libs.common.Saksbehandler
import no.nav.tiltakspenger.libs.periodisering.PeriodeDTO
import no.nav.tiltakspenger.saksbehandling.domene.behandling.KanIkkeOppdatereTilleggstekstBrev
import no.nav.tiltakspenger.saksbehandling.domene.behandling.KanIkkeOppdatereVurderingsperiode
import no.nav.tiltakspenger.saksbehandling.domene.behandling.OppdaterTilleggstekstBrevKommando
import no.nav.tiltakspenger.saksbehandling.domene.behandling.OppdaterVurderingsperiodeKommando
import no.nav.tiltakspenger.saksbehandling.domene.behandling.TilleggstekstBrev
import no.nav.tiltakspenger.saksbehandling.service.behandling.BehandlingService
import no.nav.tiltakspenger.saksbehandling.service.behandling.vilkår.kvp.KvpVilkårService
import no.nav.tiltakspenger.saksbehandling.service.behandling.vilkår.livsopphold.LivsoppholdVilkårService
Expand All @@ -25,14 +34,53 @@ import no.nav.tiltakspenger.vedtak.routes.behandling.vilkår.kvp.kvpRoutes
import no.nav.tiltakspenger.vedtak.routes.behandling.vilkår.livsopphold.livsoppholdRoutes
import no.nav.tiltakspenger.vedtak.routes.behandling.vilkår.tiltakdeltagelse.tiltakDeltagelseRoutes
import no.nav.tiltakspenger.vedtak.routes.correlationId
import no.nav.tiltakspenger.vedtak.routes.exceptionhandling.Standardfeil.behandlingKanIkkeVæreSendtTilBeslutterEllerVedtatt
import no.nav.tiltakspenger.vedtak.routes.exceptionhandling.Standardfeil.ikkeTilgang
import no.nav.tiltakspenger.vedtak.routes.exceptionhandling.Standardfeil.måVæreSaksbehandler
import no.nav.tiltakspenger.vedtak.routes.exceptionhandling.Standardfeil.måVæreSaksbehandlerEllerBeslutter
import no.nav.tiltakspenger.vedtak.routes.exceptionhandling.Standardfeil.nyPeriodeMåVæreInnenforVurderingsperiode
import no.nav.tiltakspenger.vedtak.routes.exceptionhandling.respond400BadRequest
import no.nav.tiltakspenger.vedtak.routes.exceptionhandling.respond403Forbidden
import no.nav.tiltakspenger.vedtak.routes.withBehandlingId
import no.nav.tiltakspenger.vedtak.routes.withBody

internal const val BEHANDLING_PATH = "/behandling"
internal const val BEHANDLINGER_PATH = "/behandlinger"

private data class OppdaterVurderingsPeriodeBody(
val periode: PeriodeDTO,
) {
fun tilKommando(
behandlingId: BehandlingId,
correlationId: CorrelationId,
saksbehandler: Saksbehandler,
): OppdaterVurderingsperiodeKommando {
return OppdaterVurderingsperiodeKommando(
behandlingId = behandlingId,
correlationId = correlationId,
saksbehandler = saksbehandler,
periode = periode.toDomain(),
)
}
}

private data class OppdaterSubsumsjonBody(
val subsumsjon: TilleggstekstBrev.Subsumsjon,
) {
fun tilKommando(
behandlingId: BehandlingId,
correlationId: CorrelationId,
saksbehandler: Saksbehandler,
): OppdaterTilleggstekstBrevKommando {
return OppdaterTilleggstekstBrevKommando(
behandlingId = behandlingId,
correlationId = correlationId,
saksbehandler = saksbehandler,
subsumsjon = subsumsjon,
)
}
}

fun Route.behandlingRoutes(
behandlingService: BehandlingService,
tiltaksdeltagelseVilkårService: TiltaksdeltagelseVilkårService,
Expand Down Expand Up @@ -91,6 +139,92 @@ fun Route.behandlingRoutes(
}
}

post("$BEHANDLING_PATH/{behandlingId}/tilleggstekst") {
logger.debug("Mottatt post-request på '$BEHANDLING_PATH/{behandlingId}/tilleggstekst' - oppdaterer tilleggstekst for brev")
call.withSaksbehandler(tokenService = tokenService, svarMed403HvisIngenScopes = false) { saksbehandler ->
call.withBehandlingId { behandlingId ->
val correlationId = call.correlationId()
call.withBody<OppdaterSubsumsjonBody> { body ->
behandlingService.oppdaterTilleggstekstBrevPåBehandling(
body.tilKommando(
behandlingId,
correlationId,
saksbehandler,
),
).fold(
{
when (it) {
is KanIkkeOppdatereTilleggstekstBrev.HarIkkeTilgang -> call.respond403Forbidden(
ikkeTilgang("${it.kreverEnAvRollene} for å oppdatere tilleggstekst for brev"),
)

is KanIkkeOppdatereTilleggstekstBrev.BehandlingErSendtTilBeslutterEllerVedtatt -> call.respond400BadRequest(
behandlingKanIkkeVæreSendtTilBeslutterEllerVedtatt(),
)
}
},
{
auditService.logMedBehandlingId(
behandlingId = behandlingId,
navIdent = saksbehandler.navIdent,
action = AuditLogEvent.Action.ACCESS,
contextMessage = "Oppdaterer tilleggstekst i brev",
correlationId = correlationId,
)

call.respond(status = HttpStatusCode.OK, it.toDTO())
},
)
}
}
}
}

post("$BEHANDLING_PATH/{behandlingId}/vurderingsperiode") {
logger.debug("Mottatt post-request på '$BEHANDLING_PATH/{behandlingId}/vurderingsperiode' - oppdaterer vurderingsperiode")
call.withSaksbehandler(tokenService = tokenService, svarMed403HvisIngenScopes = false) { saksbehandler ->
call.withBehandlingId { behandlingId ->
val correlationId = call.correlationId()
call.withBody<OppdaterVurderingsPeriodeBody> { body ->
behandlingService.oppdaterVurderingsPeriodeForBehandling(
body.tilKommando(
behandlingId,
correlationId,
saksbehandler,
),
).fold(
{
when (it) {
is KanIkkeOppdatereVurderingsperiode.HarIkkeTilgang -> call.respond403Forbidden(
ikkeTilgang("${it.kreverEnAvRollene} for å oppdatere vurderingsperiode"),
)

is KanIkkeOppdatereVurderingsperiode.BehandlingErSendtTilBeslutterEllerVedtatt -> call.respond400BadRequest(
behandlingKanIkkeVæreSendtTilBeslutterEllerVedtatt(),
)

is KanIkkeOppdatereVurderingsperiode.KanKunKrympe -> call.respond400BadRequest(
nyPeriodeMåVæreInnenforVurderingsperiode("Ny periode må være innenfor opprinnelig vurderingsperiode ${it.opprinnligVurderingsperiode.tilNorskFormat()}"),
)
}
},
{
auditService.logMedBehandlingId(
behandlingId = behandlingId,
navIdent = saksbehandler.navIdent,
action = AuditLogEvent.Action.ACCESS,
contextMessage = "Oppdaterer vurderingsperioden",
correlationId = correlationId,
)

call.respond(status = HttpStatusCode.OK, it.toDTO())
},
)
}
}
}
}

hentPersonRoute(tokenService, sakService, auditService)
tiltakDeltagelseRoutes(behandlingService, tiltaksdeltagelseVilkårService, auditService, tokenService)
institusjonsoppholdRoutes(behandlingService, auditService, tokenService)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package no.nav.tiltakspenger.vedtak.routes.behandling

import no.nav.tiltakspenger.saksbehandling.domene.behandling.TilleggstekstBrev

enum class SubsumsjonDTO {
TILTAKSDELTAGELSE,
}

internal fun TilleggstekstBrev.Subsumsjon.toDTO(): SubsumsjonDTO {
return when (this) {
TilleggstekstBrev.Subsumsjon.TILTAKSDELTAGELSE -> SubsumsjonDTO.TILTAKSDELTAGELSE
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package no.nav.tiltakspenger.vedtak.routes.behandling

import no.nav.tiltakspenger.saksbehandling.domene.behandling.TilleggstekstBrev

data class TilleggstekstBrevDTO(
val subsumsjon: SubsumsjonDTO,
val tekst: String,
)

fun TilleggstekstBrev.toDTO(): TilleggstekstBrevDTO =
TilleggstekstBrevDTO(
subsumsjon = subsumsjon.toDTO(),
tekst = tekst,
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ object Standardfeil {
"må_være_beslutter_eller_saksbehandler",
)

fun nyPeriodeMåVæreInnenforVurderingsperiode(melding: String = "Ny periode må være innenfor opprinnelig vurderingsperiode"): ErrorJson = ErrorJson(
melding,
"ny_periode_må_være_innenfor_vurderingsperiode",
)

fun behandlingKanIkkeVæreSendtTilBeslutterEllerVedtatt(): ErrorJson = ErrorJson(
"Behandlingen kan ikke være sendt til beslutter eller vedtatt.",
"behandling_kan_ikke_være_til_beslutning_eller_vedtatt",
)

fun saksopplysningsperiodeMåVæreLik(): ErrorJson = ErrorJson(
"Perioden til saksopplysningen er forskjellig fra vurderingsperioden",
"saksopplysningsperiode_må_være_lik",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE behandling ADD COLUMN IF NOT EXISTS tilleggstekst_brev varchar;
Loading

0 comments on commit c885732

Please sign in to comment.