Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Oppdater kravgrunnlag tilbakekreving #1566

Merged
merged 5 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import tilbakekreving.application.service.forhåndsvarsel.ForhåndsvarsleTilbake
import tilbakekreving.application.service.forhåndsvarsel.ForhåndsvisForhåndsvarselTilbakekrevingsbehandlingService
import tilbakekreving.application.service.forhåndsvarsel.VisUtsendtForhåndsvarselbrevForTilbakekrevingService
import tilbakekreving.application.service.iverksett.IverksettTilbakekrevingService
import tilbakekreving.application.service.kravgrunnlag.OppdaterKravgrunnlagService
import tilbakekreving.application.service.opprett.OpprettTilbakekrevingsbehandlingService
import tilbakekreving.application.service.tilAttestering.TilbakekrevingsbehandlingTilAttesteringService
import tilbakekreving.application.service.underkjenn.UnderkjennTilbakekrevingsbehandlingService
Expand Down Expand Up @@ -178,4 +179,10 @@ class TilbakekrevingServices(
sessionFactory = sessionFactory,
clock = clock,
),
val oppdaterKravgrunnlagService: OppdaterKravgrunnlagService = OppdaterKravgrunnlagService(
tilgangstyring = tilgangstyringService,
sakService = sakService,
tilbakekrevingsbehandlingRepo = tilbakekrevingsbehandlingRepo,
clock = clock,
),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package tilbakekreving.application.service.kravgrunnlag

import arrow.core.Either
import arrow.core.getOrElse
import arrow.core.left
import arrow.core.right
import no.nav.su.se.bakover.domain.sak.SakService
import org.slf4j.LoggerFactory
import tilbakekreving.application.service.common.TilbakekrevingsbehandlingTilgangstyringService
import tilbakekreving.domain.KanOppdatereKravgrunnlag
import tilbakekreving.domain.kravgrunnlag.KunneIkkeOppdatereKravgrunnlag
import tilbakekreving.domain.kravgrunnlag.OppdaterKravgrunnlagCommand
import tilbakekreving.domain.opprett.TilbakekrevingsbehandlingRepo
import java.time.Clock

class OppdaterKravgrunnlagService(
private val tilgangstyring: TilbakekrevingsbehandlingTilgangstyringService,
private val sakService: SakService,
private val tilbakekrevingsbehandlingRepo: TilbakekrevingsbehandlingRepo,
private val clock: Clock,
) {

private val log = LoggerFactory.getLogger(this::class.java)

fun oppdater(command: OppdaterKravgrunnlagCommand): Either<KunneIkkeOppdatereKravgrunnlag, KanOppdatereKravgrunnlag> {
tilgangstyring.assertHarTilgangTilSak(command.sakId).onLeft {
return KunneIkkeOppdatereKravgrunnlag.IkkeTilgang(it).left()
}
val sak = sakService.hentSak(command.sakId).getOrElse {
throw IllegalStateException("Kunne ikke oppdatere kravgrunnlag for tilbakekrevingsbehandling, fant ikke sak. Command: $command")
}
if (sak.versjon != command.klientensSisteSaksversjon) {
log.info("Oppdater kravgrunnlag - Sakens versjon (${sak.versjon}) er ulik saksbehandlers versjon. Command: $command")
}

val behandling = (
sak.behandlinger.tilbakekrevinger.hent(command.behandlingId)
?: throw IllegalStateException("Kunne ikke oppdatere kravgrunnlag for tilbakekrevingsbehandling. Fant ikke Tilbakekrevingsbehandling ${command.behandlingId}. Command: $command")
).let {
it as? KanOppdatereKravgrunnlag
?: throw IllegalStateException("Kunne ikke oppdatere kravgrunnlag for tilbakekrevingsbehandling ${command.behandlingId}, behandlingen er ikke i riktig tilstand. Command: $command")
}

val uteståendeKravgrunnlag =
sak.uteståendeKravgrunnlag ?: return KunneIkkeOppdatereKravgrunnlag.FantIkkeUteståendeKravgrunnlag.left()
.also {
log.error("Fant ikke utestående kravgrunnlag for å oppdatere kravgrunnlag på tilbakekrevingsbehandling ${command.behandlingId} for sak ${command.sakId}")
}

return behandling.oppdaterKravgrunnlag(
command = command,
nesteVersjon = sak.versjon.inc(),
nyttKravgrunnlag = uteståendeKravgrunnlag,
clock = clock,
).let {
tilbakekrevingsbehandlingRepo.lagre(it.first)
it.second.right()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class OpprettTilbakekrevingsbehandlingService(
forrigeVersjon = sak.versjon,
clock = clock,
kravgrunnlag = k,
erKravgrunnlagUtdatert = false,
).let { (hendelse, behandling) ->
tilbakekrevingsbehandlingRepo.lagre(hendelse)
behandling.right()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ sealed interface Tilbakekrevingsbehandling {
val opprettet: Tidspunkt
val opprettetAv: NavIdentBruker.Saksbehandler
val kravgrunnlag: Kravgrunnlag
val erKravgrunnlagUtdatert: Boolean
val månedsvurderinger: Vurderinger?
val vedtaksbrevvalg: Brevvalg.SaksbehandlersValg?
val attesteringer: Attesteringshistorikk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,16 @@ data class TilbakekrevingsbehandlingHendelser private constructor(
val hendelseId = hendelse.hendelseId
when (hendelse) {
// Dette gjelder kun første hendelsen og er et spesialtilfelle.
is OpprettetTilbakekrevingsbehandlingHendelse -> acc.plus(
hendelseId to hendelse.toDomain(
kravgrunnlagPåSakHendelse = this.kravgrunnlagPåSak.hentKravgrunnlagDetaljerPåSakHendelseForEksternKravgrunnlagId(hendelse.kravgrunnlagsId)!!,
),
)
is OpprettetTilbakekrevingsbehandlingHendelse -> {
val kravgrunnlagsDetalje = this.kravgrunnlagPåSak.hentKravgrunnlagDetaljerPåSakHendelseForEksternKravgrunnlagId(hendelse.kravgrunnlagsId)!!

acc.plus(
hendelseId to hendelse.toDomain(
kravgrunnlagPåSakHendelse = kravgrunnlagsDetalje,
erKravgrunnlagUtdatert = this.kravgrunnlagPåSak.hentUteståendeKravgrunnlag() != kravgrunnlagsDetalje.kravgrunnlag,
),
)
}

else -> acc.plus(
hendelseId to hendelse.applyToState(acc[hendelse.tidligereHendelseId!!]!!),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@file:Suppress("PackageDirectoryMismatch")
// Må ligge i samme pakke som Tilbakekrevingsbehandling (siden det er et sealed interface), men trenger ikke ligge i samme mappe.

package tilbakekreving.domain

import no.nav.su.se.bakover.common.tid.Tidspunkt
import no.nav.su.se.bakover.hendelse.domain.HendelseId
import no.nav.su.se.bakover.hendelse.domain.Hendelsesversjon
import tilbakekreving.domain.kravgrunnlag.Kravgrunnlag
import tilbakekreving.domain.kravgrunnlag.OppdaterKravgrunnlagCommand
import java.lang.IllegalStateException
import java.time.Clock

sealed interface KanOppdatereKravgrunnlag : KanEndres {
override val kravgrunnlag: Kravgrunnlag
override val erKravgrunnlagUtdatert: Boolean

fun oppdaterKravgrunnlag(
command: OppdaterKravgrunnlagCommand,
nesteVersjon: Hendelsesversjon,
nyttKravgrunnlag: Kravgrunnlag,
clock: Clock,
): Pair<OppdatertKravgrunnlagPåTilbakekrevingHendelse, UnderBehandling.Påbegynt> {
if (this.kravgrunnlag.eksternKravgrunnlagId == nyttKravgrunnlag.eksternKravgrunnlagId) {
throw IllegalStateException("Prøvde å oppdatere kravgrunnlag for behandling ${this.id}, men kravgrunnlags-id'en er lik")
}

val hendelse = OppdatertKravgrunnlagPåTilbakekrevingHendelse(
hendelseId = HendelseId.generer(),
sakId = command.sakId,
hendelsestidspunkt = Tidspunkt.now(clock),
versjon = nesteVersjon,
tidligereHendelseId = this.hendelseId,
meta = command.toDefaultHendelsesMetadata(),
id = command.behandlingId,
utførtAv = command.oppdatertAv,
oppdatertKravgrunnlag = nyttKravgrunnlag,
)
return hendelse to hendelse.applyToState(this)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package tilbakekreving.domain.kravgrunnlag

data class KravgrunnlagPåSakHendelser(
val hendelser: List<KravgrunnlagPåSakHendelse>,
private val hendelser: List<KravgrunnlagPåSakHendelse>,
) : List<KravgrunnlagPåSakHendelse> by hendelser {

val detaljerSortert = hendelser
Expand All @@ -15,6 +15,9 @@ data class KravgrunnlagPåSakHendelser(
.filterIsInstance<KravgrunnlagStatusendringPåSakHendelse>()
.sortedBy { it.eksternTidspunkt.instant }

/**
* TODO - må ta stilling til om den er svart på
*/
fun hentUteståendeKravgrunnlag(): Kravgrunnlag? {
return detaljerSortert
.map { it.kravgrunnlag }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package tilbakekreving.domain.kravgrunnlag

import tilbakekreving.domain.IkkeTilgangTilSak

sealed interface KunneIkkeOppdatereKravgrunnlag {
data class IkkeTilgang(val underliggende: IkkeTilgangTilSak) : KunneIkkeOppdatereKravgrunnlag
data object FantIkkeUteståendeKravgrunnlag : KunneIkkeOppdatereKravgrunnlag
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package tilbakekreving.domain.kravgrunnlag

import no.nav.su.se.bakover.common.CorrelationId
import no.nav.su.se.bakover.common.brukerrolle.Brukerrolle
import no.nav.su.se.bakover.common.ident.NavIdentBruker
import no.nav.su.se.bakover.hendelse.domain.Hendelsesversjon
import no.nav.su.se.bakover.hendelse.domain.SakshendelseCommand
import tilbakekreving.domain.TilbakekrevingsbehandlingId
import java.util.UUID

data class OppdaterKravgrunnlagCommand(
override val sakId: UUID,
override val correlationId: CorrelationId?,
override val brukerroller: List<Brukerrolle>,
val oppdatertAv: NavIdentBruker.Saksbehandler,
val behandlingId: TilbakekrevingsbehandlingId,
val klientensSisteSaksversjon: Hendelsesversjon,
) : SakshendelseCommand {
override val ident: NavIdentBruker = oppdatertAv
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@file:Suppress("PackageDirectoryMismatch")
// Må ligge i samme pakke som TilbakekrevingsbehandlingHendelse (siden det er et sealed interface), men trenger ikke ligge i samme mappe.

package tilbakekreving.domain

import no.nav.su.se.bakover.common.ident.NavIdentBruker
import no.nav.su.se.bakover.common.tid.Tidspunkt
import no.nav.su.se.bakover.hendelse.domain.DefaultHendelseMetadata
import no.nav.su.se.bakover.hendelse.domain.HendelseId
import no.nav.su.se.bakover.hendelse.domain.Hendelsesversjon
import no.nav.su.se.bakover.hendelse.domain.Sakshendelse
import tilbakekreving.domain.kravgrunnlag.Kravgrunnlag
import java.util.UUID

data class OppdatertKravgrunnlagPåTilbakekrevingHendelse(
override val hendelseId: HendelseId,
override val sakId: UUID,
override val hendelsestidspunkt: Tidspunkt,
override val versjon: Hendelsesversjon,
override val meta: DefaultHendelseMetadata,
override val tidligereHendelseId: HendelseId,
override val id: TilbakekrevingsbehandlingId,
override val utførtAv: NavIdentBruker.Saksbehandler,
val oppdatertKravgrunnlag: Kravgrunnlag,
) : TilbakekrevingsbehandlingHendelse {
override val entitetId: UUID = sakId
override fun compareTo(other: Sakshendelse): Int {
require(this.entitetId == other.entitetId && this.sakId == other.sakId)
return this.versjon.compareTo(other.versjon)
}

override fun applyToState(behandling: Tilbakekrevingsbehandling): UnderBehandling.Påbegynt {
return when (behandling) {
is TilbakekrevingsbehandlingTilAttestering,
is AvbruttTilbakekrevingsbehandling,
is IverksattTilbakekrevingsbehandling,
-> throw IllegalArgumentException("Tilstandene [Avbrutt, Iverksatt, TilAttestering] kan ikke oppdatere kravgrunnlag. Hendelse ${this.hendelseId}, for sak ${this.sakId} ")

is KanOppdatereKravgrunnlag -> UnderBehandling.Påbegynt(
forrigeSteg = behandling,
hendelseId = hendelseId,
versjon = versjon,
månedsvurderinger = behandling.månedsvurderinger,
forhåndsvarselsInfo = behandling.forhåndsvarselsInfo,
vedtaksbrevvalg = behandling.vedtaksbrevvalg,
kravgrunnlag = oppdatertKravgrunnlag,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ fun opprettTilbakekrevingsbehandling(
forrigeVersjon: Hendelsesversjon,
clock: Clock,
kravgrunnlag: Kravgrunnlag,
erKravgrunnlagUtdatert: Boolean,
): Pair<OpprettetTilbakekrevingsbehandlingHendelse, OpprettetTilbakekrevingsbehandling> {
return OpprettetTilbakekrevingsbehandlingHendelse.opprett(
sakId = command.sakId,
Expand All @@ -26,6 +27,6 @@ fun opprettTilbakekrevingsbehandling(
// TODO jah: Denne bør byttes med en intern id, men da må vi migrere eksisterende kravgrunnlag knyttet til sak i produksjon.
eksternKravgrunnlagId = kravgrunnlag.eksternKravgrunnlagId,
).let {
it to it.toDomain(kravgrunnlag)
it to it.toDomain(kravgrunnlag, erKravgrunnlagUtdatert)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ data class OpprettetTilbakekrevingsbehandling(
override val kravgrunnlag: Kravgrunnlag,
override val versjon: Hendelsesversjon,
override val hendelseId: HendelseId,
) : KanForhåndsvarsle, KanVurdere {
override val erKravgrunnlagUtdatert: Boolean,
) : KanForhåndsvarsle, KanVurdere, KanOppdatereKravgrunnlag {

override val attesteringer: Attesteringshistorikk = Attesteringshistorikk.empty()
override val forhåndsvarselsInfo: List<ForhåndsvarselMetaInfo> = emptyList()
Expand All @@ -40,6 +41,7 @@ data class OpprettetTilbakekrevingsbehandling(
versjon = versjon,
månedsvurderinger = this.månedsvurderinger,
forhåndsvarselsInfo = listOf(ForhåndsvarselMetaInfo(dokumentId, hendelsesTidspunkt)),
kravgrunnlag = kravgrunnlag,
)

override fun leggTilVurderinger(
Expand All @@ -52,6 +54,7 @@ data class OpprettetTilbakekrevingsbehandling(
månedsvurderinger = månedsvurderinger,
forhåndsvarselsInfo = listOf(),
versjon = versjon,
kravgrunnlag = kravgrunnlag,
)

override val månedsvurderinger: Vurderinger? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ data class OpprettetTilbakekrevingsbehandlingHendelse(
throw IllegalArgumentException("En tilbakekrevingsbehandling kan kun starte med en Opprettet hendelse ${this.hendelseId}, for sak ${this.sakId} ")
}

fun toDomain(kravgrunnlagPåSakHendelse: KravgrunnlagDetaljerPåSakHendelse): OpprettetTilbakekrevingsbehandling {
return toDomain(kravgrunnlagPåSakHendelse.kravgrunnlag)
fun toDomain(kravgrunnlagPåSakHendelse: KravgrunnlagDetaljerPåSakHendelse, erKravgrunnlagUtdatert: Boolean): OpprettetTilbakekrevingsbehandling {
return toDomain(kravgrunnlagPåSakHendelse.kravgrunnlag, erKravgrunnlagUtdatert)
}

fun toDomain(kravgrunnlag: Kravgrunnlag): OpprettetTilbakekrevingsbehandling {
fun toDomain(kravgrunnlag: Kravgrunnlag, erKravgrunnlagUtdatert: Boolean): OpprettetTilbakekrevingsbehandling {
require(kravgrunnlag.eksternKravgrunnlagId == this.kravgrunnlagsId)
return OpprettetTilbakekrevingsbehandling(
id = id,
Expand All @@ -82,6 +82,7 @@ data class OpprettetTilbakekrevingsbehandlingHendelse(
kravgrunnlag = kravgrunnlag,
versjon = versjon,
hendelseId = hendelseId,
erKravgrunnlagUtdatert = erKravgrunnlagUtdatert,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import no.nav.su.se.bakover.common.tid.Tidspunkt
import no.nav.su.se.bakover.hendelse.domain.HendelseId
import no.nav.su.se.bakover.hendelse.domain.Hendelsesversjon
import tilbakekreving.domain.forhåndsvarsel.ForhåndsvarselMetaInfo
import tilbakekreving.domain.kravgrunnlag.Kravgrunnlag
import tilbakekreving.domain.vurdert.Vurderinger
import java.util.UUID

Expand All @@ -22,7 +23,12 @@ import java.util.UUID
* 1. Iverksett eller underkjenn
*
*/
sealed interface UnderBehandling : KanLeggeTilBrev, KanVurdere, KanForhåndsvarsle, UnderBehandlingEllerTilAttestering {
sealed interface UnderBehandling :
KanOppdatereKravgrunnlag,
KanLeggeTilBrev,
KanVurdere,
KanForhåndsvarsle,
UnderBehandlingEllerTilAttestering {

override val månedsvurderinger: Vurderinger?
override fun erÅpen() = true
Expand All @@ -44,8 +50,9 @@ sealed interface UnderBehandling : KanLeggeTilBrev, KanVurdere, KanForhåndsvars
override val versjon: Hendelsesversjon,
override val månedsvurderinger: Vurderinger?,
override val forhåndsvarselsInfo: List<ForhåndsvarselMetaInfo>,
override val vedtaksbrevvalg: Brevvalg.SaksbehandlersValg? = null,
override val kravgrunnlag: Kravgrunnlag,
) : UnderBehandling, KanEndres by forrigeSteg {
override val vedtaksbrevvalg: Brevvalg.SaksbehandlersValg? = null
override val attesteringer: Attesteringshistorikk = Attesteringshistorikk.empty()

// Behandlingen må være utfylt før man kan attestere/underkjenne.
Expand Down
Loading