Skip to content

Commit

Permalink
Overstyre sisteAndelPerKjede for utvidet barnetrygd dersom fagsak er …
Browse files Browse the repository at this point in the history
…over på ny klassekode (#4970)

Favro:
[NAV-23733](https://favro.com/organization/98c34fb974ce445eac854de0/1844bbac3b6605eacc8f5543?card=NAV-23733)

### 💰 Hva skal gjøres, og hvorfor?
I revurderinger i fagsaker vi har kjørt `OppdaterUtvidetKlassekodeTask`
for, kommer ikke saksbehandler seg videre fra vilkårsvurdering pga
feilende simulering mot Oppdrag. Dette skyldes hvordan vi utleder
`sisteAndelPerKjede` og at vi etter `OppdaterUtvidetKlassekodeTask` ikke
lenger har ett 1-1 forhold mellom andeler og kjedeelementer for utvidet
barnetrygd.

Andelen i en utvidet barnetrygd behandling strekker seg eksempelvis fra
01.07.23 -> 01.07.33, mens det siste kjedeelementet vi faktisk sendte
til Oppdrag i autovedtaket strakk seg fra 01.01.25 -> 01.07.33. Oppdrag
klager da når vi forsøker å opphøre (som vi alltid gjør i simulering) på
at den ikke kjenner igjen kjedeelementet 01.07.23 -> 01.07.33, fordi den
forventer det siste vi sendte som var 01.01.25 -> 01.07.33.

Som en midlertidig løsning for å ikke hindre saksbehandlere fra å gjøre
revurderinger i fagsaker vi har kjørt jobben
`OppdaterUtvidetKlassekodeTask` for, legger vi her til logikk for å
overstyre den siste andelen for utvidet kjeden med korrekt fom-dato.
Dette gjøres ved å sjekke alle tidligere utbetalingsoppdrag til fagsak
og finne det siste utbetalingsoppdraget som inneholdt den nye
klassekoden for utvidet. Deretter velger vi ut det siste kjedeelementet
for utvidet barnetrygd fra utbetalingsoppdraget basert på `fom`, og
bruker denne `fom`-en i den siste andelen for utvidet kjeden.

> Gjenskapte feilen i preprod og testet at jeg fikk revurdert etter å ha
rullet ut disse endringene

### 🔎️ Er det noe spesielt du ønsker tilbakemelding om?
Selv om dette vil fungere i lang tid, tror jeg det er lurt å tenkte litt
nytt på den automatiske jobben vi kjører for å få fagsaker over på ny
klassekode. Det lureste vil nok være å faktisk opprette en splitt i
andelene slik at vi får tilbake 1-1 forholdet mellom andeler og
kjedeelementer.

### ✅ Checklist
- [x] Jeg har testet mine endringer i henhold til akseptansekriteriene
🕵️
- [ ] Jeg har config- eller sql-endringer.
- [x] Jeg har skrevet tester.

### 💬 Ønsker du en muntlig gjennomgang?
Tar gjerne en muntlig gjennomgang dersom det er enklere.
  • Loading branch information
bragejahren authored Dec 18, 2024
1 parent b824de2 commit 0d556dd
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class FeatureToggleConfig {
// NAV-23449 - Skrud av/på ny refaktorert logikk for hjemler i brev, skal i teorien produsere det samme resultatet
const val BRUK_OMSKRIVING_AV_HJEMLER_I_BREV = "familie-ba-sak.bruk_omskriving_av_hjemler_i_brev"

// NAV-23733
const val BRUK_OVERSTYRING_AV_FOM_SISTE_ANDEL_UTVIDET = "familie-ba-sak.bruk-overstyring-av-fom-siste-andel-utvidet"

// satsendring
// Oppretter satsendring-tasker for de som ikke har fått ny task
const val SATSENDRING_ENABLET: String = "familie-ba-sak.satsendring-enablet"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package no.nav.familie.ba.sak.integrasjoner.økonomi.utbetalingsoppdrag

import no.nav.familie.ba.sak.common.ClockProvider
import no.nav.familie.ba.sak.kjerne.beregning.domene.AndelTilkjentYtelse
import no.nav.familie.ba.sak.kjerne.beregning.domene.TilkjentYtelse
import no.nav.familie.ba.sak.kjerne.fagsak.Fagsak
import no.nav.familie.ba.sak.kjerne.fagsak.FagsakType
import no.nav.familie.ba.sak.kjerne.vedtak.Vedtak
import no.nav.familie.felles.utbetalingsgenerator.domain.AndelDataLongId
import no.nav.familie.felles.utbetalingsgenerator.domain.Behandlingsinformasjon
import no.nav.familie.felles.utbetalingsgenerator.domain.IdentOgType
import org.springframework.stereotype.Component
Expand All @@ -21,7 +21,7 @@ class BehandlingsinformasjonUtleder(
saksbehandlerId: String,
vedtak: Vedtak,
forrigeTilkjentYtelse: TilkjentYtelse?,
sisteAndelPerKjede: Map<IdentOgType, AndelTilkjentYtelse>,
sisteAndelPerKjede: Map<IdentOgType, AndelDataLongId>,
erSimulering: Boolean,
): Behandlingsinformasjon {
val behandling = vedtak.behandling
Expand All @@ -43,7 +43,7 @@ class BehandlingsinformasjonUtleder(

private fun finnOpphørsdatoForAlleKjeder(
forrigeTilkjentYtelse: TilkjentYtelse?,
sisteAndelPerKjede: Map<IdentOgType, AndelTilkjentYtelse>,
sisteAndelPerKjede: Map<IdentOgType, AndelDataLongId>,
endretMigreringsdato: YearMonth?,
): YearMonth? =
if (forrigeTilkjentYtelse == null || sisteAndelPerKjede.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package no.nav.familie.ba.sak.integrasjoner.økonomi.utbetalingsoppdrag

import no.nav.familie.ba.sak.common.toYearMonth
import no.nav.familie.ba.sak.config.FeatureToggleConfig
import no.nav.familie.ba.sak.config.featureToggle.UnleashNextMedContextService
import no.nav.familie.ba.sak.integrasjoner.pdl.logger
import no.nav.familie.ba.sak.kjerne.behandling.BehandlingHentOgPersisterService
import no.nav.familie.ba.sak.kjerne.behandling.domene.Behandling
import no.nav.familie.ba.sak.kjerne.behandling.domene.BehandlingÅrsak
Expand All @@ -14,6 +16,8 @@ import no.nav.familie.felles.utbetalingsgenerator.Utbetalingsgenerator
import no.nav.familie.felles.utbetalingsgenerator.domain.AndelDataLongId
import no.nav.familie.felles.utbetalingsgenerator.domain.BeregnetUtbetalingsoppdragLongId
import no.nav.familie.felles.utbetalingsgenerator.domain.IdentOgType
import no.nav.familie.felles.utbetalingsgenerator.domain.Utbetalingsoppdrag
import no.nav.familie.kontrakter.felles.objectMapper
import org.springframework.stereotype.Component

@Component
Expand Down Expand Up @@ -72,7 +76,7 @@ class UtbetalingsoppdragGenerator(
behandlingsinformasjon = behandlingsinformasjon,
forrigeAndeler = forrigeAndeler,
nyeAndeler = nyeAndeler,
sisteAndelPerKjede = sisteAndelPerKjede.mapValues { it.value.tilAndelDataLongId(skalBrukeNyKlassekodeForUtvidetBarnetrygd) },
sisteAndelPerKjede = sisteAndelPerKjede,
)

return klassifiseringKorrigerer.korrigerKlassifiseringVedBehov(
Expand All @@ -81,15 +85,56 @@ class UtbetalingsoppdragGenerator(
)
}

private fun hentSisteAndelTilkjentYtelse(behandling: Behandling): Map<IdentOgType, AndelTilkjentYtelse> {
private fun hentSisteAndelTilkjentYtelse(
behandling: Behandling,
): Map<IdentOgType, AndelDataLongId> {
val skalBrukeNyKlassekodeForUtvidetBarnetrygd =
unleashNextMedContextService.isEnabled(
toggleId = FeatureToggleConfig.SKAL_BRUKE_NY_KLASSEKODE_FOR_UTVIDET_BARNETRYGD,
behandlingId = behandling.id,
)
return andelTilkjentYtelseRepository
.hentSisteAndelPerIdentOgType(fagsakId = behandling.fagsak.id)
.associateBy { IdentOgType(it.aktør.aktivFødselsnummer(), it.type.tilYtelseType(skalBrukeNyKlassekodeForUtvidetBarnetrygd)) }

val sisteAndelPerKjede =
andelTilkjentYtelseRepository
.hentSisteAndelPerIdentOgType(fagsakId = behandling.fagsak.id)
.associateBy { IdentOgType(it.aktør.aktivFødselsnummer(), it.type.tilYtelseType(skalBrukeNyKlassekodeForUtvidetBarnetrygd)) }

return if (unleashNextMedContextService.isEnabled(FeatureToggleConfig.BRUK_OVERSTYRING_AV_FOM_SISTE_ANDEL_UTVIDET)) {
overstyrSisteUtvidetBarnetrygdAndel(behandling, sisteAndelPerKjede, skalBrukeNyKlassekodeForUtvidetBarnetrygd)
} else {
sisteAndelPerKjede.mapValues { it.value.tilAndelDataLongId(skalBrukeNyKlassekodeForUtvidetBarnetrygd) }
}
}

private fun overstyrSisteUtvidetBarnetrygdAndel(
behandling: Behandling,
sisteAndelPerKjede: Map<IdentOgType, AndelTilkjentYtelse>,
skalBrukeNyKlassekodeForUtvidetBarnetrygd: Boolean,
): Map<IdentOgType, AndelDataLongId> {
val tilkjenteYtelserMedOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag = tilkjentYtelseRepository.findByOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag(behandling.fagsak.id)
return sisteAndelPerKjede.mapValues { (identOgType, sisteAndelIKjede) ->
if (tilkjenteYtelserMedOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag.isNotEmpty() && identOgType.type == YtelsetypeBA.UTVIDET_BARNETRYGD) {
// Finner siste utbetalingsoppdraget som innehold kjedelementer med oppdatert utvidet klassekode
val sisteTilkjenteYtelseMedOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag = tilkjenteYtelserMedOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag.maxBy { tilkjentYtelse -> tilkjentYtelse.behandling.aktivertTidspunkt }

// Finner det siste kjedelementet med oppdatert utvidet klassekode
val sistOversendteUtvidetBarnetrygdKjedeelement =
objectMapper
.readValue(sisteTilkjenteYtelseMedOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag.utbetalingsoppdrag, Utbetalingsoppdrag::class.java)
.utbetalingsperiode
.single { utbetalingsperiode -> utbetalingsperiode.periodeId == sisteAndelIKjede.periodeOffset && utbetalingsperiode.klassifisering == YtelsetypeBA.UTVIDET_BARNETRYGD.klassifisering }

if (sisteAndelIKjede.stønadFom != sistOversendteUtvidetBarnetrygdKjedeelement.vedtakdatoFom.toYearMonth()) {
logger.warn("Overstyrer vedtakFom i andelDataLongId da fom til siste andel per kjede ikke stemmer overens med siste kjedelement oversendt til Oppdrag")
// Oppdaterer fom i AndelDataLongId til samme fom som sist oversendte, da det ikke er 1-1 mellom fom på siste andel og fom på siste kjedelement oversendt til Oppdrag.
sisteAndelIKjede.tilAndelDataLongId(skalBrukeNyKlassekodeForUtvidetBarnetrygd).copy(fom = sistOversendteUtvidetBarnetrygdKjedeelement.vedtakdatoFom.toYearMonth())
} else {
sisteAndelIKjede.tilAndelDataLongId(skalBrukeNyKlassekodeForUtvidetBarnetrygd)
}
} else {
sisteAndelIKjede.tilAndelDataLongId(skalBrukeNyKlassekodeForUtvidetBarnetrygd)
}
}
}

private fun hentForrigeTilkjentYtelse(behandling: Behandling): TilkjentYtelse? =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,13 @@ interface TilkjentYtelseRepository : JpaRepository<TilkjentYtelse, Long> {
""",
)
fun harFagsakTattIBrukNyKlassekodeForUtvidetBarnetrygd(fagsakId: Long): Boolean

@Query(
"""
SELECT ty FROM Behandling b
JOIN TilkjentYtelse ty ON ty.behandling.id = b.id
WHERE ty.utbetalingsoppdrag IS NOT NULL AND ty.utbetalingsoppdrag like '%"klassifisering":"BAUTV-OP"%' AND b.fagsak.id = :fagsakId
""",
)
fun findByOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag(fagsakId: Long): List<TilkjentYtelse>
}
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ class BehandlingsinformasjonUtlederTest {

val sisteAndelPerKjede =
mapOf(
IdentOgType("1", YtelsetypeBA.ORDINÆR_BARNETRYGD) to lagAndelTilkjentYtelse,
IdentOgType("1", YtelsetypeBA.ORDINÆR_BARNETRYGD) to lagAndelTilkjentYtelse.tilAndelDataLongId(true),
)

every {
Expand Down Expand Up @@ -311,7 +311,7 @@ class BehandlingsinformasjonUtlederTest {

val sisteAndelPerKjede =
mapOf(
IdentOgType("1", YtelsetypeBA.ORDINÆR_BARNETRYGD) to lagAndelTilkjentYtelse,
IdentOgType("1", YtelsetypeBA.ORDINÆR_BARNETRYGD) to lagAndelTilkjentYtelse.tilAndelDataLongId(true),
)

every {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ class UtbetalingsoppdragGeneratorTest {
)
} returns true

every {
unleashNextMedContextService.isEnabled(
toggleId = FeatureToggleConfig.BRUK_OVERSTYRING_AV_FOM_SISTE_ANDEL_UTVIDET,
)
} returns true

every {
klassifiseringKorrigerer.korrigerKlassifiseringVedBehov(
beregnetUtbetalingsoppdrag = any(),
Expand All @@ -120,6 +126,8 @@ class UtbetalingsoppdragGeneratorTest {
firstArg()
}

every { tilkjentYtelseRepository.findByOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag(any()) } returns emptyList()

// Act
val beregnetUtbetalingsoppdragLongId =
utbetalingsoppdragGenerator.lagUtbetalingsoppdrag(
Expand Down Expand Up @@ -234,6 +242,12 @@ class UtbetalingsoppdragGeneratorTest {
)
} returns true

every {
unleashNextMedContextService.isEnabled(
toggleId = FeatureToggleConfig.BRUK_OVERSTYRING_AV_FOM_SISTE_ANDEL_UTVIDET,
)
} returns true

every {
klassifiseringKorrigerer.korrigerKlassifiseringVedBehov(
beregnetUtbetalingsoppdrag = any(),
Expand All @@ -243,6 +257,8 @@ class UtbetalingsoppdragGeneratorTest {
firstArg()
}

every { tilkjentYtelseRepository.findByOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag(any()) } returns emptyList()

// Act
val beregnetUtbetalingsoppdragLongId =
utbetalingsoppdragGenerator.lagUtbetalingsoppdrag(
Expand Down Expand Up @@ -359,6 +375,12 @@ class UtbetalingsoppdragGeneratorTest {
)
} returns true

every {
unleashNextMedContextService.isEnabled(
toggleId = FeatureToggleConfig.BRUK_OVERSTYRING_AV_FOM_SISTE_ANDEL_UTVIDET,
)
} returns true

every {
klassifiseringKorrigerer.korrigerKlassifiseringVedBehov(
beregnetUtbetalingsoppdrag = any(),
Expand All @@ -383,6 +405,8 @@ class UtbetalingsoppdragGeneratorTest {
kildeBehandlingId = null,
),
)

every { tilkjentYtelseRepository.findByOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag(any()) } returns emptyList()
// Act
val beregnetUtbetalingsoppdragLongId =
utbetalingsoppdragGenerator.lagUtbetalingsoppdrag(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import no.nav.familie.ba.sak.integrasjoner.økonomi.utbetalingsoppdrag.Behandlin
import no.nav.familie.ba.sak.integrasjoner.økonomi.utbetalingsoppdrag.EndretMigreringsdatoUtleder
import no.nav.familie.ba.sak.integrasjoner.økonomi.utbetalingsoppdrag.KlassifiseringKorrigerer
import no.nav.familie.ba.sak.integrasjoner.økonomi.utbetalingsoppdrag.UtbetalingsoppdragGenerator
import no.nav.familie.ba.sak.integrasjoner.økonomi.utbetalingsoppdrag.YtelsetypeBA
import no.nav.familie.ba.sak.integrasjoner.økonomi.utbetalingsoppdrag.tilRestUtbetalingsoppdrag
import no.nav.familie.ba.sak.kjerne.behandling.BehandlingHentOgPersisterService
import no.nav.familie.ba.sak.kjerne.behandling.BehandlingService
Expand All @@ -43,6 +44,7 @@ import no.nav.familie.ba.sak.kjerne.beregning.domene.TilkjentYtelse
import no.nav.familie.ba.sak.kjerne.beregning.domene.TilkjentYtelseRepository
import no.nav.familie.felles.utbetalingsgenerator.Utbetalingsgenerator
import no.nav.familie.felles.utbetalingsgenerator.domain.BeregnetUtbetalingsoppdragLongId
import no.nav.familie.kontrakter.felles.objectMapper
import no.nav.familie.kontrakter.felles.oppdrag.Utbetalingsoppdrag
import no.nav.familie.kontrakter.felles.oppdrag.Utbetalingsperiode
import org.assertj.core.api.Assertions.assertThat
Expand Down Expand Up @@ -174,7 +176,10 @@ class OppdragSteg {
} returns tidligereTilkjenteYtelser.lastOrNull()?.behandling
every {
tilkjentYtelseRepository.findByBehandlingAndHasUtbetalingsoppdrag(any())
} returns tidligereTilkjenteYtelser.lastOrNull()
} returns tidligereTilkjenteYtelser.lastOrNull()?.copy(utbetalingsoppdrag = objectMapper.writeValueAsString(beregnetUtbetalingsoppdrag[tidligereTilkjenteYtelser.last().behandling.id]?.utbetalingsoppdrag))
every {
tilkjentYtelseRepository.findByOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag(any())
} returns tidligereTilkjenteYtelser.filter { beregnetUtbetalingsoppdrag[it.behandling.id]?.utbetalingsoppdrag?.utbetalingsperiode?.any { it.klassifisering == YtelsetypeBA.UTVIDET_BARNETRYGD.klassifisering } == true }.map { it.copy(utbetalingsoppdrag = objectMapper.writeValueAsString(beregnetUtbetalingsoppdrag[it.behandling.id]?.utbetalingsoppdrag)) }
every {
behandlingHentOgPersisterService.hentBehandlinger(any())
} returns behandlinger.filter { it.value.fagsak.id == tilkjentYtelse.behandling.fagsak.id }.values.toList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,10 @@ fun mockTilkjentYtelseRepository(dataFraCucumber: VedtaksperioderOgBegrunnelserS
.mapNotNull { it.utbetalingsoppdrag }
.any { it.contains("\"klassifisering\":\"BAUTV-OP\"") }
}

every { tilkjentYtelseRepository.findByOppdatertUtvidetBarnetrygdKlassekodeIUtbetalingsoppdrag(any()) } answers {
val fagsakId = firstArg<Long>()
dataFraCucumber.tilkjenteYtelser.map { it.value }.filter { it.utbetalingsoppdrag != null && it.utbetalingsoppdrag!!.contains("\"klassifisering\":\"BAUTV-OP\"") }
}
return tilkjentYtelseRepository
}
Loading

0 comments on commit 0d556dd

Please sign in to comment.