Skip to content

Commit

Permalink
Legg til ny løype for å lage eøs-begrunnelser som skal sendes til fam…
Browse files Browse the repository at this point in the history
…ilie-brev (#3981)

### 💰 Hva skal gjøres, og hvorfor?

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

Legger til løype for å lage eøs-begrunnelser som skal sendes til
familie-brev med det nye oppsettet

### ✅ Checklist
_Har du husket alle punktene i listen?_
- [ ] Jeg har testet mine endringer i henhold til akseptansekriteriene
🕵️
- [ ] Jeg har config- eller sql-endringer. I så fall, husk manuell
deploy til miljø for å verifisere endringene.
- [x] Jeg har skrevet tester
  • Loading branch information
halvorbmundal authored Sep 21, 2023
1 parent 197bde1 commit 165323b
Show file tree
Hide file tree
Showing 14 changed files with 343 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import no.nav.familie.ba.sak.common.Utils
import no.nav.familie.ba.sak.common.Utils.storForbokstavIHvertOrd
import no.nav.familie.ba.sak.common.tilDagMånedÅr
import no.nav.familie.ba.sak.config.FeatureToggleConfig.Companion.NY_GENERERING_AV_BREVOBJEKTER
import no.nav.familie.ba.sak.integrasjoner.familieintegrasjoner.IntegrasjonClient
import no.nav.familie.ba.sak.integrasjoner.organisasjon.OrganisasjonService
import no.nav.familie.ba.sak.integrasjoner.sanity.SanityService
import no.nav.familie.ba.sak.kjerne.arbeidsfordeling.ArbeidsfordelingService
Expand Down Expand Up @@ -73,6 +74,7 @@ class BrevService(
private val brevmalService: BrevmalService,
private val refusjonEøsRepository: RefusjonEøsRepository,
private val unleashNext: UnleashService,
private val integrasjonClient: IntegrasjonClient,
) {

fun hentVedtaksbrevData(vedtak: Vedtak): Vedtaksbrev {
Expand Down Expand Up @@ -274,7 +276,12 @@ class BrevService(

val brevperioder = if (unleashNext.isEnabled(NY_GENERERING_AV_BREVOBJEKTER) && false) {
val grunnlagForBegrunnelser = vedtaksperiodeService.hentGrunnlagForBegrunnelse(vedtak.behandling)
vedtaksperioder.mapNotNull { it.lagBrevPeriode(grunnlagForBegrunnelser) }
vedtaksperioder.mapNotNull {
it.lagBrevPeriode(
grunnlagForBegrunnelse = grunnlagForBegrunnelser,
landkoder = integrasjonClient.hentLandkoderISO2(),
)
}
} else {
brevPerioderData.sorted().mapNotNull {
it.tilBrevPeriodeGenerator().genererBrevPeriode()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private fun hentUtvidetAndelerIPeriode(begrunnelsesGrunnlagPerPerson: Map<Person
begrunnelsesGrunnlagPerPerson.values.flatMap { it.dennePerioden.andeler }
.filter { it.type == YtelseType.UTVIDET_BARNETRYGD }

private fun IVedtakBegrunnelse.hentSanityBegrunnelse(grunnlag: GrunnlagForBegrunnelse) = when (this) {
fun IVedtakBegrunnelse.hentSanityBegrunnelse(grunnlag: GrunnlagForBegrunnelse) = when (this) {
is EØSStandardbegrunnelse -> grunnlag.sanityEØSBegrunnelser[this]
is Standardbegrunnelse -> grunnlag.sanityBegrunnelser[this]
} ?: throw Feil("Fant ikke tilsvarende sanitybegrunnelse for $this")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import no.nav.familie.ba.sak.common.Feil
import no.nav.familie.ba.sak.common.Utils
import no.nav.familie.ba.sak.common.Utils.storForbokstav
import no.nav.familie.ba.sak.common.tilKortString
import no.nav.familie.ba.sak.ekstern.restDomene.BarnMedOpplysninger
import no.nav.familie.ba.sak.kjerne.brev.brevBegrunnelseProdusent.GrunnlagForBegrunnelse
import no.nav.familie.ba.sak.kjerne.brev.brevBegrunnelseProdusent.hentSanityBegrunnelse
import no.nav.familie.ba.sak.kjerne.brev.domene.SanityPeriodeResultat
import no.nav.familie.ba.sak.kjerne.brev.tilSammenslåttKortString
import no.nav.familie.ba.sak.kjerne.grunnlag.personopplysninger.Person
import no.nav.familie.ba.sak.kjerne.grunnlag.personopplysninger.PersonType
import no.nav.familie.ba.sak.kjerne.personident.Aktør
import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.EØSStandardbegrunnelse
import no.nav.familie.ba.sak.kjerne.vedtak.domene.EØSBegrunnelseData
import no.nav.familie.ba.sak.kjerne.vedtak.domene.EØSBegrunnelseDataMedKompetanse
import no.nav.familie.ba.sak.kjerne.vedtak.domene.EØSBegrunnelseDataUtenKompetanse
import no.nav.familie.ba.sak.kjerne.vedtak.domene.VedtaksperiodeMedBegrunnelser
import no.nav.familie.ba.sak.kjerne.vedtak.vedtaksperiode.vedtakBegrunnelseProdusent.finnBegrunnelseGrunnlagPerPerson
import no.nav.familie.ba.sak.kjerne.vedtak.vedtaksperiode.vedtakBegrunnelseProdusent.hentGyldigeBegrunnelserPerPerson
import java.time.LocalDate

fun EØSStandardbegrunnelse.tilBrevBegrunnelse(
vedtaksperiode: VedtaksperiodeMedBegrunnelser,
grunnlag: GrunnlagForBegrunnelse,
landkoder: Map<String, String>,
): List<EØSBegrunnelseData> {
val sanityBegrunnelse = hentSanityBegrunnelse(grunnlag)
val personerGjeldeneForBegrunnelse = vedtaksperiode.hentGyldigeBegrunnelserPerPerson(
grunnlag,
).mapNotNull { (person, begrunnelserPåPerson) -> person.takeIf { this in begrunnelserPåPerson } }

val begrunnelsesGrunnlagPerPerson = vedtaksperiode.finnBegrunnelseGrunnlagPerPerson(grunnlag)

val periodegrunnlagForPersonerIBegrunnelse =
begrunnelsesGrunnlagPerPerson.filter { (person, _) -> person in personerGjeldeneForBegrunnelse }

val kompetanser = when (sanityBegrunnelse.periodeResultat) {
SanityPeriodeResultat.INNVILGET_ELLER_ØKNING,
SanityPeriodeResultat.INGEN_ENDRING,
-> periodegrunnlagForPersonerIBegrunnelse.values.mapNotNull { it.dennePerioden.kompetanse }

SanityPeriodeResultat.IKKE_INNVILGET,
SanityPeriodeResultat.REDUKSJON,
-> periodegrunnlagForPersonerIBegrunnelse.values.mapNotNull { it.forrigePeriode?.kompetanse }

null -> error("Feltet 'periodeResultat' er ikke satt for begrunnelse fra sanity '${sanityBegrunnelse.apiNavn}'.")
}

return if (kompetanser.isEmpty() && sanityBegrunnelse.periodeResultat == SanityPeriodeResultat.IKKE_INNVILGET) {
val personerIBegrunnelse = personerGjeldeneForBegrunnelse
val barnPåBehandling = grunnlag.behandlingsGrunnlagForVedtaksperioder.persongrunnlag.barna
val barnIBegrunnelse = personerGjeldeneForBegrunnelse.filter { it.type == PersonType.BARN }
val gjelderSøker = personerIBegrunnelse.any { it.type == PersonType.SØKER }

val barnasFødselsdatoer = hentBarnasFødselsdatoerForAvslagsbegrunnelse(
barnIBegrunnelse = barnIBegrunnelse,
barnPåBehandling = barnPåBehandling,
uregistrerteBarn = grunnlag.behandlingsGrunnlagForVedtaksperioder.uregistrerteBarn,
gjelderSøker = gjelderSøker,
)

listOf(
EØSBegrunnelseDataUtenKompetanse(
vedtakBegrunnelseType = this.vedtakBegrunnelseType,
apiNavn = sanityBegrunnelse.apiNavn,
barnasFodselsdatoer = barnasFødselsdatoer.tilSammenslåttKortString(),
antallBarn = barnasFødselsdatoer.size,
maalform = grunnlag.behandlingsGrunnlagForVedtaksperioder.persongrunnlag.søker.målform.tilSanityFormat(),
gjelderSoker = gjelderSøker,
),
)
} else {
kompetanser.map { kompetanse ->
EØSBegrunnelseDataMedKompetanse(
vedtakBegrunnelseType = this.vedtakBegrunnelseType,
apiNavn = sanityBegrunnelse.apiNavn,
annenForeldersAktivitet = kompetanse.annenForeldersAktivitet,
annenForeldersAktivitetsland = kompetanse.annenForeldersAktivitetsland?.tilLandNavn(landkoder)?.navn,
barnetsBostedsland = kompetanse.barnetsBostedsland.tilLandNavn(landkoder).navn,
barnasFodselsdatoer = Utils.slåSammen(
kompetanse.barnAktører.map { aktør ->
grunnlag.hent(aktør).fødselsdato.tilKortString()
},
),
antallBarn = kompetanse.barnAktører.size,
maalform = grunnlag.behandlingsGrunnlagForVedtaksperioder.persongrunnlag.søker.målform.tilSanityFormat(),
sokersAktivitet = kompetanse.søkersAktivitet,
sokersAktivitetsland = kompetanse.søkersAktivitetsland.tilLandNavn(landkoder).navn,
)
}
}
}

private fun GrunnlagForBegrunnelse.hent(
aktør: Aktør,
) = behandlingsGrunnlagForVedtaksperioder.persongrunnlag.personer.single { it.aktør == aktør }

fun hentBarnasFødselsdatoerForAvslagsbegrunnelse(
barnIBegrunnelse: List<Person>,
barnPåBehandling: List<Person>,
uregistrerteBarn: List<BarnMedOpplysninger>,
gjelderSøker: Boolean,
): List<LocalDate> {
val registrerteBarnFødselsdatoer =
if (gjelderSøker) barnPåBehandling.map { it.fødselsdato } else barnIBegrunnelse.map { it.fødselsdato }
val uregistrerteBarnFødselsdatoer =
uregistrerteBarn.mapNotNull { it.fødselsdato }
val alleBarnaFødselsdatoer = registrerteBarnFødselsdatoer + uregistrerteBarnFødselsdatoer
return alleBarnaFødselsdatoer
}

data class Landkode(val kode: String, val navn: String) {
init {
if (this.kode.length != 2) {
throw Feil("Forventer landkode på 'ISO 3166-1 alpha-2'-format")
}
}
}

fun String.tilLandNavn(landkoderISO2: Map<String, String>): Landkode {
val kode = landkoderISO2.entries.find { it.key == this } ?: throw Feil("Fant ikke navn for landkode $this.")

return Landkode(kode.key, kode.value.storForbokstav())
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import no.nav.familie.ba.sak.kjerne.brev.brevBegrunnelseProdusent.GrunnlagForBeg
import no.nav.familie.ba.sak.kjerne.brev.brevBegrunnelseProdusent.lagBrevBegrunnelse
import no.nav.familie.ba.sak.kjerne.brev.domene.maler.BrevPeriodeType
import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode
import no.nav.familie.ba.sak.kjerne.vedtak.domene.BegrunnelseData
import no.nav.familie.ba.sak.kjerne.vedtak.domene.BrevBegrunnelse
import no.nav.familie.ba.sak.kjerne.vedtak.domene.FritekstBegrunnelse
import no.nav.familie.ba.sak.kjerne.vedtak.domene.VedtaksperiodeMedBegrunnelser
import tilBrevBegrunnelse

fun VedtaksperiodeMedBegrunnelser.lagBrevPeriode(
grunnlagForBegrunnelse: GrunnlagForBegrunnelse,
landkoder: Map<String, String>,
): BrevPeriode? {
val standardbegrunnelser =
this.begrunnelser.map { it.standardbegrunnelse.lagBrevBegrunnelse(this, grunnlagForBegrunnelse) }
val eøsBegrunnelser = emptyList<BegrunnelseData>()
val eøsBegrunnelser =
this.eøsBegrunnelser.flatMap { it.begrunnelse.tilBrevBegrunnelse(this, grunnlagForBegrunnelse, landkoder) }
val fritekster = this.fritekster.map { FritekstBegrunnelse(it.fritekst) }

val begrunnelserOgFritekster =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import no.nav.familie.ba.sak.kjerne.eøs.kompetanse.domene.KompetanseAktivitet
import no.nav.familie.ba.sak.kjerne.eøs.kompetanse.domene.KompetanseResultat
import no.nav.familie.ba.sak.kjerne.eøs.kompetanse.domene.UtfyltKompetanse
import no.nav.familie.ba.sak.kjerne.grunnlag.personopplysninger.Person
import no.nav.familie.ba.sak.kjerne.personident.Aktør
import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.IVedtakBegrunnelse
import no.nav.familie.ba.sak.kjerne.vilkårsvurdering.domene.Regelverk
import no.nav.familie.ba.sak.kjerne.vilkårsvurdering.domene.UtdypendeVilkårsvurdering
Expand Down Expand Up @@ -169,6 +170,7 @@ data class KompetanseForVedtaksperiode(
valkersAktivitetsland: String,
val barnetsBostedsland: String,
val resultat: KompetanseResultat,
val barnAktører: Set<Aktør>,
) {
constructor(kompetanse: UtfyltKompetanse) : this(
søkersAktivitet = kompetanse.søkersAktivitet,
Expand All @@ -177,6 +179,7 @@ data class KompetanseForVedtaksperiode(
søkersAktivitetsland = kompetanse.søkersAktivitetsland,
barnetsBostedsland = kompetanse.barnetsBostedsland,
resultat = kompetanse.resultat,
barnAktører = kompetanse.barnAktører,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class BrevServiceTest {
brevmalService = brevmalService,
refusjonEøsRepository = mockk(),
unleashNext = mockk(),
integrasjonClient = mockk(),
)

@BeforeEach
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package no.nav.familie.ba.sak.kjerne.brev

import com.fasterxml.jackson.module.kotlin.readValue
import no.nav.familie.kontrakter.felles.objectMapper
import org.springframework.core.io.ClassPathResource
import java.io.BufferedReader

data class LandkodeISO2(
val code: String,
val name: String,
)

fun hentLandkoderISO2(): Map<String, String> {
val landkoder =
ClassPathResource("landkoder/landkoder.json").inputStream.bufferedReader().use(BufferedReader::readText)

return objectMapper.readValue<List<LandkodeISO2>>(landkoder)
.associate { it.code to it.name }
}

val LANDKODER = hentLandkoderISO2()
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import no.nav.familie.ba.sak.kjerne.behandling.domene.Behandling
import no.nav.familie.ba.sak.kjerne.beregning.domene.AndelTilkjentYtelse
import no.nav.familie.ba.sak.kjerne.beregning.domene.AndelTilkjentYtelseMedEndreteUtbetalinger
import no.nav.familie.ba.sak.kjerne.beregning.domene.InternPeriodeOvergangsstønad
import no.nav.familie.ba.sak.kjerne.brev.LANDKODER
import no.nav.familie.ba.sak.kjerne.brev.brevBegrunnelseProdusent.GrunnlagForBegrunnelse
import no.nav.familie.ba.sak.kjerne.brev.brevPeriodeProdusent.lagBrevPeriode
import no.nav.familie.ba.sak.kjerne.brev.domene.RestSanityBegrunnelse
Expand All @@ -28,7 +29,7 @@ import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.IVedtakBegrunnelse
import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.RestSanityEØSBegrunnelse
import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.SanityEØSBegrunnelse
import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.Standardbegrunnelse
import no.nav.familie.ba.sak.kjerne.vedtak.domene.BegrunnelseData
import no.nav.familie.ba.sak.kjerne.vedtak.domene.BegrunnelseMedData
import no.nav.familie.ba.sak.kjerne.vedtak.domene.VedtaksperiodeMedBegrunnelser
import no.nav.familie.ba.sak.kjerne.vedtak.vedtaksperiode.Vedtaksperiodetype
import no.nav.familie.ba.sak.kjerne.vedtak.vedtaksperiode.domene.UtvidetVedtaksperiodeMedBegrunnelser
Expand Down Expand Up @@ -291,7 +292,7 @@ class BegrunnelseTeksterStepDefinition {
}

/**
* Mulige verdier: | Begrunnelse | Gjelder søker | Barnas fødselsdager | Antall barn | Måned og år begrunnelsen gjelder for | Målform | Beløp | Søknadstidspunkt | Avtale tidspunkt delt bosted | Søkers rett til utvidet |
* Mulige verdier: | Begrunnelse | Type | Gjelder søker | Barnas fødselsdager | Antall barn | Måned og år begrunnelsen gjelder for | Målform | Beløp | Søknadstidspunkt | Avtale tidspunkt delt bosted | Søkers rett til utvidet |
*/
@Så("forvent følgende brevbegrunnelser for behandling {} i periode {} til {}")
fun `forvent følgende brevbegrunnelser for behandling i periode`(
Expand All @@ -304,14 +305,14 @@ class BegrunnelseTeksterStepDefinition {
val vedtak = vedtaksliste.find { it.behandling.id == behandlingId && it.aktiv } ?: error("Finner ikke vedtak")
val grunnlagForBegrunnelse = hentGrunnlagForBegrunnelser(behandlingId, vedtak, forrigeBehandlingId)

val faktiskeBegrunnelser: List<BegrunnelseData> =
val faktiskeBegrunnelser: List<BegrunnelseMedData> =
vedtaksperioderMedBegrunnelser.single {
it.fom == parseNullableDato(periodeFom) && it.tom == parseNullableDato(periodeTom)
}.lagBrevPeriode(grunnlagForBegrunnelse)!!
}.lagBrevPeriode(grunnlagForBegrunnelse, LANDKODER)!!
.begrunnelser
.filterIsInstance<BegrunnelseData>()
.filterIsInstance<BegrunnelseMedData>()

val forvendtedeBegrunnelser = parseStandardBegrunnelser(dataTable)
val forvendtedeBegrunnelser = parseBegrunnelser(dataTable)

assertThat(faktiskeBegrunnelser.sortedBy { it.apiNavn })
.usingRecursiveComparison()
Expand Down
Loading

0 comments on commit 165323b

Please sign in to comment.