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

Ta i bruk tidslinje fra familie-felles i VilkårsvurderingTidslinjer #5075

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -6,6 +6,8 @@ import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.Dag
import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.DagTidspunkt.Companion.tilTidspunktEllerUendeligSent
import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.DagTidspunkt.Companion.tilTidspunktEllerUendeligTidlig
import no.nav.familie.ba.sak.kjerne.vilkårsvurdering.domene.VilkårResultat
import no.nav.familie.tidslinje.tilTidslinje
import no.nav.familie.tidslinje.Periode as FamilieFellesPeriode

/**
* Lager tidslinje av VilkårRegelverkResultat for ett vilkår og én aktør
Expand Down Expand Up @@ -36,3 +38,21 @@ fun VilkårResultat.tilPeriode(): Periode<VilkårRegelverkResultat, Dag> {
),
)
}

fun Iterable<VilkårResultat>.tilVilkårRegelverkResultatTidslinjeFamilieFelles() =
this
.filter { it.erOppfylt() }
.map { it.tilPeriodeNy() }
.tilTidslinje()

private fun VilkårResultat.tilPeriodeNy(): FamilieFellesPeriode<VilkårRegelverkResultat> =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Antar dette skal endres på sikt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ja, navnene på noen av duplikatfunksjonene må være forskjellig pga jvm signature som blir like >.< Mente egentlig å bruke FamilieFelles i navnet, i stedet for Ny

FamilieFellesPeriode(
verdi =
VilkårRegelverkResultat(
vilkår = vilkårType,
regelverkResultat = this.tilRegelverkResultat(),
utdypendeVilkårsvurderinger = this.utdypendeVilkårsvurderinger,
),
fom = periodeFom,
tom = periodeTom,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package no.nav.familie.ba.sak.kjerne.eøs.vilkårsvurdering
import no.nav.familie.ba.sak.kjerne.tidslinje.Tidslinje
import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.Dag
import no.nav.familie.ba.sak.kjerne.tidslinje.transformasjon.tilMånedFraMånedsskifteIkkeNull
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.transformasjon.tilMånedFraMånedsskifteIkkeNull
import no.nav.familie.tidslinje.Tidslinje as FamilieFellesTidslinje

/**
* Extension-funksjon som konverterer en dag-basert tidslinje til en måned-basert tidslinje med VilkårRegelverkResultat
Expand All @@ -24,3 +26,9 @@ fun Tidslinje<VilkårRegelverkResultat, Dag>.tilMånedsbasertTidslinjeForVilkår
.tilMånedFraMånedsskifteIkkeNull { sisteDagForrigeMåned, førsteDagDenneMåned ->
if (sisteDagForrigeMåned.erOppfylt() && førsteDagDenneMåned.erOppfylt()) førsteDagDenneMåned else null
}

fun FamilieFellesTidslinje<VilkårRegelverkResultat>.tilMånedsbasertTidslinjeForVilkårRegelverkResultat() =
this
.tilMånedFraMånedsskifteIkkeNull { sisteDagForrigeMåned, førsteDagDenneMåned ->
if (sisteDagForrigeMåned.erOppfylt() && førsteDagDenneMåned.erOppfylt()) førsteDagDenneMåned else null
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.Dag
import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.Måned
import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.Tidsenhet
import no.nav.familie.ba.sak.kjerne.tidslinje.transformasjon.beskjærEtter
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.komposisjon.kombinerUtenNull
import no.nav.familie.ba.sak.kjerne.vilkårsvurdering.domene.VilkårResultat
import no.nav.familie.ba.sak.kjerne.vilkårsvurdering.domene.Vilkårsvurdering
import no.nav.familie.tidslinje.beskjærEtter
import no.nav.familie.tidslinje.inneholder
import no.nav.familie.tidslinje.utvidelser.kombinerMed
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.komposisjon.erUnder18ÅrVilkårTidslinje as familieFellesErUnder18ÅrVilkårTidslinje
import no.nav.familie.tidslinje.Tidslinje as FamilieFellesTidslinje

class VilkårsvurderingTidslinjer(
vilkårsvurdering: Vilkårsvurdering,
Expand Down Expand Up @@ -142,3 +149,107 @@ private fun VilkårsvurderingTidslinjer.søkerHarNasjonalOgFinnesBarnMedEøs():
}

fun <I, T : Tidsenhet> Tidslinje<I, T>.inneholder(innhold: I): Boolean = this.perioder().any { it.innhold == innhold }

// TODO: Endre navn til VilkårsvurderingTidslinjer når den andre klassen er slettet
class VilkårsvurderingFamilieFellesTidslinjer(
vilkårsvurdering: Vilkårsvurdering,
søkerOgBarn: List<PersonEnkel>,
) {
private val barna: List<PersonEnkel> = søkerOgBarn.barn()
private val søker: Aktør = søkerOgBarn.søker().aktør

private val søkersTidslinje: SøkersTidslinjer =
SøkersTidslinjer(
vilkårResultater = vilkårsvurdering.hentPersonResultaterTil(søker.aktørId),
fagsakType = vilkårsvurdering.behandling.fagsak.type,
behandlingUnderkategori = vilkårsvurdering.behandling.underkategori,
)

private val barnasTidslinjer: Map<Aktør, BarnetsTidslinjer> =
barna.associate {
it.aktør to
BarnetsTidslinjer(
barn = it,
vilkårResultater = vilkårsvurdering.hentPersonResultaterTil(it.aktør.aktørId),
søkersRegelverkResultatTidslinje = søkersTidslinje.regelverkResultatTidslinje,
fagsakType = vilkårsvurdering.behandling.fagsak.type,
behandlingUnderkategori = vilkårsvurdering.behandling.underkategori,
)
}

fun søkersTidslinje(): SøkersTidslinjer = søkersTidslinje

fun barnasTidslinjer(): Map<Aktør, BarnetsTidslinjer> = barnasTidslinjer

class SøkersTidslinjer(
vilkårResultater: List<VilkårResultat>,
fagsakType: FagsakType,
behandlingUnderkategori: BehandlingUnderkategori,
) {
val vilkårsresultatTidslinjer =
vilkårResultater
.groupBy { it.vilkårType }
.map { it.value.tilVilkårRegelverkResultatTidslinjeFamilieFelles() }

val regelverkResultatTidslinje =
vilkårsresultatTidslinjer
.map { it.tilMånedsbasertTidslinjeForVilkårRegelverkResultat() }
.kombinerUtenNull {
kombinerVilkårResultaterTilRegelverkResultat(
personType = PersonType.SØKER,
alleVilkårResultater = it,
fagsakType = fagsakType,
behandlingUnderkategori = behandlingUnderkategori,
)
}
}

class BarnetsTidslinjer(
barn: PersonEnkel,
vilkårResultater: List<VilkårResultat>,
søkersRegelverkResultatTidslinje: FamilieFellesTidslinje<RegelverkResultat>,
fagsakType: FagsakType,
behandlingUnderkategori: BehandlingUnderkategori,
) {
val erUnder18ÅrVilkårTidslinje = familieFellesErUnder18ÅrVilkårTidslinje(barn.fødselsdato)

val vilkårsresultatTidslinjer =
vilkårResultater
.groupBy { it.vilkårType }
.map { it.value.tilVilkårRegelverkResultatTidslinjeFamilieFelles() }

val egetRegelverkResultatTidslinje: FamilieFellesTidslinje<RegelverkResultat> =
vilkårsresultatTidslinjer
.map { it.tilMånedsbasertTidslinjeForVilkårRegelverkResultat() }
.kombinerUtenNull {
kombinerVilkårResultaterTilRegelverkResultat(
personType = PersonType.BARN,
alleVilkårResultater = it,
fagsakType = fagsakType,
behandlingUnderkategori = behandlingUnderkategori,
)
}.beskjærEtter(erUnder18ÅrVilkårTidslinje)

val regelverkResultatTidslinje =
egetRegelverkResultatTidslinje
.kombinerMed(søkersRegelverkResultatTidslinje) { barnetsResultat, søkersResultat ->
barnetsResultat.kombinerMed(søkersResultat)
}
// Barnets egne tidslinjer kan på dette tidspunktet strekke seg 18 år frem i tid,
// og mye lenger enn søkers regelverk-tidslinje, som skal være begrensningen. Derfor beskjærer vi mot den
.beskjærEtter(søkersRegelverkResultatTidslinje)
}

fun harBlandetRegelverk(): Boolean =
søkerHarNasjonalOgFinnesBarnMedEøs() ||
søkersTidslinje().regelverkResultatTidslinje.inneholder(RegelverkResultat.OPPFYLT_BLANDET_REGELVERK) ||
barnasTidslinjer().values.any { it.egetRegelverkResultatTidslinje.inneholder(RegelverkResultat.OPPFYLT_BLANDET_REGELVERK) }

private fun søkerHarNasjonalOgFinnesBarnMedEøs(): Boolean =
barnasTidslinjer().values.any {
it.egetRegelverkResultatTidslinje
.kombinerMed(søkersTidslinje().regelverkResultatTidslinje) { barnRegelverk, søkerRegelverk ->
barnRegelverk == RegelverkResultat.OPPFYLT_EØS_FORORDNINGEN && søkerRegelverk == RegelverkResultat.OPPFYLT_NASJONALE_REGLER
}.inneholder(true)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package no.nav.familie.ba.sak.kjerne.eøs.vilkårsvurdering

import no.nav.familie.ba.sak.datagenerator.ikkeOppfyltVilkår
import no.nav.familie.ba.sak.datagenerator.lagVilkårResultat
import no.nav.familie.ba.sak.datagenerator.oppfyltVilkår
import no.nav.familie.ba.sak.kjerne.tidslinje.eksperimentelt.konkatenerTidslinjer
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.komposisjon.tilTidslinje
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.transformasjon.tilMåned
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.util.apr
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.util.feb
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.util.jul
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.util.mai
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.util.mar
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.util.nov
import no.nav.familie.ba.sak.kjerne.tidslinjefamiliefelles.util.periode
import no.nav.familie.ba.sak.kjerne.vilkårsvurdering.domene.Regelverk.EØS_FORORDNINGEN
import no.nav.familie.ba.sak.kjerne.vilkårsvurdering.domene.Regelverk.NASJONALE_REGLER
import no.nav.familie.ba.sak.kjerne.vilkårsvurdering.domene.Vilkår.BOSATT_I_RIKET
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class VilkårsresultatMånedFamilieFellesTidslinjeTest {
@Test
fun `Virkningstidspunkt fra vilkårsvurdering er måneden etter at normalt vilkår er oppfylt`() {
val dagTidslinje = periode(oppfyltVilkår(BOSATT_I_RIKET), 15.apr(2022), 14.apr(2040)).tilTidslinje()
val faktiskMånedTidslinje = dagTidslinje.tilMånedsbasertTidslinjeForVilkårRegelverkResultat()
val forventetMånedTidslinje = periode(oppfyltVilkår(BOSATT_I_RIKET), mai(2022), apr(2040)).tilTidslinje().tilMåned { it.first() }

assertEquals(forventetMånedTidslinje, faktiskMånedTidslinje)
}

@Test
fun `Back to back perioder i månedsskiftet gir sammenhengende perioder`() {
val periodeFom = 15.apr(2022)
val periodeFom2 = 1.jul(2022)
val faktiskMånedTidslinje =
listOf(
lagVilkårResultat(
vilkårType = BOSATT_I_RIKET,
periodeFom = periodeFom,
periodeTom = periodeFom2.minusDays(1),
),
lagVilkårResultat(
vilkårType = BOSATT_I_RIKET,
periodeFom = periodeFom2,
periodeTom = null,
),
).tilVilkårRegelverkResultatTidslinjeFamilieFelles()
.tilMånedsbasertTidslinjeForVilkårRegelverkResultat()

val forventetMånedTidslinje = periode(oppfyltVilkår(BOSATT_I_RIKET), mai(2022), null).tilTidslinje().tilMåned { it.first() }

assertEquals(forventetMånedTidslinje, faktiskMånedTidslinje)
}

@Test
fun `Siste dag fom-måned og første dag i tom-måned gir oppfylt fra neste måned`() {
val dagTidslinje = periode(oppfyltVilkår(BOSATT_I_RIKET), 29.feb(2020), 1.mai(2020)).tilTidslinje()
val faktiskMånedstidslinje = dagTidslinje.tilMånedsbasertTidslinjeForVilkårRegelverkResultat()
val forventetMånedTidslinje = periode(oppfyltVilkår(BOSATT_I_RIKET), mar(2020), mai(2020)).tilTidslinje().tilMåned { it.first() }

assertEquals(forventetMånedTidslinje, faktiskMånedstidslinje)
}

@Test
fun `Bytte av regelverk innen en måned skal gi kontinuerlig oppfylt tidslinje`() {
val dagvilkårtidslinje =
konkatenerTidslinjer(
periode(oppfyltVilkår(BOSATT_I_RIKET, EØS_FORORDNINGEN), 26.feb(2020), 7.mar(2020)).tilTidslinje(),
periode(oppfyltVilkår(BOSATT_I_RIKET, NASJONALE_REGLER), 21.mar(2020), 13.mai(2020)).tilTidslinje(),
)

val faktiskMånedstidslinje = dagvilkårtidslinje.tilMånedsbasertTidslinjeForVilkårRegelverkResultat()

val forventetMånedstidslinje =
konkatenerTidslinjer(
periode(oppfyltVilkår(BOSATT_I_RIKET, EØS_FORORDNINGEN), mar(2020), mar(2020)).tilTidslinje(),
periode(oppfyltVilkår(BOSATT_I_RIKET, NASJONALE_REGLER), apr(2020), mai(2020)).tilTidslinje(),
).tilMåned { it.first() }

assertEquals(forventetMånedstidslinje, faktiskMånedstidslinje)
}

@Test
fun `Hvis vilkåret er oppfylt siste dag i måneden, skal kun gi oppfylt frem til og med den måneden`() {
val dagTidslinje = periode(oppfyltVilkår(BOSATT_I_RIKET), 15.apr(2022), 30.nov(2022)).tilTidslinje()
val faktiskMånedTidslinje = dagTidslinje.tilMånedsbasertTidslinjeForVilkårRegelverkResultat()
val forventetMånedTidslinje = periode(oppfyltVilkår(BOSATT_I_RIKET), mai(2022), nov(2022)).tilTidslinje().tilMåned { it.first() }

assertEquals(forventetMånedTidslinje, faktiskMånedTidslinje)
}

@Test
fun `Hvis regelverk byttes i månedskiftet, skal det være kontinuerlig oppfylt vilkår`() {
val dagvilkårtidslinje =
konkatenerTidslinjer(
periode(oppfyltVilkår(BOSATT_I_RIKET, EØS_FORORDNINGEN), null, 31.mar(2020)).tilTidslinje(),
periode(oppfyltVilkår(BOSATT_I_RIKET, NASJONALE_REGLER), 1.apr(2020), null).tilTidslinje(),
)

val faktiskMånedstidslinje = dagvilkårtidslinje.tilMånedsbasertTidslinjeForVilkårRegelverkResultat()

val forventetMånedstidslinje =
konkatenerTidslinjer(
periode(oppfyltVilkår(BOSATT_I_RIKET, EØS_FORORDNINGEN), null, mar(2020)).tilTidslinje(),
periode(oppfyltVilkår(BOSATT_I_RIKET, NASJONALE_REGLER), apr(2020), null).tilTidslinje(),
).tilMåned { it.first() }

assertEquals(forventetMånedstidslinje, faktiskMånedstidslinje)
}

@Test
fun `Hvis det byttes fra oppfylt til ikke oppfylt i månedskiftet, skal kun gi oppfylt til og med denne måneden`() {
val dagvilkårtidslinje =
konkatenerTidslinjer(
periode(oppfyltVilkår(BOSATT_I_RIKET, EØS_FORORDNINGEN), null, 31.mar(2020)).tilTidslinje(),
periode(ikkeOppfyltVilkår(BOSATT_I_RIKET), 1.apr(2020), null).tilTidslinje(),
)

val faktiskMånedstidslinje = dagvilkårtidslinje.tilMånedsbasertTidslinjeForVilkårRegelverkResultat()

val forventetMånedstidslinje =
periode(oppfyltVilkår(BOSATT_I_RIKET, EØS_FORORDNINGEN), null, mar(2020))
.tilTidslinje()
.tilMåned { it.first() }

assertEquals(forventetMånedstidslinje, faktiskMånedstidslinje)
}

@Test
fun `Hvis regelverk byttes dagen før månedskiftet, skal det være kontinuerlig oppfylt vilkår`() {
val dagvilkårtidslinje =
konkatenerTidslinjer(
periode(oppfyltVilkår(BOSATT_I_RIKET, NASJONALE_REGLER), null, 29.apr(2020)).tilTidslinje(),
periode(oppfyltVilkår(BOSATT_I_RIKET, EØS_FORORDNINGEN), 30.apr(2020), null).tilTidslinje(),
)

val forventetMånedstidslinje =
konkatenerTidslinjer(
periode(oppfyltVilkår(BOSATT_I_RIKET, NASJONALE_REGLER), null, apr(2020)).tilTidslinje(),
periode(oppfyltVilkår(BOSATT_I_RIKET, EØS_FORORDNINGEN), mai(2020), null).tilTidslinje(),
).tilMåned { it.first() }

val faktiskMånedstidslinje = dagvilkårtidslinje.tilMånedsbasertTidslinjeForVilkårRegelverkResultat()
assertEquals(forventetMånedstidslinje, faktiskMånedstidslinje)
}
}