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

Fikse bostatus- og inntektsmapping i fbm forskuddsberegning #113

Merged
merged 7 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/kotlin/no/nav/bidrag/behandling/BidragBehandling.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package no.nav.bidrag.behandling

import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import no.nav.security.token.support.spring.api.EnableJwtTokenValidation
import org.slf4j.Logger
import org.slf4j.LoggerFactory
Expand All @@ -10,6 +13,11 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfi

const val PROFILE_NAIS = "nais"
val SECURE_LOGGER: Logger = LoggerFactory.getLogger("secureLogger")
val objectmapper =
ObjectMapper().findAndRegisterModules().registerKotlinModule()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true)
.configure(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES, false)

@SpringBootApplication(exclude = [SecurityAutoConfiguration::class, ManagementWebSecurityAutoConfiguration::class])
@EnableJwtTokenValidation(ignore = ["org.springframework", "org.springdoc"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,30 @@ enum class Kilde {

@Schema(enumAsRef = true)
enum class OpplysningerType {
INNTEKTSOPPLYSNINGER,
/**Typer for opplysninger som er bearbeidet av frontend eller bidrag-inntekt*/
INNTEKT_BEARBEIDET,
BOFORHOLD_BEARBEIDET,

/**Typer for opplysninger hentet fra bidrag-grunnlag*/
INNTEKT,
ARBEIDSFORHOLD,
HUSSTANDSMEDLEMMER,
SIVILSTAND,

@Deprecated("", replaceWith = ReplaceWith("BOFORHOLD_BEARBEIDET"))
BOFORHOLD,

@Deprecated("", replaceWith = ReplaceWith("INNTEKT_BEARBEIDET"))
INNTEKTSOPPLYSNINGER,
}

fun OpplysningerType.getOrMigrate() =
when (this) {
OpplysningerType.BOFORHOLD -> OpplysningerType.BOFORHOLD_BEARBEIDET
OpplysningerType.INNTEKTSOPPLYSNINGER -> OpplysningerType.INNTEKT_BEARBEIDET
else -> this
}

@Schema(enumAsRef = true)
enum class Behandlingstype {
BIDRAG,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package no.nav.bidrag.behandling.database.datamodell

import com.fasterxml.jackson.module.kotlin.readValue
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.EnumType
Expand All @@ -10,6 +11,13 @@ import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne
import no.nav.bidrag.behandling.database.opplysninger.BoforholdBearbeidet
import no.nav.bidrag.behandling.database.opplysninger.InntektGrunnlag
import no.nav.bidrag.behandling.database.opplysninger.InntektsopplysningerBearbeidet
import no.nav.bidrag.behandling.objectmapper
import no.nav.bidrag.transport.behandling.grunnlag.response.ArbeidsforholdDto
import no.nav.bidrag.transport.behandling.grunnlag.response.RelatertPersonDto
import no.nav.bidrag.transport.behandling.grunnlag.response.SivilstandDto
import java.util.Date

@Entity(name = "opplysninger")
Expand All @@ -27,3 +35,16 @@ class Opplysninger(
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
)

inline fun <reified T> Opplysninger?.hentData(): T? =
when (this?.opplysningerType) {
OpplysningerType.INNTEKTSOPPLYSNINGER, OpplysningerType.INNTEKT_BEARBEIDET -> konverterData<InntektsopplysningerBearbeidet>() as T
OpplysningerType.BOFORHOLD, OpplysningerType.BOFORHOLD_BEARBEIDET -> konverterData<BoforholdBearbeidet>() as T
OpplysningerType.HUSSTANDSMEDLEMMER -> konverterData<List<RelatertPersonDto>>() as T
OpplysningerType.SIVILSTAND -> konverterData<List<SivilstandDto>>() as T
OpplysningerType.ARBEIDSFORHOLD -> konverterData<List<ArbeidsforholdDto>>() as T
OpplysningerType.INNTEKT -> konverterData<List<InntektGrunnlag>>() as T
else -> null
}

inline fun <reified T> Opplysninger?.konverterData(): T? = this?.data?.let { objectmapper.readValue(it) }
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package no.nav.bidrag.behandling.database.opplysninger

import no.nav.bidrag.domene.enums.person.Bostatuskode
import no.nav.bidrag.domene.enums.person.Sivilstandskode
import no.nav.bidrag.transport.behandling.grunnlag.response.ArbeidsforholdDto
import no.nav.bidrag.transport.behandling.grunnlag.response.BarnetilleggDto
import no.nav.bidrag.transport.behandling.grunnlag.response.UtvidetBarnetrygdOgSmaabarnstilleggDto
import no.nav.bidrag.transport.behandling.inntekt.response.SummertÅrsinntekt
import java.time.LocalDate
import java.time.LocalDateTime

data class BoforholdBearbeidet(
val husstand: List<BoforholdHusstandBearbeidet> = emptyList(),
val sivilstand: List<SivilstandBearbeidet> = emptyList(),
)

data class SivilstandBearbeidet(
val datoFom: LocalDate,
val datoTom: LocalDate? = null,
val sivilstand: Sivilstandskode,
)

data class BoforholdHusstandBearbeidet(
val foedselsdato: LocalDate?,
val ident: String,
val navn: String?,
val perioder: List<BoforholdBearbeidetPeriode> = emptyList(),
)

data class BoforholdBearbeidetPeriode(
val fraDato: LocalDateTime,
val tilDato: LocalDateTime?,
val bostatus: Bostatuskode,
)

data class InntektsopplysningerBearbeidet(
val inntekt: List<InntektBearbeidet> = emptyList(),
val utvidetbarnetrygd: List<UtvidetBarnetrygdOgSmaabarnstilleggDto> = emptyList(),
val barnetillegg: List<BarnetilleggDto> = emptyList(),
val arbeidsforhold: List<ArbeidsforholdDto> = emptyList(),
)

data class InntektBearbeidet(
val ident: String,
val versjon: String?,
val summertAarsinntektListe: List<SummertÅrsinntekt>,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package no.nav.bidrag.behandling.database.opplysninger

import no.nav.bidrag.transport.behandling.grunnlag.response.AinntektDto
import no.nav.bidrag.transport.behandling.grunnlag.response.BarnetilleggDto
import no.nav.bidrag.transport.behandling.grunnlag.response.BarnetilsynDto
import no.nav.bidrag.transport.behandling.grunnlag.response.KontantstotteDto
import no.nav.bidrag.transport.behandling.grunnlag.response.OvergangsstonadDto
import no.nav.bidrag.transport.behandling.grunnlag.response.SkattegrunnlagDto
import no.nav.bidrag.transport.behandling.grunnlag.response.UtvidetBarnetrygdOgSmaabarnstilleggDto

data class InntektGrunnlag(
val ainntektListe: List<AinntektDto> = emptyList(),
val skattegrunnlagListe: List<SkattegrunnlagDto> = emptyList(),
val ubstListe: List<UtvidetBarnetrygdOgSmaabarnstilleggDto> = emptyList(),
val barnetilleggListe: List<BarnetilleggDto> = emptyList(),
val kontantstotteListe: List<KontantstotteDto> = emptyList(),
val overgangsstonadListe: List<OvergangsstonadDto> = emptyList(),
val barnetilsynListe: List<BarnetilsynDto> = emptyList(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import java.time.LocalDate
data class OppdatereVirkningstidspunktRequest(
val virkningstidspunktsbegrunnelseIVedtakOgNotat: String? = null,
val virkningstidspunktsbegrunnelseKunINotat: String? = null,
@Schema(name = "årsak")
val årsak: ForskuddAarsakType? = null,
@Schema(type = "string", format = "date", example = "2025-01-25")
@JsonFormat(pattern = "yyyy-MM-dd")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import java.time.LocalDate
data class VirkningstidspunktResponse(
val virkningstidspunktsbegrunnelseIVedtakOgNotat: String? = null,
val virkningstidspunktsbegrunnelseKunINotat: String? = null,
@Schema(name = "årsak")
val årsak: ForskuddAarsakType? = null,
@Schema(type = "string", format = "date", example = "2025-01-25")
@JsonFormat(pattern = "yyyy-MM-dd")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package no.nav.bidrag.behandling.service

import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import no.nav.bidrag.behandling.database.datamodell.Behandling
import no.nav.bidrag.behandling.database.datamodell.Husstandsbarn
import no.nav.bidrag.behandling.database.datamodell.OpplysningerType
import no.nav.bidrag.behandling.database.datamodell.Rolle
import no.nav.bidrag.behandling.database.datamodell.Sivilstand
import no.nav.bidrag.behandling.database.datamodell.hentData
import no.nav.bidrag.behandling.database.opplysninger.BoforholdBearbeidet
import no.nav.bidrag.behandling.database.opplysninger.BoforholdHusstandBearbeidet
import no.nav.bidrag.behandling.database.opplysninger.InntektsopplysningerBearbeidet
import no.nav.bidrag.behandling.database.opplysninger.SivilstandBearbeidet
import no.nav.bidrag.behandling.dto.notat.Arbeidsforhold
import no.nav.bidrag.behandling.dto.notat.Barnetillegg
import no.nav.bidrag.behandling.dto.notat.Boforhold
Expand All @@ -27,38 +28,28 @@ import no.nav.bidrag.behandling.dto.notat.Virkningstidspunkt
import no.nav.bidrag.behandling.transformers.toLocalDate
import no.nav.bidrag.commons.security.utils.TokenUtils
import no.nav.bidrag.commons.service.organisasjon.SaksbehandlernavnProvider
import no.nav.bidrag.domene.enums.person.Bostatuskode
import no.nav.bidrag.domene.enums.person.Sivilstandskode
import no.nav.bidrag.domene.enums.rolle.Rolletype
import no.nav.bidrag.domene.ident.Personident
import no.nav.bidrag.domene.tid.ÅrMånedsperiode
import no.nav.bidrag.transport.behandling.grunnlag.response.ArbeidsforholdDto
import org.springframework.stereotype.Service
import java.time.LocalDate
import java.time.YearMonth

private val objectmapper = ObjectMapper().findAndRegisterModules().registerKotlinModule()

@Service
class NotatOpplysningerService(
private val behandlingService: BehandlingService,
private val opplysningerService: OpplysningerService,
) {
fun hentNotatOpplysninger(behandlingId: Long): NotatDto {
val behandling = behandlingService.hentBehandlingById(behandlingId)
val opplysningerBoforholdJson =
opplysningerService.hentSistAktiv(behandlingId, OpplysningerType.BOFORHOLD)
?.let { objectmapper.readTree(it.data) }
val husstandGrunnlag = opplysningerBoforholdJson?.get("husstand")?.toList() ?: emptyList()
val sivilstandGrunnlag =
opplysningerBoforholdJson?.get("sivilstand")?.toList() ?: emptyList()
val opplysningerBoforhold =
opplysningerService.hentSistAktiv(behandlingId, OpplysningerType.BOFORHOLD_BEARBEIDET)
?.hentData()
?: BoforholdBearbeidet()

val opplysningerInntektJson =
opplysningerService.hentSistAktiv(behandlingId, OpplysningerType.INNTEKTSOPPLYSNINGER)
?.let { objectmapper.readTree(it.data) }
val arbeidsforhold: List<ArbeidsforholdDto> =
opplysningerInntektJson?.get("arbeidsforhold")?.toString()
?.let { objectmapper.readValue(it) } ?: emptyList()
val opplysningerInntekt: InntektsopplysningerBearbeidet =
opplysningerService.hentSistAktiv(behandlingId, OpplysningerType.INNTEKT_BEARBEIDET)
.hentData() ?: InntektsopplysningerBearbeidet()
return NotatDto(
saksnummer = behandling.saksnummer,
saksbehandlerNavn =
Expand All @@ -68,18 +59,22 @@ class NotatOpplysningerService(
boforhold =
Boforhold(
notat = behandling.tilNotatBoforhold(),
sivilstand = behandling.tilSivilstand(sivilstandGrunnlag),
sivilstand = behandling.tilSivilstand(opplysningerBoforhold.sivilstand),
barn =
behandling.husstandsbarn.sortedBy { it.ident }
.map { it.tilBoforholdBarn(husstandGrunnlag) },
.map { it.tilBoforholdBarn(opplysningerBoforhold.husstand) },
),
parterISøknad = behandling.roller.map(Rolle::tilPartISøknad),
inntekter =
Inntekter(
notat = behandling.tilNotatInntekt(),
inntekterPerRolle =
behandling.roller.map {
behandling.hentInntekterForIdent(it.ident!!, it.rolletype, arbeidsforhold)
behandling.hentInntekterForIdent(
it.ident!!,
it.rolletype,
opplysningerInntekt.arbeidsforhold,
)
},
),
vedtak = emptyList(),
Expand All @@ -105,24 +100,20 @@ private fun Behandling.tilNotatInntekt() =
intern = inntektsbegrunnelseKunINotat,
)

private fun Behandling.tilSivilstand(sivilstandGrunnlag: List<JsonNode>) =
private fun Behandling.tilSivilstand(sivilstandOpplysninger: List<SivilstandBearbeidet>) =
SivilstandNotat(
opplysningerBruktTilBeregning =
sivilstand.sortedBy { it.datoFom }
.map(Sivilstand::tilSivilstandsperiode),
opplysningerFraFolkeregisteret =
sivilstandGrunnlag.map { periode ->
sivilstandOpplysninger.map { periode ->
OpplysningerFraFolkeregisteret(
periode =
ÅrMånedsperiode(
periode.get("datoFom").asText().takeIf { date -> date != "null" }
?.let { date -> LocalDate.parse(date) } ?: LocalDate.now(),
periode.get("datoTom").asText().takeIf { date -> date != "null" }
?.let { date -> LocalDate.parse(date) },
periode.datoFom,
periode.datoTom,
),
status =
periode.get("sivilstand")?.asText()
?.let { it1 -> Sivilstandskode.valueOf(it1) },
status = periode.sivilstand,
)
}.sortedBy { it.periode?.fom },
)
Expand All @@ -148,29 +139,26 @@ private fun Behandling.tilVirkningstidspunkt() =
notat = tilNotatVirkningstidspunkt(),
)

private fun Husstandsbarn.tilBoforholdBarn(husstandGrunnlag: List<JsonNode>) =
private fun Husstandsbarn.tilBoforholdBarn(opplysningerBoforhold: List<BoforholdHusstandBearbeidet>) =
BoforholdBarn(
navn = navn!!,
fødselsdato =
foedselsdato
?: hentPersonFødselsdato(ident),
opplysningerFraFolkeregisteret =
husstandGrunnlag.filter {
it.get("ident").textValue() == this.ident
opplysningerBoforhold.filter {
it.ident == this.ident
}.flatMap {
it.get("perioder")?.toList()?.map { periode ->
it.perioder.map { periode ->
OpplysningerFraFolkeregisteret(
periode =
ÅrMånedsperiode(
LocalDate.parse(periode.get("fraDato").asText().split("T")[0]),
periode.get("tilDato").asText().takeIf { date -> date != "null" }
?.let { date -> LocalDate.parse(date.split("T")[0]) },
periode.fraDato.toLocalDate(),
periode.tilDato?.toLocalDate(),
),
status =
periode.get("bostatus")?.asText()
?.let { it1 -> Bostatuskode.valueOf(it1) },
status = periode.bostatus,
)
} ?: emptyList()
}
},
opplysningerBruktTilBeregning =
perioder.sortedBy { it.datoFom }.map { periode ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package no.nav.bidrag.behandling.service
import no.nav.bidrag.behandling.behandlingNotFoundException
import no.nav.bidrag.behandling.database.datamodell.Opplysninger
import no.nav.bidrag.behandling.database.datamodell.OpplysningerType
import no.nav.bidrag.behandling.database.datamodell.getOrMigrate
import no.nav.bidrag.behandling.database.repository.BehandlingRepository
import no.nav.bidrag.behandling.database.repository.OpplysningerRepository
import org.springframework.stereotype.Service
Expand All @@ -28,7 +29,7 @@ class OpplysningerService(
return opplysningerRepository.save<Opplysninger>(
Opplysninger(
it,
opplysningerType,
opplysningerType.getOrMigrate(),
data,
hentetDato,
),
Expand All @@ -42,6 +43,6 @@ class OpplysningerService(
): Opplysninger? =
opplysningerRepository.findTopByBehandlingIdAndOpplysningerTypeOrderByTsDescIdDesc(
behandlingId,
opplysningerType,
opplysningerType.getOrMigrate(),
)
}
Loading