diff --git a/src/main/kotlin/no/nav/familie/ba/sak/common/Tid.kt b/src/main/kotlin/no/nav/familie/ba/sak/common/Tid.kt index 921f02fb789..fb71df15ad9 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/common/Tid.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/common/Tid.kt @@ -19,6 +19,7 @@ private val FORMAT_DATO_NORSK = DateTimeFormatter.ofPattern("dd.MM.yyyy", nbLoca private val FORMAT_DATO_MÅNED_ÅR_KORT = DateTimeFormatter.ofPattern("MM.yy", nbLocale) private val FORMAT_DATO_DAG_MÅNED_ÅR = DateTimeFormatter.ofPattern("d. MMMM yyyy", nbLocale) private val FORMAT_DATO_MÅNED_ÅR = DateTimeFormatter.ofPattern("MMMM yyyy", nbLocale) +private val FORMAT_DATO_MÅNED_ÅR_MEDIUM = DateTimeFormatter.ofPattern("MMM yy", nbLocale) fun LocalDate.tilddMMyy() = this.format(FORMAT_DATE_DDMMYY) @@ -36,6 +37,8 @@ fun LocalDate.tilMånedÅr() = this.format(FORMAT_DATO_MÅNED_ÅR) fun YearMonth.tilMånedÅr() = this.format(FORMAT_DATO_MÅNED_ÅR) +fun YearMonth.tilMånedÅrMedium() = this.format(FORMAT_DATO_MÅNED_ÅR_MEDIUM) + fun erBack2BackIMånedsskifte( tilOgMed: LocalDate?, fraOgMed: LocalDate?, diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevService.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevService.kt index 84d43ed4db9..28e7ad08497 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevService.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevService.kt @@ -6,6 +6,8 @@ import no.nav.familie.ba.sak.common.Utils import no.nav.familie.ba.sak.common.Utils.storForbokstavIAlleNavn import no.nav.familie.ba.sak.common.secureLogger import no.nav.familie.ba.sak.common.tilDagMånedÅr +import no.nav.familie.ba.sak.common.tilMånedÅr +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.familieintegrasjoner.IntegrasjonClient @@ -16,6 +18,7 @@ import no.nav.familie.ba.sak.kjerne.arbeidsfordeling.ArbeidsfordelingService import no.nav.familie.ba.sak.kjerne.autovedtak.fødselshendelse.Resultat import no.nav.familie.ba.sak.kjerne.behandling.domene.Behandling import no.nav.familie.ba.sak.kjerne.beregning.domene.AndelTilkjentYtelseRepository +import no.nav.familie.ba.sak.kjerne.beregning.domene.tilTidslinjerPerPersonOgType import no.nav.familie.ba.sak.kjerne.brev.brevBegrunnelseProdusent.BrevBegrunnelseFeil import no.nav.familie.ba.sak.kjerne.brev.brevPeriodeProdusent.lagBrevPeriode import no.nav.familie.ba.sak.kjerne.brev.domene.maler.Autovedtak6og18årOgSmåbarnstillegg @@ -40,9 +43,16 @@ import no.nav.familie.ba.sak.kjerne.brev.domene.maler.Opphørt import no.nav.familie.ba.sak.kjerne.brev.domene.maler.RefusjonEøsAvklart import no.nav.familie.ba.sak.kjerne.brev.domene.maler.RefusjonEøsUavklart import no.nav.familie.ba.sak.kjerne.brev.domene.maler.SignaturVedtak +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.UtbetalingstabellAutomatiskValutajustering import no.nav.familie.ba.sak.kjerne.brev.domene.maler.VedtakEndring import no.nav.familie.ba.sak.kjerne.brev.domene.maler.VedtakFellesfelter import no.nav.familie.ba.sak.kjerne.brev.domene.maler.Vedtaksbrev +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs +import no.nav.familie.ba.sak.kjerne.eøs.kompetanse.KompetanseRepository +import no.nav.familie.ba.sak.kjerne.eøs.kompetanse.domene.UtfyltKompetanse +import no.nav.familie.ba.sak.kjerne.eøs.kompetanse.domene.tilIKompetanse +import no.nav.familie.ba.sak.kjerne.eøs.utenlandskperiodebeløp.UtenlandskPeriodebeløpRepository +import no.nav.familie.ba.sak.kjerne.eøs.valutakurs.ValutakursRepository import no.nav.familie.ba.sak.kjerne.grunnlag.personopplysninger.Målform import no.nav.familie.ba.sak.kjerne.grunnlag.personopplysninger.PersongrunnlagService import no.nav.familie.ba.sak.kjerne.grunnlag.personopplysninger.PersonopplysningGrunnlag @@ -60,6 +70,7 @@ import no.nav.familie.ba.sak.kjerne.vedtak.vedtaksperiode.Vedtaksperiodetype import no.nav.familie.ba.sak.kjerne.vilkårsvurdering.VilkårsvurderingService import no.nav.familie.ba.sak.sikkerhet.SaksbehandlerContext import org.springframework.stereotype.Service +import tilLandNavn import java.math.BigDecimal @Service @@ -80,6 +91,9 @@ class BrevService( private val integrasjonClient: IntegrasjonClient, private val testVerktøyService: TestVerktøyService, private val andelTilkjentYtelseRepository: AndelTilkjentYtelseRepository, + private val utenlandskPeriodebeløpRepository: UtenlandskPeriodebeløpRepository, + private val kompetanseRepository: KompetanseRepository, + private val valutakursRepository: ValutakursRepository, private val unleashService: UnleashNextMedContextService, ) { fun hentVedtaksbrevData(vedtak: Vedtak): Vedtaksbrev { @@ -112,6 +126,7 @@ class BrevService( duMåMeldeFraOmEndringer = !skalMeldeFraOmEndringerEøsSelvstendigRett, duMåMeldeFraOmEndringerEøsSelvstendigRett = skalMeldeFraOmEndringerEøsSelvstendigRett, informasjonOmUtbetaling = skalInkludereInformasjonOmUtbetaling, + utbetalingstabellAutomatiskValutajustering = hentLandOgStartdatoForUtbetalingstabell(vedtak, vedtakFellesfelter), ) Brevmal.VEDTAK_FØRSTEGANGSVEDTAK_INSTITUSJON -> @@ -137,6 +152,7 @@ class BrevService( duMåMeldeFraOmEndringer = !skalMeldeFraOmEndringerEøsSelvstendigRett, duMåMeldeFraOmEndringerEøsSelvstendigRett = skalMeldeFraOmEndringerEøsSelvstendigRett, informasjonOmUtbetaling = skalInkludereInformasjonOmUtbetaling, + utbetalingstabellAutomatiskValutajustering = hentLandOgStartdatoForUtbetalingstabell(vedtak, vedtakFellesfelter), ) Brevmal.VEDTAK_ENDRING_INSTITUSJON -> @@ -170,6 +186,7 @@ class BrevService( refusjonEosAvklart = beskrivPerioderMedAvklartRefusjonEøs(vedtak), refusjonEosUavklart = beskrivPerioderMedUavklartRefusjonEøs(vedtak), erKlage = behandling.erKlage(), + utbetalingstabellAutomatiskValutajustering = hentLandOgStartdatoForUtbetalingstabell(vedtak, vedtakFellesfelter), ) Brevmal.VEDTAK_OPPHØR_MED_ENDRING_INSTITUSJON -> @@ -198,6 +215,7 @@ class BrevService( duMåMeldeFraOmEndringer = !skalMeldeFraOmEndringerEøsSelvstendigRett, duMåMeldeFraOmEndringerEøsSelvstendigRett = skalMeldeFraOmEndringerEøsSelvstendigRett, informasjonOmUtbetaling = skalInkludereInformasjonOmUtbetaling, + utbetalingstabellAutomatiskValutajustering = hentLandOgStartdatoForUtbetalingstabell(vedtak, vedtakFellesfelter), ) Brevmal.VEDTAK_FORTSATT_INNVILGET_INSTITUSJON -> @@ -228,6 +246,26 @@ class BrevService( } } + private fun hentLandOgStartdatoForUtbetalingstabell( + vedtak: Vedtak, + vedtakFellesfelter: VedtakFellesfelter, + ): UtbetalingstabellAutomatiskValutajustering? { + return vedtakFellesfelter.utbetalingerPerMndEøs?.let { + val mndÅrFørsteEndring = hentSorterteVedtaksperioderMedBegrunnelser(vedtak).first().fom!! + val landkoder = integrasjonClient.hentLandkoderISO2() + val kompetanser = kompetanseRepository.finnFraBehandlingId(behandlingId = vedtak.behandling.id).map { it.tilIKompetanse() }.filterIsInstance() + val eøsLandMedUtbetalinger = + kompetanser.filter { it.fom >= mndÅrFørsteEndring.toYearMonth() }.map { + if (it.erAnnenForelderOmfattetAvNorskLovgivning) { + it.søkersAktivitetsland.tilLandNavn(landkoder).navn + } else { + it.annenForeldersAktivitetsland?.tilLandNavn(landkoder)?.navn ?: it.barnetsBostedsland.tilLandNavn(landkoder).navn + } + }.toSet() + return UtbetalingstabellAutomatiskValutajustering(utbetalingerEosLand = eøsLandMedUtbetalinger.slåSammen(), utbetalingerEosMndAar = mndÅrFørsteEndring.tilMånedÅr()) + } + } + fun sjekkOmDetErLøpendeDifferanseUtbetalingPåBehandling(behandling: Behandling): Boolean { if (!unleashService.isEnabled(FeatureToggleConfig.KAN_OPPRETTE_AUTOMATISKE_VALUTAKURSER_PÅ_MANUELLE_SAKER)) return false @@ -316,14 +354,15 @@ class BrevService( ) } + private fun hentSorterteVedtaksperioderMedBegrunnelser(vedtak: Vedtak) = + vedtaksperiodeService.hentPersisterteVedtaksperioder(vedtak) + .filter { it.erBegrunnet() } + .sortedBy { it.fom } + fun lagVedtaksbrevFellesfelter(vedtak: Vedtak): VedtakFellesfelter { - val vedtaksperioder = - vedtaksperiodeService.hentPersisterteVedtaksperioder(vedtak) - .filter { - !(it.begrunnelser.isEmpty() && it.fritekster.isEmpty() && it.eøsBegrunnelser.isEmpty()) - }.sortedBy { it.fom } + val sorterteVedtaksperioderMedBegrunnelser = hentSorterteVedtaksperioderMedBegrunnelser(vedtak) - if (vedtaksperioder.isEmpty()) { + if (sorterteVedtaksperioderMedBegrunnelser.isEmpty()) { throw FunksjonellFeil( "Vedtaket mangler begrunnelser. Du må legge til begrunnelser for å generere vedtaksbrevet.", ) @@ -336,7 +375,7 @@ class BrevService( val grunnlagForBegrunnelser = vedtaksperiodeService.hentGrunnlagForBegrunnelse(vedtak.behandling) val brevperioder = - vedtaksperioder.mapNotNull { vedtaksperiode -> + sorterteVedtaksperioderMedBegrunnelser.mapNotNull { vedtaksperiode -> try { vedtaksperiode.lagBrevPeriode( grunnlagForBegrunnelse = grunnlagForBegrunnelser, @@ -353,14 +392,16 @@ class BrevService( } } + val utbetalingerPerMndEøs = hentUtbetalingerPerMndEøs(vedtak) + val korrigertVedtak = korrigertVedtakService.finnAktivtKorrigertVedtakPåBehandling(behandlingId) val refusjonEøs = refusjonEøsRepository.finnRefusjonEøsForBehandling(behandlingId) val hjemler = hentHjemler( behandlingId = behandlingId, - erFritekstIBrev = vedtaksperioder.any { it.fritekster.isNotEmpty() }, - vedtaksperioder = vedtaksperioder, + erFritekstIBrev = sorterteVedtaksperioderMedBegrunnelser.any { it.fritekster.isNotEmpty() }, + vedtaksperioder = sorterteVedtaksperioderMedBegrunnelser, målform = personopplysningGrunnlag.søker.målform, vedtakKorrigertHjemmelSkalMedIBrev = korrigertVedtak != null, refusjonEøsHjemmelSkalMedIBrev = refusjonEøs.isNotEmpty(), @@ -380,6 +421,7 @@ class BrevService( organisasjonsnummer = organisasjonsnummer, gjelder = if (organisasjonsnummer != null) grunnlagOgSignaturData.grunnlag.søker.navn else null, korrigertVedtakData = korrigertVedtak?.let { KorrigertVedtakData(datoKorrigertVedtak = it.vedtaksdato.tilDagMånedÅr()) }, + utbetalingerPerMndEøs = utbetalingerPerMndEøs, ) } @@ -446,6 +488,32 @@ class BrevService( ) } + private fun hentUtbetalingerPerMndEøs( + vedtak: Vedtak, + ): Map? { + if (!unleashService.isEnabled(FeatureToggleConfig.KAN_OPPRETTE_AUTOMATISKE_VALUTAKURSER_PÅ_MANUELLE_SAKER)) { + return null + } + + val behandlingId = vedtak.behandling.id + val endringstidspunkt = vedtaksperiodeService.finnEndringstidspunktForBehandling(behandlingId = behandlingId) + val valutakurser = valutakursRepository.finnFraBehandlingId(behandlingId = behandlingId) + + if (!skalHenteUtbetalingerEøs(endringstidspunkt = endringstidspunkt, valutakurser)) { + return null + } + + val andelerForVedtaksperioderPerAktørOgType = andelTilkjentYtelseRepository.finnAndelerTilkjentYtelseForBehandling(behandlingId = behandlingId).tilTidslinjerPerPersonOgType() + val utenlandskePeriodebeløp = utenlandskPeriodebeløpRepository.finnFraBehandlingId(behandlingId = behandlingId).toList() + + return hentUtbetalingerPerMndEøs( + endringstidspunkt = endringstidspunkt, + andelerForVedtaksperioderPerAktørOgType = andelerForVedtaksperioderPerAktørOgType, + utenlandskePeriodebeløp = utenlandskePeriodebeløp, + valutakurser = valutakurser, + ) + } + fun hentSaksbehandlerOgBeslutter( behandling: Behandling, totrinnskontroll: Totrinnskontroll?, diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevUtil.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevUtil.kt index 70c5a7bfeda..476aa8dff47 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevUtil.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevUtil.kt @@ -6,6 +6,7 @@ import no.nav.familie.ba.sak.common.TIDENES_MORGEN import no.nav.familie.ba.sak.common.Utils import no.nav.familie.ba.sak.common.sisteDagIMåned import no.nav.familie.ba.sak.common.tilMånedÅr +import no.nav.familie.ba.sak.common.tilMånedÅrMedium import no.nav.familie.ba.sak.kjerne.behandling.domene.Behandling import no.nav.familie.ba.sak.kjerne.behandling.domene.BehandlingType import no.nav.familie.ba.sak.kjerne.behandling.domene.Behandlingsresultat.DELVIS_INNVILGET @@ -15,11 +16,31 @@ import no.nav.familie.ba.sak.kjerne.behandling.domene.Behandlingsresultat.INNVIL import no.nav.familie.ba.sak.kjerne.behandling.domene.Behandlingsresultat.INNVILGET_OG_ENDRET import no.nav.familie.ba.sak.kjerne.behandling.domene.Behandlingsresultat.INNVILGET_OG_OPPHØRT import no.nav.familie.ba.sak.kjerne.behandling.domene.BehandlingÅrsak +import no.nav.familie.ba.sak.kjerne.beregning.AndelTilkjentYtelseTidslinje +import no.nav.familie.ba.sak.kjerne.beregning.domene.YtelseType import no.nav.familie.ba.sak.kjerne.brev.domene.SanityBegrunnelse import no.nav.familie.ba.sak.kjerne.brev.domene.SanityEØSBegrunnelse import no.nav.familie.ba.sak.kjerne.brev.domene.maler.Brevmal +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.AndelUpbOgValutakurs +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingEøs +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøsOppsummering +import no.nav.familie.ba.sak.kjerne.eøs.differanseberegning.domene.times +import no.nav.familie.ba.sak.kjerne.eøs.felles.beregning.tilSeparateTidslinjerForBarna +import no.nav.familie.ba.sak.kjerne.eøs.utenlandskperiodebeløp.UtenlandskPeriodebeløp +import no.nav.familie.ba.sak.kjerne.eøs.utenlandskperiodebeløp.tilUtbetaltFraAnnetLand +import no.nav.familie.ba.sak.kjerne.eøs.valutakurs.Valutakurs import no.nav.familie.ba.sak.kjerne.fagsak.FagsakStatus import no.nav.familie.ba.sak.kjerne.grunnlag.personopplysninger.Målform +import no.nav.familie.ba.sak.kjerne.personident.Aktør +import no.nav.familie.ba.sak.kjerne.tidslinje.komposisjon.erIkkeTom +import no.nav.familie.ba.sak.kjerne.tidslinje.komposisjon.kombiner +import no.nav.familie.ba.sak.kjerne.tidslinje.komposisjon.outerJoin +import no.nav.familie.ba.sak.kjerne.tidslinje.splitPerTidsenhet +import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.MånedTidspunkt.Companion.tilMånedTidspunkt +import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.tilYearMonth +import no.nav.familie.ba.sak.kjerne.tidslinje.transformasjon.beskjærFraOgMed +import no.nav.familie.ba.sak.kjerne.tidslinje.transformasjon.mapIkkeNull import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.EØSStandardbegrunnelse import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.Standardbegrunnelse import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.hjemlerTilhørendeFritekst @@ -145,14 +166,14 @@ private fun slåSammenHjemlerAvUlikeTyper(hjemler: List) = when (hjemler.size) { 0 -> throw FunksjonellFeil("Ingen hjemler var knyttet til begrunnelsen(e) som er valgt. Du må velge minst én begrunnelse som er knyttet til en hjemmel.") 1 -> hjemler.single() - else -> slåSammenListeMedHjemler(hjemler) + else -> hjemler.slåSammen() } -private fun slåSammenListeMedHjemler(hjemler: List): String { - return hjemler.reduceIndexed { index, acc, s -> +fun Collection.slåSammen(): String { + return this.reduceIndexed { index, acc, s -> when (index) { - 0 -> acc + s - hjemler.size - 1 -> "$acc og $s" + 0 -> s + this.size - 1 -> "$acc og $s" else -> "$acc, $s" } } @@ -271,3 +292,73 @@ fun hentVirkningstidspunktForDødsfallbrev( fun hentForvaltningsloverHjemler(vedtakKorrigertHjemmelSkalMedIBrev: Boolean): List { return if (vedtakKorrigertHjemmelSkalMedIBrev) listOf("35") else emptyList() } + +fun skalHenteUtbetalingerEøs( + endringstidspunkt: LocalDate, + valutakurser: List, +): Boolean { + val valutakurserEtterEndringtidspunktet = + valutakurser.tilSeparateTidslinjerForBarna() + .mapValues { (_, valutakursTidslinjeForBarn) -> valutakursTidslinjeForBarn.beskjærFraOgMed(endringstidspunkt.tilMånedTidspunkt()) } + return valutakurserEtterEndringtidspunktet.any { it.value.erIkkeTom() } +} + +fun hentUtbetalingerPerMndEøs( + endringstidspunkt: LocalDate, + andelerForVedtaksperioderPerAktørOgType: Map, AndelTilkjentYtelseTidslinje>, + utenlandskePeriodebeløp: List, + valutakurser: List, +): Map { + // Ønsker kun andeler etter endringstidspunkt så beskjærer fra og med endringstidspunktet + val andelerForVedtaksperioderPerAktørOgTypeAvgrensetTilVedtaksperioder = + andelerForVedtaksperioderPerAktørOgType.mapValues { (_, andelForVedtaksperiode) -> andelForVedtaksperiode.beskjærFraOgMed(endringstidspunkt.tilMånedTidspunkt()) } + + val utenlandskePeriodebeløpTidslinjerForBarna = utenlandskePeriodebeløp.tilSeparateTidslinjerForBarna().mapKeys { entry -> Pair(entry.key, YtelseType.ORDINÆR_BARNETRYGD) } + val valutakursTidslinjerForBarna = valutakurser.tilSeparateTidslinjerForBarna().mapKeys { entry -> Pair(entry.key, YtelseType.ORDINÆR_BARNETRYGD) } + + return andelerForVedtaksperioderPerAktørOgTypeAvgrensetTilVedtaksperioder + // Kombinerer tidslinjene for andeler, utenlandskPeriodebeløp og valutakurser per aktørOgYtelse + .outerJoin(utenlandskePeriodebeløpTidslinjerForBarna, valutakursTidslinjerForBarna) { andelForVedtaksperiode, utenlandsPeriodebeløp, valutakurs -> andelForVedtaksperiode?.let { AndelUpbOgValutakurs(andelTilkjentYtelse = andelForVedtaksperiode, utenlandskPeriodebeløp = utenlandsPeriodebeløp, valutakurs = valutakurs) } } + .map { (aktørOgYtelseType, andelUpbOgValutakursTidslinje) -> + andelUpbOgValutakursTidslinje.mapIkkeNull { andelerUpbOgValutakurs -> + hentUtbetalingEøs(aktørOgYtelseType = aktørOgYtelseType, andelUpbOgValutakurs = andelerUpbOgValutakurs) + } + } + // Kombinerer verdiene til alle tidslinjene slik at vi får en liste av UtbetalingEøs per periode, samt sørger for at vi får en periode per mnd. + // Grupperer deretter på periodenes fom + .kombiner().perioder() + .flatMap { periode -> periode.splitPerTidsenhet(LocalDate.now().tilMånedTidspunkt()) } + .associate { periode -> + val utbetalingMndEøs = hentUtbetalingMndEøs(utbetalingerEøs = periode.innhold?.toList() ?: emptyList()) + val fraOgMedDato = periode.fraOgMed.tilYearMonth().tilMånedÅrMedium() + + fraOgMedDato to utbetalingMndEøs + } + .filter { it.value.utbetalinger.isNotEmpty() } +} + +private fun hentUtbetalingEøs( + aktørOgYtelseType: Pair, + andelUpbOgValutakurs: AndelUpbOgValutakurs, +): UtbetalingEøs { + return UtbetalingEøs( + fnr = aktørOgYtelseType.first.aktivFødselsnummer(), + ytelseType = aktørOgYtelseType.second, + satsINorge = andelUpbOgValutakurs.andelTilkjentYtelse.sats, + utbetaltFraAnnetLand = andelUpbOgValutakurs.utenlandskPeriodebeløp?.tilUtbetaltFraAnnetLand(andelUpbOgValutakurs.valutakurs), + utbetaltFraNorge = andelUpbOgValutakurs.andelTilkjentYtelse.kalkulertUtbetalingsbeløp, + ) +} + +private fun hentUtbetalingMndEøs(utbetalingerEøs: List): UtbetalingMndEøs { + val summertUtbetaltFraAnnetLand = utbetalingerEøs.sumOf { utbetalingEøs -> utbetalingEøs.utbetaltFraAnnetLand?.beløpINok ?: 0 } + return UtbetalingMndEøs( + utbetalinger = utbetalingerEøs, + oppsummering = + UtbetalingMndEøsOppsummering( + summertSatsINorge = utbetalingerEøs.sumOf { utbetalingEøs -> utbetalingEøs.satsINorge }, + summertUtbetaltFraAnnetLand = summertUtbetaltFraAnnetLand.takeIf { it != 0 }, + summertUtbetaltFraNorge = utbetalingerEøs.sumOf { it.utbetaltFraNorge }, + ), + ) +} diff --git "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Autovedtak6og18\303\245rOgSm\303\245barnstillegg.kt" "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Autovedtak6og18\303\245rOgSm\303\245barnstillegg.kt" index 6ad65a709b8..ee1efe5fb57 100644 --- "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Autovedtak6og18\303\245rOgSm\303\245barnstillegg.kt" +++ "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Autovedtak6og18\303\245rOgSm\303\245barnstillegg.kt" @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs data class Autovedtak6og18årOgSmåbarnstillegg( override val mal: Brevmal = Brevmal.AUTOVEDTAK_BARN_6_OG_18_ÅR_OG_SMÅBARNSTILLEGG, @@ -34,6 +35,7 @@ data class Autovedtak6og18årData( override val delmalData: Delmaler, override val flettefelter: FlettefelterForDokumentImpl, override val perioder: List, + override val utbetalingerPerMndEøs: Map? = null, ) : VedtaksbrevData { data class Delmaler( val hjemmeltekst: Hjemmeltekst, diff --git "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/AutovedtakNyf\303\270dtBarnFraF\303\270r.kt" "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/AutovedtakNyf\303\270dtBarnFraF\303\270r.kt" index c47b668ccce..a6a9e6539a0 100644 --- "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/AutovedtakNyf\303\270dtBarnFraF\303\270r.kt" +++ "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/AutovedtakNyf\303\270dtBarnFraF\303\270r.kt" @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs data class AutovedtakNyfødtBarnFraFør( override val mal: Brevmal = Brevmal.AUTOVEDTAK_NYFØDT_BARN_FRA_FØR, @@ -36,6 +37,7 @@ data class AutovedtakNyfødtBarnFraFørData( override val delmalData: Delmaler, override val flettefelter: FlettefelterForDokumentImpl, override val perioder: List, + override val utbetalingerPerMndEøs: Map? = null, ) : VedtaksbrevData { data class Delmaler( val etterbetaling: Etterbetaling?, diff --git "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/AutovedtakNyf\303\270dtF\303\270rsteBarn.kt" "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/AutovedtakNyf\303\270dtF\303\270rsteBarn.kt" index 0abce5005e5..2b7e45a4f91 100644 --- "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/AutovedtakNyf\303\270dtF\303\270rsteBarn.kt" +++ "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/AutovedtakNyf\303\270dtF\303\270rsteBarn.kt" @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs data class AutovedtakNyfødtFørsteBarn( override val mal: Brevmal = Brevmal.AUTOVEDTAK_NYFØDT_FØRSTE_BARN, @@ -36,6 +37,7 @@ data class AutovedtakNyfødtFørsteBarnData( override val delmalData: Delmaler, override val flettefelter: FlettefelterForDokumentImpl, override val perioder: List, + override val utbetalingerPerMndEøs: Map? = null, ) : VedtaksbrevData { data class Delmaler( val etterbetaling: Etterbetaling?, diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Avslag.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Avslag.kt index 3a6a90b8bc3..f6f408bc11f 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Avslag.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Avslag.kt @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs data class Avslag( override val mal: Brevmal, @@ -41,6 +42,7 @@ data class AvslagData( override val delmalData: Delmaler, override val flettefelter: FlettefelterForDokumentImpl, override val perioder: List, + override val utbetalingerPerMndEøs: Map? = null, ) : VedtaksbrevData { data class Delmaler( val signaturVedtak: SignaturVedtak, diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/FellesDelmaler.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/FellesDelmaler.kt index 989da5407bc..905d53623e4 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/FellesDelmaler.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/FellesDelmaler.kt @@ -86,6 +86,16 @@ data class RefusjonEøsUavklart( ) } +data class UtbetalingstabellAutomatiskValutajustering( + val utbetalingerEosLand: Flettefelt, + val utbetalingerEosMndAar: Flettefelt, +) { + constructor(utbetalingerEosLand: String, utbetalingerEosMndAar: String) : this( + utbetalingerEosLand = flettefelt(utbetalingerEosLand), + utbetalingerEosMndAar = flettefelt(utbetalingerEosMndAar), + ) +} + data class FritekstAvsnitt( val fritekstAvsnittTekst: Flettefelt, ) { diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/ForsattInnvilget.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/ForsattInnvilget.kt index ca284aa2a11..a1c5268bc63 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/ForsattInnvilget.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/ForsattInnvilget.kt @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs data class ForsattInnvilget( override val mal: Brevmal, @@ -17,6 +18,7 @@ data class ForsattInnvilget( duMåMeldeFraOmEndringer: Boolean = true, duMåMeldeFraOmEndringerEøsSelvstendigRett: Boolean = false, informasjonOmUtbetaling: Boolean = false, + utbetalingstabellAutomatiskValutajustering: UtbetalingstabellAutomatiskValutajustering? = null, ) : this( mal = mal, @@ -40,6 +42,7 @@ data class ForsattInnvilget( duMaaMeldeFraOmEndringer = duMåMeldeFraOmEndringer, duMaaMeldeFraOmEndringerEosSelvstendigRett = duMåMeldeFraOmEndringerEøsSelvstendigRett, informasjonOmUtbetaling = informasjonOmUtbetaling, + utbetalingstabellAutomatiskValutajustering = utbetalingstabellAutomatiskValutajustering, ), flettefelter = FlettefelterForDokumentImpl( @@ -49,6 +52,7 @@ data class ForsattInnvilget( organisasjonsnummer = flettefelt(vedtakFellesfelter.organisasjonsnummer), ), perioder = vedtakFellesfelter.perioder, + utbetalingerPerMndEøs = vedtakFellesfelter.utbetalingerPerMndEøs, ), ) } @@ -57,6 +61,7 @@ data class ForsattInnvilgetData( override val delmalData: Delmaler, override val flettefelter: FlettefelterForDokument, override val perioder: List, + override val utbetalingerPerMndEøs: Map? = null, ) : VedtaksbrevData { data class Delmaler( val signaturVedtak: SignaturVedtak, @@ -70,5 +75,6 @@ data class ForsattInnvilgetData( val duMaaMeldeFraOmEndringerEosSelvstendigRett: Boolean, val duMaaMeldeFraOmEndringer: Boolean, val informasjonOmUtbetaling: Boolean, + val utbetalingstabellAutomatiskValutajustering: UtbetalingstabellAutomatiskValutajustering?, ) } diff --git "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/F\303\270rstegangsvedtak.kt" "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/F\303\270rstegangsvedtak.kt" index 5c385a52694..b171a7e2bdf 100644 --- "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/F\303\270rstegangsvedtak.kt" +++ "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/F\303\270rstegangsvedtak.kt" @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs data class Førstegangsvedtak( override val mal: Brevmal, @@ -14,6 +15,7 @@ data class Førstegangsvedtak( informasjonOmAarligKontroll: Boolean = false, refusjonEosAvklart: RefusjonEøsAvklart? = null, refusjonEosUavklart: RefusjonEøsUavklart? = null, + utbetalingstabellAutomatiskValutajustering: UtbetalingstabellAutomatiskValutajustering? = null, duMåMeldeFraOmEndringer: Boolean = true, duMåMeldeFraOmEndringerEøsSelvstendigRett: Boolean = false, informasjonOmUtbetaling: Boolean = false, @@ -40,6 +42,7 @@ data class Førstegangsvedtak( duMaaMeldeFraOmEndringerEosSelvstendigRett = duMåMeldeFraOmEndringerEøsSelvstendigRett, duMaaMeldeFraOmEndringer = duMåMeldeFraOmEndringer, informasjonOmUtbetaling = informasjonOmUtbetaling, + utbetalingstabellAutomatiskValutajustering = utbetalingstabellAutomatiskValutajustering, ), perioder = vedtakFellesfelter.perioder, flettefelter = @@ -49,6 +52,7 @@ data class Førstegangsvedtak( fodselsnummer = flettefelt(vedtakFellesfelter.søkerFødselsnummer), organisasjonsnummer = flettefelt(vedtakFellesfelter.organisasjonsnummer), ), + utbetalingerPerMndEøs = vedtakFellesfelter.utbetalingerPerMndEøs, ), ) } @@ -57,6 +61,7 @@ data class FørstegangsvedtakData( override val delmalData: Delmaler, override val flettefelter: FlettefelterForDokument, override val perioder: List, + override val utbetalingerPerMndEøs: Map?, ) : VedtaksbrevData { data class Delmaler( val signaturVedtak: SignaturVedtak, @@ -67,6 +72,7 @@ data class FørstegangsvedtakData( val informasjonOmAarligKontroll: Boolean, val refusjonEosAvklart: RefusjonEøsAvklart?, val refusjonEosUavklart: RefusjonEøsUavklart?, + val utbetalingstabellAutomatiskValutajustering: UtbetalingstabellAutomatiskValutajustering?, val duMaaMeldeFraOmEndringerEosSelvstendigRett: Boolean, val duMaaMeldeFraOmEndringer: Boolean, val informasjonOmUtbetaling: Boolean, diff --git "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Opph\303\270rMedEndring.kt" "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Opph\303\270rMedEndring.kt" index e2fcb7463a3..b4cf05e901c 100644 --- "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Opph\303\270rMedEndring.kt" +++ "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Opph\303\270rMedEndring.kt" @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs data class OpphørMedEndring( override val mal: Brevmal, @@ -15,6 +16,7 @@ data class OpphørMedEndring( refusjonEosAvklart: RefusjonEøsAvklart? = null, refusjonEosUavklart: RefusjonEøsUavklart? = null, erKlage: Boolean, + utbetalingstabellAutomatiskValutajustering: UtbetalingstabellAutomatiskValutajustering? = null, ) : this( mal = mal, @@ -36,6 +38,7 @@ data class OpphørMedEndring( refusjonEosAvklart = refusjonEosAvklart, refusjonEosUavklart = refusjonEosUavklart, klage = erKlage, + utbetalingstabellAutomatiskValutajustering = utbetalingstabellAutomatiskValutajustering, ), flettefelter = FlettefelterForDokumentImpl( @@ -45,6 +48,7 @@ data class OpphørMedEndring( organisasjonsnummer = flettefelt(vedtakFellesfelter.organisasjonsnummer), ), perioder = vedtakFellesfelter.perioder, + utbetalingerPerMndEøs = vedtakFellesfelter.utbetalingerPerMndEøs, ), ) } @@ -53,6 +57,7 @@ data class OpphørMedEndringData( override val delmalData: Delmaler, override val flettefelter: FlettefelterForDokument, override val perioder: List, + override val utbetalingerPerMndEøs: Map? = null, ) : VedtaksbrevData { data class Delmaler( val signaturVedtak: SignaturVedtak, @@ -64,5 +69,6 @@ data class OpphørMedEndringData( val refusjonEosAvklart: RefusjonEøsAvklart?, val refusjonEosUavklart: RefusjonEøsUavklart?, val klage: Boolean, + val utbetalingstabellAutomatiskValutajustering: UtbetalingstabellAutomatiskValutajustering?, ) } diff --git "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Opph\303\270rt.kt" "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Opph\303\270rt.kt" index a2cd8f656c8..85e526d01f5 100644 --- "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Opph\303\270rt.kt" +++ "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Opph\303\270rt.kt" @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs data class Opphørt( override val mal: Brevmal, @@ -43,6 +44,7 @@ data class OpphørtData( override val delmalData: Delmaler, override val flettefelter: FlettefelterForDokumentImpl, override val perioder: List, + override val utbetalingerPerMndEøs: Map? = null, ) : VedtaksbrevData { data class Delmaler( val signaturVedtak: SignaturVedtak, diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/VedtakEndring.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/VedtakEndring.kt index 96ded0563d0..67d500fdcf5 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/VedtakEndring.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/VedtakEndring.kt @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs data class VedtakEndring( override val mal: Brevmal, @@ -20,6 +21,7 @@ data class VedtakEndring( duMåMeldeFraOmEndringer: Boolean = true, duMåMeldeFraOmEndringerEøsSelvstendigRett: Boolean = false, informasjonOmUtbetaling: Boolean = false, + utbetalingstabellAutomatiskValutajustering: UtbetalingstabellAutomatiskValutajustering? = null, ) : this( mal = mal, @@ -47,6 +49,7 @@ data class VedtakEndring( duMaaMeldeFraOmEndringerEosSelvstendigRett = duMåMeldeFraOmEndringerEøsSelvstendigRett, duMaaMeldeFraOmEndringer = duMåMeldeFraOmEndringer, informasjonOmUtbetaling = informasjonOmUtbetaling, + utbetalingstabellAutomatiskValutajustering = utbetalingstabellAutomatiskValutajustering, ), flettefelter = FlettefelterForDokumentImpl( @@ -56,6 +59,7 @@ data class VedtakEndring( organisasjonsnummer = flettefelt(vedtakFellesfelter.organisasjonsnummer), ), perioder = vedtakFellesfelter.perioder, + utbetalingerPerMndEøs = vedtakFellesfelter.utbetalingerPerMndEøs, ), ) } @@ -64,6 +68,7 @@ data class EndringVedtakData( override val delmalData: Delmaler, override val flettefelter: FlettefelterForDokument, override val perioder: List, + override val utbetalingerPerMndEøs: Map? = null, ) : VedtaksbrevData { data class Delmaler( val signaturVedtak: SignaturVedtak, @@ -81,5 +86,6 @@ data class EndringVedtakData( val duMaaMeldeFraOmEndringerEosSelvstendigRett: Boolean, val duMaaMeldeFraOmEndringer: Boolean, val informasjonOmUtbetaling: Boolean, + val utbetalingstabellAutomatiskValutajustering: UtbetalingstabellAutomatiskValutajustering?, ) } diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Vedtaksbrev.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Vedtaksbrev.kt index fb8893eca34..0d9b50d7639 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Vedtaksbrev.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/Vedtaksbrev.kt @@ -1,6 +1,7 @@ package no.nav.familie.ba.sak.kjerne.brev.domene.maler import no.nav.familie.ba.sak.kjerne.brev.domene.maler.brevperioder.BrevPeriode +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetalingMndEøs interface Vedtaksbrev : Brev { override val mal: Brevmal @@ -9,6 +10,7 @@ interface Vedtaksbrev : Brev { interface VedtaksbrevData : BrevData { val perioder: List + val utbetalingerPerMndEøs: Map? } enum class BrevPeriodeType(val apiNavn: String) { @@ -27,6 +29,7 @@ data class VedtakFellesfelter( val søkerNavn: String, val søkerFødselsnummer: String, val perioder: List, + val utbetalingerPerMndEøs: Map?, val organisasjonsnummer: String? = null, val gjelder: String? = null, val korrigertVedtakData: KorrigertVedtakData? = null, diff --git "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/utbetalingE\303\270s/UtbetalingE\303\270s.kt" "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/utbetalingE\303\270s/UtbetalingE\303\270s.kt" new file mode 100644 index 00000000000..19efc4d5b3b --- /dev/null +++ "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/brev/domene/maler/utbetalingE\303\270s/UtbetalingE\303\270s.kt" @@ -0,0 +1,37 @@ +package no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs + +import no.nav.familie.ba.sak.kjerne.beregning.domene.AndelTilkjentYtelse +import no.nav.familie.ba.sak.kjerne.beregning.domene.YtelseType +import no.nav.familie.ba.sak.kjerne.eøs.utenlandskperiodebeløp.UtenlandskPeriodebeløp +import no.nav.familie.ba.sak.kjerne.eøs.valutakurs.Valutakurs + +data class AndelUpbOgValutakurs( + val andelTilkjentYtelse: AndelTilkjentYtelse, + val utenlandskPeriodebeløp: UtenlandskPeriodebeløp?, + val valutakurs: Valutakurs?, +) + +data class UtbetalingMndEøs( + val utbetalinger: List, + val oppsummering: UtbetalingMndEøsOppsummering, +) + +class UtbetalingMndEøsOppsummering( + val summertSatsINorge: Int, + val summertUtbetaltFraAnnetLand: Int?, + val summertUtbetaltFraNorge: Int, +) + +data class UtbetalingEøs( + val fnr: String, + val ytelseType: YtelseType, + val satsINorge: Int, + val utbetaltFraAnnetLand: UtbetaltFraAnnetLand?, + val utbetaltFraNorge: Int, +) + +data class UtbetaltFraAnnetLand( + val beløp: Int, + val valutakode: String, + val beløpINok: Int, +) diff --git "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/e\303\270s/kompetanse/domene/Kompetanse.kt" "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/e\303\270s/kompetanse/domene/Kompetanse.kt" index 24434ea724a..e42e59f23fa 100644 --- "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/e\303\270s/kompetanse/domene/Kompetanse.kt" +++ "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/e\303\270s/kompetanse/domene/Kompetanse.kt" @@ -165,6 +165,7 @@ data class UtfyltKompetanse( val søkersAktivitetsland: String, val barnetsBostedsland: String, val resultat: KompetanseResultat, + val erAnnenForelderOmfattetAvNorskLovgivning: Boolean, ) : IKompetanse fun Kompetanse.tilIKompetanse(): IKompetanse { @@ -181,6 +182,7 @@ fun Kompetanse.tilIKompetanse(): IKompetanse { søkersAktivitetsland = this.søkersAktivitetsland!!, barnetsBostedsland = this.barnetsBostedsland!!, resultat = this.resultat!!, + erAnnenForelderOmfattetAvNorskLovgivning = this.erAnnenForelderOmfattetAvNorskLovgivning!!, ) } else { TomKompetanse( diff --git "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/e\303\270s/utenlandskperiodebel\303\270p/UtenlandskPeriodebel\303\270p.kt" "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/e\303\270s/utenlandskperiodebel\303\270p/UtenlandskPeriodebel\303\270p.kt" index ac70a7d20bf..cd8cb4332eb 100644 --- "a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/e\303\270s/utenlandskperiodebel\303\270p/UtenlandskPeriodebel\303\270p.kt" +++ "b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/e\303\270s/utenlandskperiodebel\303\270p/UtenlandskPeriodebel\303\270p.kt" @@ -15,9 +15,16 @@ import jakarta.persistence.JoinTable import jakarta.persistence.ManyToMany import jakarta.persistence.SequenceGenerator import jakarta.persistence.Table +import no.nav.familie.ba.sak.common.Feil import no.nav.familie.ba.sak.common.YearMonthConverter +import no.nav.familie.ba.sak.ekstern.restDomene.tilKalkulertMånedligBeløp +import no.nav.familie.ba.sak.kjerne.brev.domene.maler.utbetalingEøs.UtbetaltFraAnnetLand import no.nav.familie.ba.sak.kjerne.eøs.differanseberegning.domene.Intervall +import no.nav.familie.ba.sak.kjerne.eøs.differanseberegning.domene.tilKronerPerValutaenhet +import no.nav.familie.ba.sak.kjerne.eøs.differanseberegning.domene.tilMånedligValutabeløp +import no.nav.familie.ba.sak.kjerne.eøs.differanseberegning.domene.times import no.nav.familie.ba.sak.kjerne.eøs.felles.PeriodeOgBarnSkjemaEntitet +import no.nav.familie.ba.sak.kjerne.eøs.valutakurs.Valutakurs import no.nav.familie.ba.sak.kjerne.personident.Aktør import no.nav.familie.ba.sak.kjerne.tidslinje.Periode import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.MånedTidspunkt @@ -97,7 +104,8 @@ data class UtenlandskPeriodebeløp( this.beløp != null && this.intervall != null && this.utbetalingsland != null && - this.barnAktører.isNotEmpty() + this.barnAktører.isNotEmpty() && + this.kalkulertMånedligBeløp != null companion object { val NULL = UtenlandskPeriodebeløp(null, null, emptySet()) @@ -124,6 +132,7 @@ data class UtfyltUtenlandskPeriodebeløp( val valutakode: String, val intervall: Intervall, val utbetalingsland: String, + val kalkulertMånedligBeløp: BigDecimal, ) : IUtenlandskPeriodebeløp fun UtenlandskPeriodebeløp.tilIUtenlandskPeriodebeløp(): IUtenlandskPeriodebeløp { @@ -138,6 +147,7 @@ fun UtenlandskPeriodebeløp.tilIUtenlandskPeriodebeløp(): IUtenlandskPeriodebel valutakode = this.valutakode!!, intervall = this.intervall!!, utbetalingsland = this.utbetalingsland!!, + kalkulertMånedligBeløp = this.kalkulertMånedligBeløp!!, ) } else { TomUtenlandskPeriodebeløp( @@ -157,3 +167,14 @@ fun List.tilTidslinje() = }.tilTidslinje() fun Collection.filtrerErUtfylt() = this.map { it.tilIUtenlandskPeriodebeløp() }.filterIsInstance() + +fun UtenlandskPeriodebeløp.tilUtbetaltFraAnnetLand(valutakurs: Valutakurs?): UtbetaltFraAnnetLand = + try { + UtbetaltFraAnnetLand( + beløp = kalkulertMånedligBeløp!!.toBigInteger().intValueExact(), + valutakode = valutakode!!, + beløpINok = (tilMånedligValutabeløp()!! * valutakurs.tilKronerPerValutaenhet())!!.toBigInteger().intValueExact(), + ) + } catch (exception: NullPointerException) { + throw Feil("Kan ikke opprette UtbetaltFraAnnetLand for periode med utenlandsk periodebeløp da ett eller flere av de påkrevde feltene er null: kalkulertMånedligBeløp = ${tilKalkulertMånedligBeløp()}, valutkode = $valutakode valutakurs = ${valutakurs.tilKronerPerValutaenhet()}") + } diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/Periode.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/Periode.kt index 1f86b9fa38a..ab2265c0009 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/Periode.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/Periode.kt @@ -9,6 +9,7 @@ import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.MånedTidspunkt.Companio import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.Tidsenhet import no.nav.familie.ba.sak.kjerne.tidslinje.tidspunkt.Tidspunkt import no.nav.familie.ba.sak.kjerne.tidslinje.tidsrom.TidspunktClosedRange +import no.nav.familie.ba.sak.kjerne.tidslinje.tidsrom.rangeTo import java.time.LocalDate import java.time.YearMonth @@ -44,3 +45,12 @@ fun periodeAv( fun Collection>.mapInnhold(mapper: (I?) -> R?): Collection> = this.map { Periode(it.fraOgMed, it.tilOgMed, mapper(it.innhold)) } + +fun Periode.splitPerTidsenhet(fremTilTidspunkt: Tidspunkt): List> = + this.fraOgMed.rangeTo(minOf(this.tilOgMed, fremTilTidspunkt)).map { + Periode( + it, + it, + this.innhold, + ) + } diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/komposisjon/TidslinjeJoin.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/komposisjon/TidslinjeJoin.kt index 2ac9ad4f8a1..61606f4e317 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/komposisjon/TidslinjeJoin.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/komposisjon/TidslinjeJoin.kt @@ -18,6 +18,21 @@ fun Map>.outerJoin( } } +fun Map>.outerJoin( + bTidslinjer: Map>, + cTidslinjer: Map>, + kombinator: (A?, B?, C?) -> R?, +): Map> { + val aTidslinjer = this + val alleNøkler = aTidslinjer.keys + bTidslinjer.keys + cTidslinjer.keys + return alleNøkler.associateWith { nøkkel -> + val aTidslinje = aTidslinjer.getOrDefault(nøkkel, TomTidslinje()) + val bTidslinje = bTidslinjer.getOrDefault(nøkkel, TomTidslinje()) + val cTidslinje = cTidslinjer.getOrDefault(nøkkel, TomTidslinje()) + aTidslinje.kombinerMed(bTidslinje, cTidslinje, kombinator) + } +} + fun Map>.leftJoin( høyreTidslinjer: Map>, kombinator: (V?, H?) -> R?, diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/komposisjon/TidslinjeKombinator.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/komposisjon/TidslinjeKombinator.kt index e057c38aa05..93c517a7384 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/komposisjon/TidslinjeKombinator.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/tidslinje/komposisjon/TidslinjeKombinator.kt @@ -114,6 +114,13 @@ fun Collection>.kombiner( .tilVerdi() } +/** + * Extension-metode for å kombinere liste av tidslinjer + * Kombinasjonen baserer seg på å iterere gjennom alle tidspunktene + * fra minste til største fra alle tidslinjene + * Innhold (I) og tidsenhet (T) må være av samme type + * Resultatet er en tidslinje med tidsenhet T og innhold Iterable + */ fun Collection>.kombiner() = this.kombiner { if (it.toList().isNotEmpty()) it else null } @@ -152,6 +159,7 @@ fun Tidslinje.kombinerMedKunVerdi( when { innholdA.harVerdi && innholdB.harVerdi && innholdC.harVerdi -> kombinator(innholdA.verdi, innholdB.verdi, innholdC.verdi).tilVerdi() + else -> Innhold.utenInnhold() } } diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/domene/VedtaksperiodeMedBegrunnelser.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/domene/VedtaksperiodeMedBegrunnelser.kt index 5e34c2be7d2..3ca07dfaf0e 100644 --- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/domene/VedtaksperiodeMedBegrunnelser.kt +++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/domene/VedtaksperiodeMedBegrunnelser.kt @@ -114,6 +114,8 @@ data class VedtaksperiodeMedBegrunnelser( fun harFriteksterUtenStandardbegrunnelser(): Boolean { return (type == Vedtaksperiodetype.OPPHØR || type == Vedtaksperiodetype.AVSLAG) && fritekster.isNotEmpty() && begrunnelser.isEmpty() && eøsBegrunnelser.isEmpty() } + + fun erBegrunnet() = !(begrunnelser.isEmpty() && fritekster.isEmpty() && eøsBegrunnelser.isEmpty()) } fun List.erAlleredeBegrunnetMedBegrunnelse( diff --git a/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevServiceTest.kt b/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevServiceTest.kt index e622b7d33df..47f8f4a8a01 100644 --- a/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevServiceTest.kt +++ b/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevServiceTest.kt @@ -40,6 +40,9 @@ class BrevServiceTest { integrasjonClient = mockk(), testVerktøyService = mockk(), andelTilkjentYtelseRepository = andelTilkjentYtelseRepository, + utenlandskPeriodebeløpRepository = mockk(), + valutakursRepository = mockk(), + kompetanseRepository = mockk(), unleashService = unleashService, ) diff --git a/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevUtilsTest.kt b/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevUtilsTest.kt index d01296de0e5..5d60b9ef8d5 100644 --- a/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevUtilsTest.kt +++ b/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/brev/BrevUtilsTest.kt @@ -1,24 +1,39 @@ package no.nav.familie.ba.sak.kjerne.brev import io.mockk.mockk +import no.nav.familie.ba.sak.common.Feil +import no.nav.familie.ba.sak.common.lagAndelTilkjentYtelse import no.nav.familie.ba.sak.common.lagBehandling import no.nav.familie.ba.sak.common.lagSanityBegrunnelse import no.nav.familie.ba.sak.common.lagSanityEøsBegrunnelse import no.nav.familie.ba.sak.common.lagVedtaksperiodeMedBegrunnelser +import no.nav.familie.ba.sak.common.randomAktør +import no.nav.familie.ba.sak.common.rangeTo import no.nav.familie.ba.sak.common.tilMånedÅr +import no.nav.familie.ba.sak.common.tilMånedÅrMedium +import no.nav.familie.ba.sak.common.toYearMonth import no.nav.familie.ba.sak.datagenerator.vedtak.lagVedtaksbegrunnelse +import no.nav.familie.ba.sak.integrasjoner.økonomi.sats import no.nav.familie.ba.sak.kjerne.behandling.domene.BehandlingType import no.nav.familie.ba.sak.kjerne.behandling.domene.Behandlingsresultat import no.nav.familie.ba.sak.kjerne.behandling.domene.BehandlingÅrsak +import no.nav.familie.ba.sak.kjerne.beregning.domene.YtelseType +import no.nav.familie.ba.sak.kjerne.beregning.domene.tilTidslinjerPerPersonOgType +import no.nav.familie.ba.sak.kjerne.eøs.differanseberegning.domene.Intervall +import no.nav.familie.ba.sak.kjerne.eøs.kompetanse.domene.lagValutakurs +import no.nav.familie.ba.sak.kjerne.eøs.utenlandskperiodebeløp.UtenlandskPeriodebeløp import no.nav.familie.ba.sak.kjerne.grunnlag.personopplysninger.Målform import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.EØSStandardbegrunnelse import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.Standardbegrunnelse import no.nav.familie.ba.sak.kjerne.vedtak.begrunnelser.domene.EØSBegrunnelse import no.nav.familie.ba.sak.kjerne.vedtak.domene.VedtaksbegrunnelseFritekst import no.nav.familie.ba.sak.kjerne.vedtak.vedtaksperiode.Vedtaksperiodetype +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.math.BigDecimal import java.time.LocalDate internal class BrevUtilsTest { @@ -729,4 +744,228 @@ internal class BrevUtilsTest { Assertions.assertEquals(sisteFom.tilMånedÅr(), hentVirkningstidspunktForDødsfallbrev(opphørsperioder, 0L)) } + + @Test + fun `hentUtbetalingerEøs - Skal gi utbetalingsinfo for alle måneder etter endringstidspunktet for ett barn hvor søker har utvidet og småbarnstillegg`() { + val søker = randomAktør() + val barn = randomAktør() + + val endringstidspunkt = LocalDate.now().minusMonths(7) + + val andelerTilkjentYtelse = + listOf( + // Søker har utvidet barnetrygd og småbarnstillegg de siste 12 månedene. + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().toYearMonth(), ytelseType = YtelseType.UTVIDET_BARNETRYGD, aktør = søker, kalkulertUtbetalingsbeløp = sats(YtelseType.UTVIDET_BARNETRYGD)), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().toYearMonth(), ytelseType = YtelseType.SMÅBARNSTILLEGG, aktør = søker, kalkulertUtbetalingsbeløp = sats(YtelseType.SMÅBARNSTILLEGG)), + // Barn har barnetrygd de siste 12 månedene, og fra og med 7 måneder siden har vi kjørt månedlig valutajustering. + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().minusMonths(8).toYearMonth(), aktør = barn, kalkulertUtbetalingsbeløp = 1000), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(7).toYearMonth(), tom = LocalDate.now().minusMonths(7).toYearMonth(), aktør = barn, kalkulertUtbetalingsbeløp = 900), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(6).toYearMonth(), tom = LocalDate.now().minusMonths(6).toYearMonth(), aktør = barn, kalkulertUtbetalingsbeløp = 800), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(5).toYearMonth(), tom = LocalDate.now().minusMonths(5).toYearMonth(), aktør = barn, kalkulertUtbetalingsbeløp = 700), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), aktør = barn, kalkulertUtbetalingsbeløp = 600), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), aktør = barn, kalkulertUtbetalingsbeløp = 500), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), aktør = barn, kalkulertUtbetalingsbeløp = 400), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), aktør = barn, kalkulertUtbetalingsbeløp = 300), + lagAndelTilkjentYtelse(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), aktør = barn, kalkulertUtbetalingsbeløp = 200), + ) + val utenlandskePeriodebeløp = + listOf( + // Barnet mottar det samme beløpet fra det andre landet i hele perioden. + UtenlandskPeriodebeløp(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().toYearMonth(), barnAktører = setOf(barn), beløp = BigDecimal.valueOf(500), valutakode = "SEK", intervall = Intervall.MÅNEDLIG, kalkulertMånedligBeløp = BigDecimal.valueOf(500)), + ) + + val valutakurser = + listOf( + // Barnets valutakurser de siste månedene. Fra og med 7 måneder siden ble kursen endret hver måned. + lagValutakurs(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().minusMonths(8).toYearMonth(), barnAktører = setOf(barn), valutakursdato = LocalDate.now().minusMonths(7), valutakode = "SEK", kurs = BigDecimal.valueOf(1)), + lagValutakurs(fom = LocalDate.now().minusMonths(7).toYearMonth(), tom = LocalDate.now().minusMonths(7).toYearMonth(), barnAktører = setOf(barn), valutakursdato = LocalDate.now().minusMonths(7), valutakode = "SEK", kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().minusMonths(6).toYearMonth(), tom = LocalDate.now().minusMonths(6).toYearMonth(), barnAktører = setOf(barn), valutakursdato = LocalDate.now().minusMonths(6), valutakode = "SEK", kurs = BigDecimal.valueOf(1.3)), + lagValutakurs(fom = LocalDate.now().minusMonths(5).toYearMonth(), tom = LocalDate.now().minusMonths(5).toYearMonth(), barnAktører = setOf(barn), valutakursdato = LocalDate.now().minusMonths(5), valutakode = "SEK", kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), barnAktører = setOf(barn), valutakursdato = LocalDate.now().minusMonths(4), valutakode = "SEK", kurs = BigDecimal.valueOf(1.3)), + lagValutakurs(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), barnAktører = setOf(barn), valutakursdato = LocalDate.now().minusMonths(3), valutakode = "SEK", kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), barnAktører = setOf(barn), valutakursdato = LocalDate.now().minusMonths(2), valutakode = "SEK", kurs = BigDecimal.valueOf(1.3)), + lagValutakurs(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), barnAktører = setOf(barn), valutakursdato = LocalDate.now().minusMonths(1), valutakode = "SEK", kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), barnAktører = setOf(barn), valutakursdato = LocalDate.now(), valutakode = "SEK", kurs = BigDecimal.valueOf(1)), + ) + + val utbetalingerPerMndEøs = hentUtbetalingerPerMndEøs(endringstidspunkt = endringstidspunkt, andelerForVedtaksperioderPerAktørOgType = andelerTilkjentYtelse.tilTidslinjerPerPersonOgType(), utenlandskePeriodebeløp = utenlandskePeriodebeløp, valutakurser = valutakurser) + + // Skal inneholde de siste 8 månedene. + assertThat(utbetalingerPerMndEøs.size).isEqualTo(8) + assertThat(utbetalingerPerMndEøs.keys).isEqualTo(setAvMånedÅrMediumForPeriode(7, 0)) + + // Hver mnd skal inneholde 1 utbetaling for barn og 2 utbetalinger for søker per måned. + assertThat(utbetalingerPerMndEøs.all { it.value.utbetalinger.size == 3 }).isTrue + } + + @Test + fun `hentUtbetalingerEøs - Skal gi utbetalingsinfo for alle måneder etter endringstidspunktet for ett primærlandsbarn og ett sekundærlandsbarn`() { + val sekundærlandsbarn = randomAktør() + val primærlandsbarn = randomAktør() + + val endringstidspunkt = LocalDate.now().minusMonths(4) + + val andelerTilkjentYtelse = + listOf( + // Sekundærlandsbarn har barnetrygd de siste 12 månedene, og fra og med 5 måneder siden har vi kjørt månedlig valutajustering. + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().minusMonths(5).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 1000), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 600), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 500), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 400), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 300), + lagAndelTilkjentYtelse(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 200), + // Primærlandsbarn har barntrygd de siste 12 månedene + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().toYearMonth(), aktør = primærlandsbarn, kalkulertUtbetalingsbeløp = 1054), + ) + val utenlandskePeriodebeløp = + listOf( + // Sekundærlandsbarnet mottar to forskjellige beløp fra det andre landet i perioden. + UtenlandskPeriodebeløp(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), barnAktører = setOf(sekundærlandsbarn), beløp = BigDecimal.valueOf(500), valutakode = "SEK", intervall = Intervall.MÅNEDLIG, kalkulertMånedligBeløp = BigDecimal.valueOf(500)), + UtenlandskPeriodebeløp(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().toYearMonth(), barnAktører = setOf(sekundærlandsbarn), beløp = BigDecimal.valueOf(550), valutakode = "SEK", intervall = Intervall.MÅNEDLIG, kalkulertMånedligBeløp = BigDecimal.valueOf(550)), + ) + + val valutakurser = + listOf( + // Barnets valutakurser de siste månedene. Fra og med 5 måneder siden ble kursen endret hver måned. + lagValutakurs(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), barnAktører = setOf(sekundærlandsbarn), valutakursdato = LocalDate.now().minusMonths(4), valutakode = "SEK", kurs = BigDecimal.valueOf(1.3)), + lagValutakurs(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), barnAktører = setOf(sekundærlandsbarn), valutakursdato = LocalDate.now().minusMonths(3), valutakode = "SEK", kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), barnAktører = setOf(sekundærlandsbarn), valutakursdato = LocalDate.now().minusMonths(2), valutakode = "SEK", kurs = BigDecimal.valueOf(1.3)), + lagValutakurs(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), barnAktører = setOf(sekundærlandsbarn), valutakursdato = LocalDate.now().minusMonths(1), valutakode = "SEK", kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), barnAktører = setOf(sekundærlandsbarn), valutakursdato = LocalDate.now(), valutakode = "SEK", kurs = BigDecimal.valueOf(1)), + ) + + val utbetalingerPerMndEøs = hentUtbetalingerPerMndEøs(endringstidspunkt = endringstidspunkt, andelerForVedtaksperioderPerAktørOgType = andelerTilkjentYtelse.tilTidslinjerPerPersonOgType(), utenlandskePeriodebeløp = utenlandskePeriodebeløp, valutakurser = valutakurser) + + // Skal inneholde de siste 8 månedene. + assertThat(utbetalingerPerMndEøs.size).isEqualTo(5) + assertThat(utbetalingerPerMndEøs.keys).isEqualTo(setAvMånedÅrMediumForPeriode(4, 0)) + + // Hver måned skal inneholde 1 utbetaling for sekundærlandsbarn og 1 utbetaling for primærlandsbarn. + assertThat(utbetalingerPerMndEøs.all { it.value.utbetalinger.size == 2 }).isTrue + } + + @Test + fun `hentUtbetalingerEøs - Skal gi utbetalingsinfo for alle måneder etter endringstidspunktet for to sekundærlandsbarn hvor det ene barnet mottar barnetrygd fra midt i endringsperioden`() { + val sekundærlandsbarn = randomAktør() + val sekundærlandsbarn2 = randomAktør() + + val endringstidspunkt = LocalDate.now().minusMonths(4) + + val andelerTilkjentYtelse = + listOf( + // Sekundærlandsbarn har barnetrygd de siste 12 månedene, og fra og med 5 måneder siden har vi kjørt månedlig valutajustering. + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().minusMonths(5).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 1000), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 600), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 500), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 400), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 300), + lagAndelTilkjentYtelse(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 200), + // Det andre sekundærlandsbarnet har barntrygd de siste 3 månedene + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), aktør = sekundærlandsbarn2, kalkulertUtbetalingsbeløp = 1000), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), aktør = sekundærlandsbarn2, kalkulertUtbetalingsbeløp = 900), + lagAndelTilkjentYtelse(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), aktør = sekundærlandsbarn2, kalkulertUtbetalingsbeløp = 800), + ) + val utenlandskePeriodebeløp = + listOf( + // Sekundærlandsbarnet mottar to forskjellige beløp fra det andre landet i perioden. + UtenlandskPeriodebeløp(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), barnAktører = setOf(sekundærlandsbarn), beløp = BigDecimal.valueOf(500), valutakode = "SEK", intervall = Intervall.MÅNEDLIG, kalkulertMånedligBeløp = BigDecimal.valueOf(500)), + // Sekundærlandsbarn 1 og 2 mottar det samme beløpet fra det andre landet + UtenlandskPeriodebeløp(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().toYearMonth(), barnAktører = setOf(sekundærlandsbarn, sekundærlandsbarn2), beløp = BigDecimal.valueOf(550), valutakode = "SEK", intervall = Intervall.MÅNEDLIG, kalkulertMånedligBeløp = BigDecimal.valueOf(550)), + ) + + val valutakurser = + listOf( + // Barnets valutakurser de siste månedene. Fra og med 5 måneder siden ble kursen endret hver måned. + lagValutakurs(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), barnAktører = setOf(sekundærlandsbarn), valutakursdato = LocalDate.now().minusMonths(4), valutakode = "SEK", kurs = BigDecimal.valueOf(1.3)), + lagValutakurs(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), barnAktører = setOf(sekundærlandsbarn), valutakursdato = LocalDate.now().minusMonths(3), valutakode = "SEK", kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), barnAktører = setOf(sekundærlandsbarn, sekundærlandsbarn2), valutakursdato = LocalDate.now().minusMonths(2), valutakode = "SEK", kurs = BigDecimal.valueOf(1.3)), + lagValutakurs(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), barnAktører = setOf(sekundærlandsbarn, sekundærlandsbarn2), valutakursdato = LocalDate.now().minusMonths(1), valutakode = "SEK", kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), barnAktører = setOf(sekundærlandsbarn, sekundærlandsbarn2), valutakursdato = LocalDate.now(), valutakode = "SEK", kurs = BigDecimal.valueOf(1)), + ) + + val utbetalingerPerMndEøs = hentUtbetalingerPerMndEøs(endringstidspunkt = endringstidspunkt, andelerForVedtaksperioderPerAktørOgType = andelerTilkjentYtelse.tilTidslinjerPerPersonOgType(), utenlandskePeriodebeløp = utenlandskePeriodebeløp, valutakurser = valutakurser) + + // Skal inneholde de siste 8 månedene. + assertThat(utbetalingerPerMndEøs.size).isEqualTo(5) + assertThat(utbetalingerPerMndEøs.keys).isEqualTo(setAvMånedÅrMediumForPeriode(fraAntallMndSiden = 4, tilAndtalMndSiden = 0)) + + // De første 2 månedene skal kun inneholde utbetaling for det første sekundærlandsbarnet. + assertThat(utbetalingerPerMndEøs.filterKeys { setAvMånedÅrMediumForPeriode(fraAntallMndSiden = 4, tilAndtalMndSiden = 3).contains(it) }.values.all { it.utbetalinger.size == 1 }).isTrue + + // De siste 3 månedene skal inneholde utbetalinger for begge sekundærlandsbarna. + assertThat(utbetalingerPerMndEøs.filterKeys { setAvMånedÅrMediumForPeriode(fraAntallMndSiden = 2, tilAndtalMndSiden = 0).contains(it) }.values.all { it.utbetalinger.size == 2 }).isTrue + } + + @Test + fun `hentUtbetalingerEøs - Skal kaste feil dersom utbetalt fra annet land, valutakode eller valutakurs er null`() { + val sekundærlandsbarn = randomAktør() + + val endringstidspunkt = LocalDate.now().minusMonths(4) + + val andelerTilkjentYtelse = + listOf( + // Sekundærlandsbarn har barnetrygd de siste 12 månedene, og fra og med 5 måneder siden har vi kjørt månedlig valutajustering. + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().minusMonths(5).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 1000), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 600), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 500), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 400), + lagAndelTilkjentYtelse(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 300), + lagAndelTilkjentYtelse(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), aktør = sekundærlandsbarn, kalkulertUtbetalingsbeløp = 200), + ) + val utenlandskePeriodebeløp = + listOf( + // Sekundærlandsbarnet har to perioder med utenlandsk periodebeløp men disse mangler beløp, intervall og valutakode. + UtenlandskPeriodebeløp(fom = LocalDate.now().minusMonths(12).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), barnAktører = setOf(sekundærlandsbarn)), + UtenlandskPeriodebeløp(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().toYearMonth(), barnAktører = setOf(sekundærlandsbarn)), + ) + + val valutakurser = + listOf( + // Barnets valutakurser de siste månedene. Mangler kurs. + lagValutakurs(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), barnAktører = setOf(sekundærlandsbarn)), + lagValutakurs(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), barnAktører = setOf(sekundærlandsbarn)), + lagValutakurs(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), barnAktører = setOf(sekundærlandsbarn)), + lagValutakurs(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), barnAktører = setOf(sekundærlandsbarn)), + lagValutakurs(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), barnAktører = setOf(sekundærlandsbarn)), + ) + + assertThrows { hentUtbetalingerPerMndEøs(endringstidspunkt = endringstidspunkt, andelerForVedtaksperioderPerAktørOgType = andelerTilkjentYtelse.tilTidslinjerPerPersonOgType(), utenlandskePeriodebeløp = utenlandskePeriodebeløp, valutakurser = valutakurser) } + } + + @Test + fun `skalHenteUtbetalingerEøs - skal returne true når det finnes valutakurser etter endringstidspunktet`() { + val endringstidspunkt = LocalDate.now().minusMonths(2) + val barn = randomAktør() + + val valutakurser = + listOf( + lagValutakurs(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), barnAktører = setOf(barn), kurs = BigDecimal.valueOf(1)), + lagValutakurs(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), barnAktører = setOf(barn), kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().minusMonths(2).toYearMonth(), tom = LocalDate.now().minusMonths(2).toYearMonth(), barnAktører = setOf(barn), kurs = BigDecimal.valueOf(1.1)), + lagValutakurs(fom = LocalDate.now().minusMonths(1).toYearMonth(), tom = LocalDate.now().minusMonths(1).toYearMonth(), barnAktører = setOf(barn), kurs = BigDecimal.valueOf(1.2)), + lagValutakurs(fom = LocalDate.now().toYearMonth(), tom = LocalDate.now().toYearMonth(), barnAktører = setOf(barn), kurs = BigDecimal.valueOf(1.3)), + ) + + assertThat(skalHenteUtbetalingerEøs(endringstidspunkt = endringstidspunkt, valutakurser = valutakurser)).isTrue + } + + @Test + fun `skalHenteUtbetalingerEøs - skal returne false når det ikke finnes valutakurser etter endringstidspunktet`() { + val endringstidspunkt = LocalDate.now().minusMonths(2) + val barn = randomAktør() + + val valutakurser = + listOf( + lagValutakurs(fom = LocalDate.now().minusMonths(4).toYearMonth(), tom = LocalDate.now().minusMonths(4).toYearMonth(), barnAktører = setOf(barn), kurs = BigDecimal.valueOf(1)), + lagValutakurs(fom = LocalDate.now().minusMonths(3).toYearMonth(), tom = LocalDate.now().minusMonths(3).toYearMonth(), barnAktører = setOf(barn), kurs = BigDecimal.valueOf(1.2)), + ) + + assertThat(skalHenteUtbetalingerEøs(endringstidspunkt = endringstidspunkt, valutakurser = valutakurser)).isFalse + } } + +private fun setAvMånedÅrMediumForPeriode( + fraAntallMndSiden: Long, + tilAndtalMndSiden: Long, +): Set = + LocalDate.now().minusMonths(fraAntallMndSiden).toYearMonth().rangeTo(LocalDate.now().minusMonths(tilAndtalMndSiden).toYearMonth()).map { it.tilMånedÅrMedium() }.toSet()