diff --git a/pom.xml b/pom.xml index c4d655163..9bc57fd7d 100644 --- a/pom.xml +++ b/pom.xml @@ -16,8 +16,8 @@ 21 2.0.21 - 2024.11.25.120349 - 2024.11.25.120521 + 2024.11.28.115919 + 2024.11.29.125938 2.3.232 8.0 3.2.0 diff --git a/src/main/kotlin/no/nav/bidrag/behandling/controller/v2/GebyrController.kt b/src/main/kotlin/no/nav/bidrag/behandling/controller/v2/GebyrController.kt new file mode 100644 index 000000000..7978d67db --- /dev/null +++ b/src/main/kotlin/no/nav/bidrag/behandling/controller/v2/GebyrController.kt @@ -0,0 +1,50 @@ +package no.nav.bidrag.behandling.controller.v2 + +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.security.SecurityRequirement +import jakarta.validation.Valid +import no.nav.bidrag.behandling.dto.v2.gebyr.OppdaterGebyrResponsDto +import no.nav.bidrag.behandling.dto.v2.gebyr.OppdaterManueltGebyrDto +import no.nav.bidrag.behandling.service.BehandlingService +import no.nav.bidrag.behandling.service.GebyrService +import no.nav.bidrag.behandling.transformers.behandling.tilDto +import no.nav.bidrag.behandling.transformers.gebyr.tilDto +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.PutMapping +import org.springframework.web.bind.annotation.RequestBody + +@BehandlingRestControllerV2 +class GebyrController( + private val gebyrService: GebyrService, + private val behandlingService: BehandlingService, +) { + @Suppress("unused") + @PutMapping("/behandling/{behandlingsid}/gebyr") + @Operation( + description = + "Oppdater manuelt overstyr gebyr for en behandling.", + security = [SecurityRequirement(name = "bearer-key")], + ) + fun oppdaterManueltOverstyrtGebyr( + @PathVariable behandlingsid: Long, + @Valid + @RequestBody(required = true) + request: OppdaterManueltGebyrDto, + ): OppdaterGebyrResponsDto { + gebyrService.oppdaterManueltOverstyrtGebyr(behandlingService.hentBehandlingById(behandlingsid), request) + return tilRespons(behandlingsid, request.rolleId) + } + + private fun tilRespons( + behandlingsId: Long, + rolleId: Long, + ): OppdaterGebyrResponsDto { + val behandling = behandlingService.hentBehandlingById(behandlingsId) + return behandling.roller.find { it.id == rolleId }!!.let { rolle -> + OppdaterGebyrResponsDto( + rolle.tilDto(), + rolle.manueltOverstyrtGebyr?.tilDto(), + ) + } + } +} diff --git a/src/main/kotlin/no/nav/bidrag/behandling/database/datamodell/Rolle.kt b/src/main/kotlin/no/nav/bidrag/behandling/database/datamodell/Rolle.kt index 969a9d053..2988019ce 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/database/datamodell/Rolle.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/database/datamodell/Rolle.kt @@ -23,8 +23,10 @@ import no.nav.bidrag.domene.enums.rolle.Rolletype import no.nav.bidrag.domene.ident.Personident import no.nav.bidrag.transport.felles.commonObjectmapper import org.hibernate.annotations.ColumnTransformer +import org.hibernate.annotations.JdbcTypeCode import org.hibernate.annotations.SQLDelete import org.hibernate.annotations.SQLRestriction +import org.hibernate.type.SqlTypes import java.math.BigDecimal import java.time.LocalDate import java.time.LocalDateTime @@ -52,6 +54,11 @@ open class Rolle( @Deprecated("Migrere til Person.navn") open val navn: String? = null, open val deleted: Boolean = false, + open var harGebyrsøknad: Boolean = false, + @Column(columnDefinition = "jsonb") + @ColumnTransformer(write = "?::jsonb") + @JdbcTypeCode(SqlTypes.JSON) + open var manueltOverstyrtGebyr: RolleManueltOverstyrtGebyr? = null, open var innbetaltBeløp: BigDecimal? = null, @Column(name = "forrige_sivilstandshistorikk", columnDefinition = "jsonb") @ColumnTransformer(write = "?::jsonb") @@ -87,6 +94,12 @@ open class Rolle( "Rolle(id=$id, behandling=${behandling.id}, rolletype=$rolletype, ident=$ident, fødselsdato=$fødselsdato, opprettet=$opprettet, navn=$navn, deleted=$deleted, innbetaltBeløp=$innbetaltBeløp)" } +data class RolleManueltOverstyrtGebyr( + val overstyrGebyr: Boolean = true, + val ilagtGebyr: Boolean? = false, + val begrunnelse: String? = null, +) + fun Rolle.tilPersonident() = ident?.let { Personident(it) } fun Rolle.tilNyestePersonident() = ident?.let { hentNyesteIdent(it) } diff --git a/src/main/kotlin/no/nav/bidrag/behandling/dto/v1/behandling/OpprettRolleDto.kt b/src/main/kotlin/no/nav/bidrag/behandling/dto/v1/behandling/OpprettRolleDto.kt index 2f5728ea0..5735eb0f2 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/dto/v1/behandling/OpprettRolleDto.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/dto/v1/behandling/OpprettRolleDto.kt @@ -29,4 +29,5 @@ data class OpprettRolleDto( val innbetaltBeløp: BigDecimal? = null, val erSlettet: Boolean = false, val erUkjent: Boolean = false, + val harGebyrsøknad: Boolean = false, ) diff --git a/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/behandling/BehandlingDtoV2.kt b/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/behandling/BehandlingDtoV2.kt index ea7efdc8a..736050e55 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/behandling/BehandlingDtoV2.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/behandling/BehandlingDtoV2.kt @@ -9,6 +9,8 @@ import no.nav.bidrag.behandling.dto.v1.behandling.RolleDto import no.nav.bidrag.behandling.dto.v1.behandling.SivilstandDto import no.nav.bidrag.behandling.dto.v1.behandling.VirkningstidspunktDto import no.nav.bidrag.behandling.dto.v2.boforhold.BoforholdDtoV2 +import no.nav.bidrag.behandling.dto.v2.gebyr.GebyrValideringsfeilDto +import no.nav.bidrag.behandling.dto.v2.gebyr.ManueltOverstyrGebyrDto import no.nav.bidrag.behandling.dto.v2.inntekt.InntekterDtoV2 import no.nav.bidrag.behandling.dto.v2.inntekt.InntektspostDtoV2 import no.nav.bidrag.behandling.dto.v2.samvær.SamværDto @@ -112,6 +114,7 @@ data class BehandlingDtoV2( val virkningstidspunkt: VirkningstidspunktDto, val inntekter: InntekterDtoV2, val boforhold: BoforholdDtoV2, + val gebyr: GebyrDto? = null, val aktiveGrunnlagsdata: AktiveGrunnlagsdata, val ikkeAktiverteEndringerIGrunnlagsdata: IkkeAktiveGrunnlagsdata, val feilOppståttVedSisteGrunnlagsinnhenting: Set? = null, @@ -124,6 +127,25 @@ data class BehandlingDtoV2( val vedtakstypeVisningsnavn get() = vedtakstype.visningsnavnIntern(opprinneligVedtakstype) } +data class GebyrDto( + val gebyrRoller: List, + val valideringsfeil: List? = null, +) + +data class GebyrRolleDto( + val inntekt: GebyrInntektDto, + val manueltOverstyrtGebyr: ManueltOverstyrGebyrDto? = null, + val beregnetIlagtGebyr: Boolean, + val rolle: RolleDto, +) { + data class GebyrInntektDto( + val skattepliktigInntekt: BigDecimal, + val maksBarnetillegg: BigDecimal? = null, + ) { + val totalInntekt get() = skattepliktigInntekt + (maksBarnetillegg ?: BigDecimal.ZERO) + } +} + data class PersoninfoDto( val id: Long? = null, val ident: Personident? = null, diff --git a/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/gebyr/GebyrValideringsfeilDto.kt b/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/gebyr/GebyrValideringsfeilDto.kt new file mode 100644 index 000000000..830300e4f --- /dev/null +++ b/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/gebyr/GebyrValideringsfeilDto.kt @@ -0,0 +1,32 @@ +package no.nav.bidrag.behandling.dto.v2.gebyr + +import com.fasterxml.jackson.annotation.JsonIgnore +import no.nav.bidrag.behandling.database.datamodell.Behandling +import no.nav.bidrag.behandling.dto.v1.behandling.RolleDto +import no.nav.bidrag.behandling.transformers.behandling.tilDto + +fun Behandling.validerGebyr() = + roller + .filter { it.harGebyrsøknad } + .map { + GebyrValideringsfeilDto( + gjelder = it.tilDto(), + måBestemmeGebyr = avslag != null && it.manueltOverstyrtGebyr?.ilagtGebyr == null, + manglerBegrunnelse = + if (it.manueltOverstyrtGebyr?.overstyrGebyr == true) { + it.manueltOverstyrtGebyr?.begrunnelse.isNullOrEmpty() + } else { + false + }, + ) + }.filter { it.harFeil } + +data class GebyrValideringsfeilDto( + val gjelder: RolleDto, + val måBestemmeGebyr: Boolean, + val manglerBegrunnelse: Boolean, +) { + @get:JsonIgnore + val harFeil + get() = manglerBegrunnelse || måBestemmeGebyr +} diff --git a/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/gebyr/OppdaterManueltGebyr.kt b/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/gebyr/OppdaterManueltGebyr.kt new file mode 100644 index 000000000..c5efc0f2c --- /dev/null +++ b/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/gebyr/OppdaterManueltGebyr.kt @@ -0,0 +1,20 @@ +package no.nav.bidrag.behandling.dto.v2.gebyr + +import io.swagger.v3.oas.annotations.media.Schema +import no.nav.bidrag.behandling.dto.v1.behandling.RolleDto + +data class OppdaterManueltGebyrDto( + val rolleId: Long, + val overstyrtGebyr: ManueltOverstyrGebyrDto?, +) + +data class OppdaterGebyrResponsDto( + val rolle: RolleDto, + val overstyrtGebyr: ManueltOverstyrGebyrDto?, +) + +data class ManueltOverstyrGebyrDto( + val begrunnelse: String? = null, + @Schema(description = "Skal bare settes hvis det er avslag") + val ilagtGebyr: Boolean? = null, +) diff --git a/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/validering/Validering.kt b/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/validering/Validering.kt index bc12e7401..0b8752ea8 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/validering/Validering.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/dto/v2/validering/Validering.kt @@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema import no.nav.bidrag.behandling.database.datamodell.Husstandsmedlem import no.nav.bidrag.behandling.dto.v1.behandling.RolleDto import no.nav.bidrag.behandling.dto.v2.behandling.Grunnlagsdatatype +import no.nav.bidrag.behandling.dto.v2.gebyr.GebyrValideringsfeilDto import no.nav.bidrag.behandling.dto.v2.samvær.SamværValideringsfeilDto import no.nav.bidrag.behandling.dto.v2.underhold.ValideringsfeilUnderhold import no.nav.bidrag.behandling.service.hentPersonVisningsnavn @@ -217,6 +218,7 @@ data class BeregningValideringsfeil( val andreVoksneIHusstanden: AndreVoksneIHusstandenPeriodeseringsfeil? = null, val sivilstand: SivilstandPeriodeseringsfeil? = null, val samvær: Set? = null, + val gebyr: Set? = null, val underholdskostnad: Set? = null, val måBekrefteNyeOpplysninger: Set = emptySet(), ) diff --git a/src/main/kotlin/no/nav/bidrag/behandling/service/BehandlingService.kt b/src/main/kotlin/no/nav/bidrag/behandling/service/BehandlingService.kt index 7d661f6dc..d1dd134d9 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/service/BehandlingService.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/service/BehandlingService.kt @@ -61,6 +61,7 @@ class BehandlingService( private val mapper: Dtomapper, private val validerBehandlingService: ValiderBehandlingService, private val underholdService: UnderholdService, + private val gebyrService: GebyrService, ) { @Transactional fun slettBehandling(behandlingId: Long) { @@ -254,8 +255,7 @@ class BehandlingService( log.info { "Oppdaterer informasjon om virkningstidspunkt for behandling $behandlingsid" } secureLogger.info { "Oppdaterer informasjon om virkningstidspunkt for behandling $behandlingsid, forespørsel=$request" } request.valider(it) - it.årsak = if (request.avslag != null) null else request.årsak ?: it.årsak - it.avslag = if (request.årsak != null) null else request.avslag ?: it.avslag + oppdaterAvslagÅrsak(it, request) request.henteOppdatereNotat()?.let { n -> notatService.oppdatereNotat( it, @@ -268,6 +268,30 @@ class BehandlingService( it } + @Transactional + fun oppdaterAvslagÅrsak( + behandling: Behandling, + request: OppdatereVirkningstidspunkt, + ) { + fun oppdaterGebyr() { + log.info { "Virkningstidspunkt årsak/avslag er endret. Oppdaterer gebyr detaljer ${behandling.id}" } + gebyrService.oppdaterGebyrEtterEndringÅrsakAvslag(behandling) + } + val erAvslagÅrsakEndret = request.årsak != behandling.årsak || request.avslag != behandling.avslag + + if (erAvslagÅrsakEndret) { + behandling.årsak = if (request.avslag != null) null else request.årsak ?: behandling.årsak + behandling.avslag = if (request.årsak != null) null else request.avslag ?: behandling.avslag + + when (behandling.tilType()) { + TypeBehandling.BIDRAG -> { + oppdaterGebyr() + } + else -> {} + } + } + } + @Transactional fun oppdaterVirkningstidspunkt( request: OppdatereVirkningstidspunkt, @@ -458,6 +482,8 @@ class BehandlingService( oppdatereHusstandsmedlemmerForRoller(behandling, rollerSomLeggesTil) oppdatereSamværForRoller(behandling, rollerSomLeggesTil) + // TODO oppdater underholdskostnader ( legge til når ny barn legges til ) + behandlingRepository.save(behandling) if (behandling.søknadsbarn.isEmpty()) { @@ -476,6 +502,7 @@ class BehandlingService( .forEach { roller.find { br -> br.ident == it.ident?.verdi }?.let { eksisterendeRolle -> eksisterendeRolle.innbetaltBeløp = it.innbetaltBeløp + eksisterendeRolle.harGebyrsøknad = it.harGebyrsøknad } } } diff --git a/src/main/kotlin/no/nav/bidrag/behandling/service/GebyrService.kt b/src/main/kotlin/no/nav/bidrag/behandling/service/GebyrService.kt new file mode 100644 index 000000000..bdf756868 --- /dev/null +++ b/src/main/kotlin/no/nav/bidrag/behandling/service/GebyrService.kt @@ -0,0 +1,84 @@ +package no.nav.bidrag.behandling.service + +import no.nav.bidrag.behandling.database.datamodell.Behandling +import no.nav.bidrag.behandling.database.datamodell.RolleManueltOverstyrtGebyr +import no.nav.bidrag.behandling.dto.v2.gebyr.OppdaterManueltGebyrDto +import no.nav.bidrag.behandling.transformers.tilType +import no.nav.bidrag.behandling.transformers.validerSann +import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.VedtakGrunnlagMapper +import no.nav.bidrag.behandling.ugyldigForespørsel +import no.nav.bidrag.domene.enums.behandling.TypeBehandling +import no.nav.bidrag.transport.felles.ifTrue +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class GebyrService( + private val vedtakGrunnlagMapper: VedtakGrunnlagMapper, +) { + @Transactional + fun oppdaterGebyrEtterEndringÅrsakAvslag(behandling: Behandling) { + behandling + .roller + .filter { it.harGebyrsøknad } + .forEach { rolle -> + rolle.manueltOverstyrtGebyr = + (rolle.manueltOverstyrtGebyr ?: RolleManueltOverstyrtGebyr()).let { + it.copy( + overstyrGebyr = behandling.avslag != null, + ilagtGebyr = + (behandling.avslag == null).ifTrue { + val beregning = vedtakGrunnlagMapper.beregnGebyr(behandling, rolle) + !beregning.ilagtGebyr + }, + ) + } + } + } + + @Transactional + fun oppdaterManueltOverstyrtGebyr( + behandling: Behandling, + request: OppdaterManueltGebyrDto, + ) { + val rolle = + behandling.roller.find { it.id == request.rolleId } + ?: ugyldigForespørsel("Fant ikke rolle ${request.rolleId} i behandling ${behandling.id}") + val beregning = vedtakGrunnlagMapper.beregnGebyr(behandling, rolle) + behandling.validerOppdatering(request) + rolle.manueltOverstyrtGebyr = + (rolle.manueltOverstyrtGebyr ?: RolleManueltOverstyrtGebyr()).let { + it.copy( + overstyrGebyr = request.overstyrtGebyr != null, + ilagtGebyr = request.overstyrtGebyr?.ilagtGebyr ?: (behandling.avslag == null).ifTrue { !beregning.ilagtGebyr }, + begrunnelse = request.overstyrtGebyr?.begrunnelse ?: it.begrunnelse, + ) + } + } + + private fun Behandling.validerOppdatering(request: OppdaterManueltGebyrDto) { + val feilListe = mutableSetOf() + + feilListe.validerSann(tilType() == TypeBehandling.BIDRAG, "Kan bare oppdatere gebyr på en bidragsbehandling") + + val rolle = + roller.find { it.id == request.rolleId } + ?: ugyldigForespørsel("Fant ikke rolle ${request.rolleId} i behandling $id") + + feilListe.validerSann( + rolle.harGebyrsøknad, + "Kan ikke endre gebyr på en rolle som ikke har gebyrsøknad", + ) + + if (avslag == null) { + feilListe.validerSann( + request.overstyrtGebyr?.ilagtGebyr == null, + "Kan ikke sette gebyr til samme som beregnet gebyr når det ikke er avslag", + ) + } + + if (feilListe.isNotEmpty()) { + ugyldigForespørsel(feilListe.toSet().joinToString("\n")) + } + } +} diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/BeregningDtoMapping.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/BeregningDtoMapping.kt index 0ae367c7a..b23bf2a71 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/transformers/BeregningDtoMapping.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/BeregningDtoMapping.kt @@ -14,12 +14,16 @@ import no.nav.bidrag.behandling.dto.v1.beregning.ResultatBidragsberegningBarn import no.nav.bidrag.behandling.dto.v1.beregning.ResultatBidragsberegningBarnDto import no.nav.bidrag.behandling.dto.v1.beregning.ResultatForskuddsberegningBarn import no.nav.bidrag.behandling.dto.v1.beregning.ResultatSærbidragsberegningDto +import no.nav.bidrag.behandling.dto.v2.behandling.GebyrRolleDto import no.nav.bidrag.behandling.dto.v2.behandling.UtgiftBeregningDto import no.nav.bidrag.behandling.dto.v2.behandling.UtgiftspostDto import no.nav.bidrag.behandling.dto.v2.underhold.DatoperiodeDto import no.nav.bidrag.behandling.dto.v2.underhold.UnderholdskostnadDto +import no.nav.bidrag.behandling.transformers.behandling.tilDto +import no.nav.bidrag.behandling.transformers.gebyr.tilDto import no.nav.bidrag.behandling.transformers.utgift.tilBeregningDto import no.nav.bidrag.behandling.transformers.utgift.tilDto +import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.BeregnGebyrResultat import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.finnBeregnTilDato import no.nav.bidrag.behandling.transformers.vedtak.takeIfNotNullOrEmpty import no.nav.bidrag.domene.enums.beregning.Resultatkode @@ -71,6 +75,18 @@ import java.math.BigDecimal import java.math.RoundingMode import java.time.LocalDate +fun BeregnGebyrResultat.tilDto(rolle: Rolle) = + GebyrRolleDto( + inntekt = + GebyrRolleDto.GebyrInntektDto( + skattepliktigInntekt = skattepliktigInntekt, + maksBarnetillegg = maksBarnetillegg, + ), + manueltOverstyrtGebyr = rolle.manueltOverstyrtGebyr?.tilDto(), + beregnetIlagtGebyr = ilagtGebyr, + rolle = rolle.tilDto(), + ) + fun Behandling.tilInntektberegningDto(rolle: Rolle): BeregnValgteInntekterGrunnlag = BeregnValgteInntekterGrunnlag( periode = diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/DtoExtensions.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/DtoExtensions.kt index bf1b7a3b5..0d3f2fa0f 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/transformers/DtoExtensions.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/DtoExtensions.kt @@ -25,13 +25,15 @@ fun Behandling.tilForsendelseRolleDto() = fun OpprettRolleDto.toRolle(behandling: Behandling): Rolle = Rolle( - behandling, - rolletype = this.rolletype, - this.ident?.verdi, - this.fødselsdato ?: hentPersonFødselsdato(ident?.verdi) - ?: rolleManglerFødselsdato(rolletype), - navn = this.navn, - innbetaltBeløp = this.innbetaltBeløp, + behandling = behandling, + rolletype = rolletype, + ident = ident?.verdi, + fødselsdato = + fødselsdato ?: hentPersonFødselsdato(ident?.verdi) + ?: rolleManglerFødselsdato(rolletype), + navn = navn, + innbetaltBeløp = innbetaltBeløp, + harGebyrsøknad = harGebyrsøknad, ) fun OpprettRolleDto.toHusstandsmedlem(behandling: Behandling): Husstandsmedlem = diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/Dtomapper.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/Dtomapper.kt index 288db2e7d..5d769f0b3 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/transformers/Dtomapper.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/Dtomapper.kt @@ -1,6 +1,7 @@ package no.nav.bidrag.behandling.transformers import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.node.POJONode import no.nav.bidrag.behandling.database.datamodell.Behandling import no.nav.bidrag.behandling.database.datamodell.FaktiskTilsynsutgift import no.nav.bidrag.behandling.database.datamodell.Grunnlag @@ -23,6 +24,7 @@ import no.nav.bidrag.behandling.dto.v2.behandling.AktivereGrunnlagResponseV2 import no.nav.bidrag.behandling.dto.v2.behandling.AndreVoksneIHusstandenDetaljerDto import no.nav.bidrag.behandling.dto.v2.behandling.AndreVoksneIHusstandenGrunnlagDto import no.nav.bidrag.behandling.dto.v2.behandling.BehandlingDtoV2 +import no.nav.bidrag.behandling.dto.v2.behandling.GebyrDto import no.nav.bidrag.behandling.dto.v2.behandling.Grunnlagsdatatype import no.nav.bidrag.behandling.dto.v2.behandling.HusstandsmedlemGrunnlagDto import no.nav.bidrag.behandling.dto.v2.behandling.IkkeAktiveGrunnlagsdata @@ -34,6 +36,7 @@ import no.nav.bidrag.behandling.dto.v2.boforhold.BoforholdDtoV2 import no.nav.bidrag.behandling.dto.v2.boforhold.HusstandsmedlemDtoV2 import no.nav.bidrag.behandling.dto.v2.boforhold.OppdatereBoforholdResponse import no.nav.bidrag.behandling.dto.v2.boforhold.egetBarnErEnesteVoksenIHusstanden +import no.nav.bidrag.behandling.dto.v2.gebyr.validerGebyr import no.nav.bidrag.behandling.dto.v2.underhold.DatoperiodeDto import no.nav.bidrag.behandling.dto.v2.underhold.FaktiskTilsynsutgiftDto import no.nav.bidrag.behandling.dto.v2.underhold.TilleggsstønadDto @@ -59,6 +62,8 @@ import no.nav.bidrag.behandling.transformers.behandling.tilKanBehandlesINyLøsni import no.nav.bidrag.behandling.transformers.behandling.toSivilstand import no.nav.bidrag.behandling.transformers.beregning.ValiderBeregning import no.nav.bidrag.behandling.transformers.boforhold.tilBostatusperiode +import no.nav.bidrag.behandling.transformers.gebyr.tilDto +import no.nav.bidrag.behandling.transformers.grunnlag.tilGrunnlagsreferanse import no.nav.bidrag.behandling.transformers.samvær.tilDto import no.nav.bidrag.behandling.transformers.underhold.tilStønadTilBarnetilsynDtos import no.nav.bidrag.behandling.transformers.utgift.hentValideringsfeil @@ -74,6 +79,7 @@ import no.nav.bidrag.boforhold.dto.BoforholdResponseV2 import no.nav.bidrag.boforhold.dto.Bostatus import no.nav.bidrag.domene.enums.behandling.TypeBehandling import no.nav.bidrag.domene.enums.diverse.Kilde +import no.nav.bidrag.domene.enums.grunnlag.Grunnlagstype import no.nav.bidrag.domene.enums.person.Familierelasjon import no.nav.bidrag.domene.enums.rolle.Rolletype import no.nav.bidrag.domene.enums.vedtak.Innkrevingstype @@ -81,6 +87,7 @@ import no.nav.bidrag.domene.ident.Personident import no.nav.bidrag.domene.sak.Saksnummer import no.nav.bidrag.domene.tid.ÅrMånedsperiode import no.nav.bidrag.transport.behandling.beregning.felles.BeregnGrunnlag +import no.nav.bidrag.transport.behandling.felles.grunnlag.GrunnlagDto import no.nav.bidrag.transport.behandling.felles.grunnlag.NotatGrunnlag.NotatType import no.nav.bidrag.transport.behandling.grunnlag.response.ArbeidsforholdGrunnlagDto import no.nav.bidrag.transport.behandling.grunnlag.response.FeilrapporteringDto @@ -561,6 +568,20 @@ class Dtomapper( saksnummer = saksnummer, søknadsid = soknadsid, behandlerenhet = behandlerEnhet, + gebyr = + if (roller.filter { it.harGebyrsøknad }.isNotEmpty()) { + GebyrDto( + gebyrRoller = + roller.filter { it.harGebyrsøknad }.map { rolle -> + vedtakGrunnlagMapper + .beregnGebyr(this, rolle) + .tilDto(rolle) + }, + valideringsfeil = validerGebyr().takeIf { it.isNotEmpty() }, + ) + } else { + null + }, roller = roller.map { it.tilDto() }.toSet(), søknadRefId = soknadRefId, @@ -596,6 +617,23 @@ class Dtomapper( ) } + fun Behandling.beregnetInntekterGrunnlagForRolle(rolle: Rolle) = + BeregnApi() + .beregnInntekt(tilInntektberegningDto(rolle)) + .inntektPerBarnListe + .filter { it.inntektGjelderBarnIdent != null } + .flatMap { beregningBarn -> + beregningBarn.summertInntektListe.map { + GrunnlagDto( + referanse = "${Grunnlagstype.DELBEREGNING_SUM_INNTEKT}_${rolle.tilGrunnlagsreferanse()}", + type = Grunnlagstype.DELBEREGNING_SUM_INNTEKT, + innhold = POJONode(it), + gjelderReferanse = rolle.tilGrunnlagsreferanse(), + gjelderBarnReferanse = beregningBarn.inntektGjelderBarnIdent!!.verdi, + ) + } + } + private fun Husstandsmedlem.mapTilOppdatereBoforholdResponse() = OppdatereBoforholdResponse( oppdatertePerioderMedAndreVoksne = diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/Validering.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/Validering.kt index 6a138ea66..b029e1389 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/transformers/Validering.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/Validering.kt @@ -54,6 +54,15 @@ import java.time.LocalDate private val log = KotlinLogging.logger {} +fun MutableSet.validerSann( + betingelse: Boolean, + melding: String, +) { + if (!betingelse) { + add(melding) + } +} + fun bestemRollerSomMåHaMinstEnInntekt(typeBehandling: TypeBehandling) = when (typeBehandling) { TypeBehandling.FORSKUDD -> listOf(Rolletype.BIDRAGSMOTTAKER) diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/beregning/ValiderBeregning.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/beregning/ValiderBeregning.kt index 14d01fb41..76334a130 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/transformers/beregning/ValiderBeregning.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/beregning/ValiderBeregning.kt @@ -5,6 +5,7 @@ import no.nav.bidrag.behandling.database.datamodell.Husstandsmedlem import no.nav.bidrag.behandling.database.datamodell.barn import no.nav.bidrag.behandling.database.datamodell.voksneIHusstanden import no.nav.bidrag.behandling.dto.v2.behandling.Grunnlagsdatatype +import no.nav.bidrag.behandling.dto.v2.gebyr.validerGebyr import no.nav.bidrag.behandling.dto.v2.samvær.mapValideringsfeil import no.nav.bidrag.behandling.dto.v2.validering.BeregningValideringsfeil import no.nav.bidrag.behandling.dto.v2.validering.BoforholdPeriodeseringsfeil @@ -165,6 +166,17 @@ class ValiderBeregning( } fun Behandling.validerForBeregningBidrag() { + val gebyrValideringsfeil = validerGebyr() + val erVirkningstidspunktSenereEnnOpprinnerligVirknignstidspunkt = + erKlageEllerOmgjøring && + opprinneligVirkningstidspunkt != null && + virkningstidspunkt?.isAfter(opprinneligVirkningstidspunkt) == true + val virkningstidspunktFeil = + VirkningstidspunktFeilDto( + manglerÅrsakEllerAvslag = avslag == null && årsak == null, + manglerVirkningstidspunkt = virkningstidspunkt == null, + virkningstidspunktKanIkkeVæreSenereEnnOpprinnelig = erVirkningstidspunktSenereEnnOpprinnerligVirknignstidspunkt, + ).takeIf { it.harFeil } val feil = if (avslag == null) { val inntekterFeil = hentInntekterValideringsfeil().takeIf { it.harFeil } @@ -215,8 +227,10 @@ class ValiderBeregning( val harFeil = inntekterFeil != null || husstandsmedlemsfeil.isNotEmpty() || + virkningstidspunktFeil != null || andreVoksneIHusstandenFeil != null || samværValideringsfeil.isNotEmpty() || + gebyrValideringsfeil.isNotEmpty() || måBekrefteOpplysninger.isNotEmpty() harFeil.ifTrue { BeregningValideringsfeil( @@ -224,22 +238,30 @@ class ValiderBeregning( husstandsmedlem = husstandsmedlemsfeil.takeIf { it.isNotEmpty() }, andreVoksneIHusstanden = andreVoksneIHusstandenFeil, måBekrefteNyeOpplysninger = måBekrefteOpplysninger, + virkningstidspunkt = virkningstidspunktFeil, + gebyr = gebyrValideringsfeil.takeIf { it.isNotEmpty() }?.toSet(), samvær = samværValideringsfeil.takeIf { it.isNotEmpty() }, underholdskostnad = null, // TODO: Legg til validering av underholdskostnad ) } } else { - null + val harFeil = virkningstidspunktFeil != null || gebyrValideringsfeil.isNotEmpty() + harFeil.ifTrue { + BeregningValideringsfeil( + virkningstidspunkt = virkningstidspunktFeil, + gebyr = gebyrValideringsfeil.takeIf { it.isNotEmpty() }?.toSet(), + ) + } } if (feil != null) { secureLogger.warn { - "Feil ved validering av behandling for beregning av særbidrag" + + "Feil ved validering av behandling for beregning av bidrag" + commonObjectmapper.writeValueAsString(feil) } throw HttpClientErrorException( HttpStatus.BAD_REQUEST, - "Feil ved validering av behandling for beregning av særbidrag", + "Feil ved validering av behandling for beregning av bidrag", commonObjectmapper.writeValueAsBytes(feil), Charset.defaultCharset(), ) diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/gebyr/Gebyrmapping.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/gebyr/Gebyrmapping.kt new file mode 100644 index 000000000..5727efd37 --- /dev/null +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/gebyr/Gebyrmapping.kt @@ -0,0 +1,11 @@ +package no.nav.bidrag.behandling.transformers.gebyr + +import no.nav.bidrag.behandling.database.datamodell.RolleManueltOverstyrtGebyr +import no.nav.bidrag.behandling.dto.v2.gebyr.ManueltOverstyrGebyrDto + +fun RolleManueltOverstyrtGebyr.tilDto() = + if (overstyrGebyr) { + ManueltOverstyrGebyrDto(begrunnelse, ilagtGebyr) + } else { + null + } diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/BehandlingTilGrunnlagMappingV2.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/BehandlingTilGrunnlagMappingV2.kt index 03c59af56..707b7eacd 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/BehandlingTilGrunnlagMappingV2.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/BehandlingTilGrunnlagMappingV2.kt @@ -18,6 +18,7 @@ import no.nav.bidrag.behandling.transformers.grunnlag.valider import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi import no.nav.bidrag.domene.enums.diverse.Kilde import no.nav.bidrag.domene.enums.grunnlag.Grunnlagstype +import no.nav.bidrag.domene.enums.inntekt.Inntektsrapportering import no.nav.bidrag.domene.enums.vedtak.Engangsbeløptype import no.nav.bidrag.domene.enums.vedtak.Stønadstype import no.nav.bidrag.domene.ident.Personident @@ -25,6 +26,7 @@ import no.nav.bidrag.domene.tid.ÅrMånedsperiode import no.nav.bidrag.transport.behandling.felles.grunnlag.BaseGrunnlag import no.nav.bidrag.transport.behandling.felles.grunnlag.FaktiskUtgiftPeriode import no.nav.bidrag.transport.behandling.felles.grunnlag.GrunnlagDto +import no.nav.bidrag.transport.behandling.felles.grunnlag.InntektsrapporteringPeriode import no.nav.bidrag.transport.behandling.felles.grunnlag.Person import no.nav.bidrag.transport.behandling.felles.grunnlag.SamværsperiodeGrunnlag import no.nav.bidrag.transport.behandling.felles.grunnlag.SivilstandPeriode @@ -33,6 +35,7 @@ import no.nav.bidrag.transport.behandling.felles.grunnlag.bidragspliktig import no.nav.bidrag.transport.behandling.felles.grunnlag.erPerson import no.nav.bidrag.transport.behandling.felles.grunnlag.filtrerBasertPåEgenReferanse import no.nav.bidrag.transport.behandling.felles.grunnlag.hentPerson +import no.nav.bidrag.transport.behandling.felles.grunnlag.innholdTilObjekt import no.nav.bidrag.transport.behandling.felles.grunnlag.opprettInnhentetSivilstandGrunnlagsreferanse import no.nav.bidrag.transport.behandling.felles.grunnlag.personIdent import no.nav.bidrag.transport.behandling.felles.grunnlag.personObjekt @@ -164,8 +167,15 @@ class BehandlingTilGrunnlagMappingV2( tilGrunnlagFaktiskeTilsynsutgifter(personobjekter), ).flatten() + fun Behandling.tilGrunnlagInntektSiste12Mnd(rolle: Rolle) = + tilGrunnlagInntekt() + .filter { it.gjelderReferanse == rolle.tilGrunnlagsreferanse() } + .find { + it.innholdTilObjekt().inntektsrapportering == Inntektsrapportering.AINNTEKT_BEREGNET_12MND + } + fun Behandling.tilGrunnlagInntekt( - personobjekter: Set, + personobjekter: Set = tilPersonobjekter(), søknadsbarn: GrunnlagDto? = null, inkluderAlle: Boolean = true, ): Set { diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/BehandlingTilVedtakMapping.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/BehandlingTilVedtakMapping.kt index d57f5c20d..f10498fec 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/BehandlingTilVedtakMapping.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/BehandlingTilVedtakMapping.kt @@ -11,6 +11,7 @@ import no.nav.bidrag.behandling.transformers.vedtak.StønadsendringPeriode import no.nav.bidrag.behandling.transformers.vedtak.reelMottakerEllerBidragsmottaker import no.nav.bidrag.behandling.transformers.vedtak.skyldnerNav import no.nav.bidrag.behandling.transformers.vedtak.tilVedtakDto +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi import no.nav.bidrag.domene.enums.behandling.TypeBehandling import no.nav.bidrag.domene.enums.beregning.Resultatkode import no.nav.bidrag.domene.enums.grunnlag.Grunnlagstype @@ -23,6 +24,7 @@ import no.nav.bidrag.domene.ident.Personident import no.nav.bidrag.domene.organisasjon.Enhetsnummer import no.nav.bidrag.domene.sak.Saksnummer import no.nav.bidrag.domene.tid.ÅrMånedsperiode +import no.nav.bidrag.transport.behandling.felles.grunnlag.BaseGrunnlag import no.nav.bidrag.transport.behandling.felles.grunnlag.GrunnlagDto import no.nav.bidrag.transport.behandling.felles.grunnlag.hentAllePersoner import no.nav.bidrag.transport.behandling.vedtak.request.OpprettEngangsbeløpRequestDto @@ -30,7 +32,9 @@ import no.nav.bidrag.transport.behandling.vedtak.request.OpprettPeriodeRequestDt import no.nav.bidrag.transport.behandling.vedtak.request.OpprettStønadsendringRequestDto import no.nav.bidrag.transport.behandling.vedtak.request.OpprettVedtakRequestDto import no.nav.bidrag.transport.behandling.vedtak.response.VedtakDto +import no.nav.bidrag.transport.felles.ifTrue import no.nav.bidrag.transport.sak.BidragssakDto +import org.springframework.context.annotation.Import import org.springframework.http.HttpStatus import org.springframework.stereotype.Service import org.springframework.web.client.HttpClientErrorException @@ -39,6 +43,7 @@ import java.time.LocalDateTime import java.time.YearMonth @Service +@Import(BeregnGebyrApi::class) class BehandlingTilVedtakMapping( private val sakConsumer: BidragSakConsumer, private val mapper: VedtakGrunnlagMapper, @@ -63,6 +68,7 @@ class BehandlingTilVedtakMapping( StønadsendringPeriode::grunnlag, ) + stønadsendringGrunnlagListe ).toSet() + val engangsbeløpGebyr = mapEngangsbeløpGebyr(grunnlagListe.toList()) return byggOpprettVedtakRequestObjekt().copy( stønadsendringListe = @@ -88,45 +94,60 @@ class BehandlingTilVedtakMapping( ) }, engangsbeløpListe = - mapEngangsbeløpGebyr() + mapEngangsbeløpDirekteOppgjør(sak), - grunnlagListe = grunnlagListe.map(GrunnlagDto::tilOpprettRequestDto), + engangsbeløpGebyr.engangsbeløp + mapEngangsbeløpDirekteOppgjør(sak), + grunnlagListe = (grunnlagListe + engangsbeløpGebyr.grunnlagsliste).toSet().map(BaseGrunnlag::tilOpprettRequestDto), ) } } - private fun Behandling.mapEngangsbeløpGebyr() = - listOf( - OpprettEngangsbeløpRequestDto( - type = Engangsbeløptype.GEBYR_SKYLDNER, - beløp = BigDecimal.ZERO, // TODO: Gebyr fra beregning - betaltBeløp = null, - resultatkode = Resultatkode.GEBYR_ILAGT.name, // TODO: Resultat fra beregning - eksternReferanse = null, - beslutning = Beslutningstype.ENDRING, - grunnlagReferanseListe = emptyList(), - innkreving = Innkrevingstype.MED_INNKREVING, - skyldner = Personident(bidragspliktig!!.ident!!), - kravhaver = skyldnerNav, - mottaker = skyldnerNav, - valutakode = "NOK", - sak = Saksnummer(saksnummer), - ), - OpprettEngangsbeløpRequestDto( - type = Engangsbeløptype.GEBYR_MOTTAKER, - beløp = BigDecimal.ZERO, // TODO: Gebyr fra beregning - betaltBeløp = null, - resultatkode = Resultatkode.GEBYR_ILAGT.name, // TODO: Resultat fra beregning - eksternReferanse = null, - beslutning = Beslutningstype.ENDRING, - grunnlagReferanseListe = emptyList(), - innkreving = Innkrevingstype.MED_INNKREVING, - skyldner = Personident(bidragsmottaker!!.ident!!), - kravhaver = skyldnerNav, - mottaker = skyldnerNav, - valutakode = "NOK", - sak = Saksnummer(saksnummer), - ), - ) + private fun Behandling.byggGrunnlagForGebyr(): Set = byggGrunnlagManueltOverstyrtGebyr() + + private fun Behandling.mapEngangsbeløpGebyr(grunnlagsliste: List): GebyrResulat { + val gebyrGrunnlagsliste: MutableSet = mutableSetOf() + val grunnlagslisteGebyr = grunnlagsliste + byggGrunnlagForGebyr() + val engangsbeløpListe = + listOfNotNull( + bidragspliktig!!.harGebyrsøknad.ifTrue { + val beregning = mapper.beregnGebyr(this, bidragspliktig!!, grunnlagslisteGebyr) + gebyrGrunnlagsliste.addAll(beregning.grunnlagsliste) + OpprettEngangsbeløpRequestDto( + type = Engangsbeløptype.GEBYR_SKYLDNER, + beløp = beregning.beløpGebyrsats, + betaltBeløp = null, + resultatkode = beregning.resultatkode.name, + eksternReferanse = null, + beslutning = Beslutningstype.ENDRING, + grunnlagReferanseListe = beregning.grunnlagsreferanseListeEngangsbeløp, + innkreving = Innkrevingstype.MED_INNKREVING, + skyldner = Personident(bidragspliktig!!.ident!!), + kravhaver = skyldnerNav, + mottaker = skyldnerNav, + valutakode = "NOK", + sak = Saksnummer(saksnummer), + ) + }, + bidragsmottaker!!.harGebyrsøknad.ifTrue { + val beregning = mapper.beregnGebyr(this, bidragsmottaker!!, grunnlagslisteGebyr) + gebyrGrunnlagsliste.addAll(beregning.grunnlagsliste) + OpprettEngangsbeløpRequestDto( + type = Engangsbeløptype.GEBYR_MOTTAKER, + beløp = beregning.beløpGebyrsats, + betaltBeløp = null, + resultatkode = beregning.resultatkode.name, + eksternReferanse = null, + beslutning = Beslutningstype.ENDRING, + grunnlagReferanseListe = beregning.grunnlagsreferanseListeEngangsbeløp, + innkreving = Innkrevingstype.MED_INNKREVING, + skyldner = Personident(bidragsmottaker!!.ident!!), + kravhaver = skyldnerNav, + mottaker = skyldnerNav, + valutakode = "NOK", + sak = Saksnummer(saksnummer), + ) + }, + ) + return GebyrResulat(engangsbeløpListe, gebyrGrunnlagsliste) + } private fun Behandling.mapEngangsbeløpDirekteOppgjør(sak: BidragssakDto) = søknadsbarn @@ -164,10 +185,12 @@ class BehandlingTilVedtakMapping( mapper.run { val sak = sakConsumer.hentSak(saksnummer) val grunnlagListe = byggGrunnlagGenereltAvslag() + val grunnlagslisteGebyr = byggGrunnlagForGebyr() + val resultatEngangsbeløpGebyr = mapEngangsbeløpGebyr(grunnlagListe.toList() + grunnlagslisteGebyr) return byggOpprettVedtakRequestObjekt() .copy( - engangsbeløpListe = mapEngangsbeløpGebyr(), + engangsbeløpListe = resultatEngangsbeløpGebyr.engangsbeløp, stønadsendringListe = søknadsbarn.map { OpprettStønadsendringRequestDto( @@ -198,7 +221,10 @@ class BehandlingTilVedtakMapping( ), ) }, - grunnlagListe = (grunnlagListe + tilPersonobjekter()).map(GrunnlagDto::tilOpprettRequestDto), + grunnlagListe = + (grunnlagListe + tilPersonobjekter() + resultatEngangsbeløpGebyr.grunnlagsliste).map( + BaseGrunnlag::tilOpprettRequestDto, + ), ) } diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagByggerFelles.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagByggerFelles.kt index df9298c26..2b0ce3ceb 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagByggerFelles.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagByggerFelles.kt @@ -5,6 +5,7 @@ import no.nav.bidrag.behandling.database.datamodell.Behandling import no.nav.bidrag.behandling.database.datamodell.Bostatusperiode import no.nav.bidrag.behandling.database.datamodell.Grunnlag import no.nav.bidrag.behandling.database.datamodell.Inntekt +import no.nav.bidrag.behandling.database.datamodell.Rolle import no.nav.bidrag.behandling.database.datamodell.tilNyestePersonident import no.nav.bidrag.behandling.rolleManglerIdent import no.nav.bidrag.behandling.service.NotatService.Companion.henteInntektsnotat @@ -20,21 +21,28 @@ import no.nav.bidrag.behandling.transformers.vedtak.inntektsrapporteringSomKreve import no.nav.bidrag.behandling.transformers.vedtak.skyldnerNav import no.nav.bidrag.behandling.transformers.vedtak.takeIfNotNullOrEmpty import no.nav.bidrag.domene.enums.behandling.TypeBehandling +import no.nav.bidrag.domene.enums.beregning.Resultatkode import no.nav.bidrag.domene.enums.diverse.Kilde import no.nav.bidrag.domene.enums.grunnlag.Grunnlagstype +import no.nav.bidrag.domene.enums.inntekt.Inntektsrapportering import no.nav.bidrag.domene.enums.rolle.Rolletype import no.nav.bidrag.domene.enums.vedtak.BehandlingsrefKilde import no.nav.bidrag.domene.enums.vedtak.Stønadstype import no.nav.bidrag.domene.tid.ÅrMånedsperiode +import no.nav.bidrag.transport.behandling.felles.grunnlag.BaseGrunnlag import no.nav.bidrag.transport.behandling.felles.grunnlag.BostatusPeriode import no.nav.bidrag.transport.behandling.felles.grunnlag.GrunnlagDto import no.nav.bidrag.transport.behandling.felles.grunnlag.InntektsrapporteringPeriode +import no.nav.bidrag.transport.behandling.felles.grunnlag.ManueltOverstyrtGebyr import no.nav.bidrag.transport.behandling.felles.grunnlag.NotatGrunnlag import no.nav.bidrag.transport.behandling.felles.grunnlag.Person +import no.nav.bidrag.transport.behandling.felles.grunnlag.SluttberegningGebyr import no.nav.bidrag.transport.behandling.felles.grunnlag.SøknadGrunnlag import no.nav.bidrag.transport.behandling.felles.grunnlag.VirkningstidspunktGrunnlag +import no.nav.bidrag.transport.behandling.felles.grunnlag.innholdTilObjekt import no.nav.bidrag.transport.behandling.felles.grunnlag.opprettInnhentetHusstandsmedlemGrunnlagsreferanse import no.nav.bidrag.transport.behandling.felles.grunnlag.personIdent +import no.nav.bidrag.transport.behandling.felles.grunnlag.tilInnholdMedReferanse import no.nav.bidrag.transport.behandling.vedtak.request.OpprettBehandlingsreferanseRequestDto import no.nav.bidrag.transport.behandling.vedtak.request.OpprettGrunnlagRequestDto import no.nav.bidrag.transport.felles.ifTrue @@ -64,7 +72,7 @@ fun Behandling.byggGrunnlagGenerelt(): Set { return grunnlagListe } -fun GrunnlagDto.tilOpprettRequestDto() = +fun BaseGrunnlag.tilOpprettRequestDto() = OpprettGrunnlagRequestDto( referanse = referanse, type = type, @@ -93,6 +101,25 @@ private fun opprettGrunnlagNotat( ), ) +fun Behandling.byggGrunnlagManueltOverstyrtGebyr() = + roller + .filter { it.harGebyrsøknad } + .filter { it.manueltOverstyrtGebyr != null && it.manueltOverstyrtGebyr?.overstyrGebyr == true } + .map { + GrunnlagDto( + referanse = "${Grunnlagstype.MANUELT_OVERSTYRT_GEBYR}_${it.tilGrunnlagsreferanse()}", + type = Grunnlagstype.MANUELT_OVERSTYRT_GEBYR, + gjelderReferanse = it.tilGrunnlagsreferanse(), + innhold = + POJONode( + ManueltOverstyrtGebyr( + begrunnelse = it.manueltOverstyrtGebyr!!.begrunnelse!!, + ilagtGebyr = it.manueltOverstyrtGebyr!!.ilagtGebyr!!, + ), + ), + ) + }.toSet() + fun Behandling.byggGrunnlagSøknad() = setOf( GrunnlagDto( @@ -265,6 +292,14 @@ internal fun opprettGrunnlagForBostatusperioder( ) }.toSet() +internal fun SluttberegningGebyr.tilResultatkode() = if (ilagtGebyr) Resultatkode.GEBYR_ILAGT else Resultatkode.GEBYR_FRITTATT + +fun List.finnInntektSiste12Mnd(rolle: Rolle) = + filter { + it.type == Grunnlagstype.INNTEKT_RAPPORTERING_PERIODE && it.gjelderReferanse == rolle.tilGrunnlagsreferanse() + }.find { it.innholdTilObjekt().inntektsrapportering == Inntektsrapportering.AINNTEKT_BEREGNET_12MND } + ?.tilInnholdMedReferanse() + internal fun Inntekt.tilInntektsrapporteringPeriode( gjelder: GrunnlagDto, søknadsbarn: GrunnlagDto?, diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagDtos.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagDtos.kt new file mode 100644 index 000000000..3f201c0a0 --- /dev/null +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagDtos.kt @@ -0,0 +1,24 @@ +@file:Suppress("ktlint:standard:filename") + +package no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak + +import no.nav.bidrag.domene.enums.beregning.Resultatkode +import no.nav.bidrag.transport.behandling.felles.grunnlag.BaseGrunnlag +import no.nav.bidrag.transport.behandling.felles.grunnlag.Grunnlagsreferanse +import no.nav.bidrag.transport.behandling.vedtak.request.OpprettEngangsbeløpRequestDto +import java.math.BigDecimal + +internal data class GebyrResulat( + val engangsbeløp: List, + val grunnlagsliste: Set, +) + +data class BeregnGebyrResultat( + val skattepliktigInntekt: BigDecimal, + val maksBarnetillegg: BigDecimal?, + val ilagtGebyr: Boolean, + val beløpGebyrsats: BigDecimal, + val resultatkode: Resultatkode, + val grunnlagsreferanseListeEngangsbeløp: List, + val grunnlagsliste: List, +) diff --git a/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/VedtakGrunnlagMapper.kt b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/VedtakGrunnlagMapper.kt index cb4a28fee..d821875b0 100644 --- a/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/VedtakGrunnlagMapper.kt +++ b/src/main/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/VedtakGrunnlagMapper.kt @@ -11,9 +11,13 @@ import no.nav.bidrag.behandling.transformers.beregning.EvnevurderingBeregningRes import no.nav.bidrag.behandling.transformers.beregning.ValiderBeregning import no.nav.bidrag.behandling.transformers.grunnlag.manglerRolleIGrunnlag import no.nav.bidrag.behandling.transformers.grunnlag.tilGrunnlagPerson +import no.nav.bidrag.behandling.transformers.grunnlag.tilGrunnlagsreferanse import no.nav.bidrag.behandling.transformers.grunnlag.valider +import no.nav.bidrag.behandling.transformers.tilInntektberegningDto import no.nav.bidrag.behandling.transformers.tilType import no.nav.bidrag.behandling.vedtakmappingFeilet +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi +import no.nav.bidrag.beregn.core.BeregnApi import no.nav.bidrag.domene.enums.behandling.TypeBehandling import no.nav.bidrag.domene.enums.beregning.Resultatkode import no.nav.bidrag.domene.enums.beregning.Samværsklasse @@ -28,8 +32,11 @@ import no.nav.bidrag.transport.behandling.felles.grunnlag.LøpendeBidragGrunnlag import no.nav.bidrag.transport.behandling.felles.grunnlag.Person import no.nav.bidrag.transport.behandling.felles.grunnlag.bidragsmottaker import no.nav.bidrag.transport.behandling.felles.grunnlag.bidragspliktig +import no.nav.bidrag.transport.behandling.felles.grunnlag.gebyrBeløp +import no.nav.bidrag.transport.behandling.felles.grunnlag.gebyrDelberegningSumInntekt import no.nav.bidrag.transport.behandling.felles.grunnlag.hentPerson import no.nav.bidrag.transport.behandling.felles.grunnlag.personObjekt +import no.nav.bidrag.transport.behandling.felles.grunnlag.sluttberegningGebyr import no.nav.bidrag.transport.behandling.felles.grunnlag.tilPersonreferanse import no.nav.bidrag.transport.behandling.stonad.response.LøpendeBidragssak import no.nav.bidrag.transport.felles.toCompactString @@ -49,6 +56,7 @@ class VedtakGrunnlagMapper( val validering: ValiderBeregning, private val beregningEvnevurderingService: BeregningEvnevurderingService, private val personService: PersonService, + private val beregnGebyrApi: BeregnGebyrApi, ) { fun Behandling.tilSærbidragAvslagskode() = validering.run { tilSærbidragAvslagskode() } @@ -68,6 +76,60 @@ class VedtakGrunnlagMapper( ) } + private fun Behandling.gebyrGrunnlagslisteDefaultVerdi(rolle: Rolle) = + if (avslag != null) { + emptyList() + } else { + beregnetInntekterGrunnlagForRolle(rolle) + } + + fun beregnGebyr( + behandling: Behandling, + rolle: Rolle, + grunnlagsliste: List = behandling.gebyrGrunnlagslisteDefaultVerdi(rolle), + ): BeregnGebyrResultat { + val gebyrBeregning = + if (behandling.avslag != null) { + beregnGebyrApi.beregnGebyr(grunnlagsliste, rolle.tilGrunnlagsreferanse()) + + mapper.run { behandling.tilGrunnlagInntektSiste12Mnd(rolle) } + } else { + beregnGebyrApi.beregnGebyr(grunnlagsliste, rolle.tilGrunnlagsreferanse()) + }.filterNotNull() + val delberegningSumInntekt = gebyrBeregning.gebyrDelberegningSumInntekt + val inntektSiste12Mnd = gebyrBeregning.finnInntektSiste12Mnd(rolle) + return BeregnGebyrResultat( + skattepliktigInntekt = + delberegningSumInntekt?.skattepliktigInntekt ?: inntektSiste12Mnd?.innhold?.beløp ?: BigDecimal.ZERO, + maksBarnetillegg = delberegningSumInntekt?.barnetillegg, + resultatkode = gebyrBeregning.sluttberegningGebyr!!.innhold.tilResultatkode(), + beløpGebyrsats = gebyrBeregning.gebyrBeløp!!, + grunnlagsreferanseListeEngangsbeløp = + listOfNotNull( + gebyrBeregning.sluttberegningGebyr!!.referanse, + inntektSiste12Mnd?.referanse, + ), + ilagtGebyr = gebyrBeregning.sluttberegningGebyr!!.innhold.ilagtGebyr, + grunnlagsliste = gebyrBeregning, + ) + } + + fun Behandling.beregnetInntekterGrunnlagForRolle(rolle: Rolle) = + BeregnApi() + .beregnInntekt(tilInntektberegningDto(rolle)) + .inntektPerBarnListe + .filter { it.inntektGjelderBarnIdent != null } + .flatMap { beregningBarn -> + beregningBarn.summertInntektListe.map { + GrunnlagDto( + referanse = "${Grunnlagstype.DELBEREGNING_SUM_INNTEKT}_${rolle.tilGrunnlagsreferanse()}", + type = Grunnlagstype.DELBEREGNING_SUM_INNTEKT, + innhold = POJONode(it), + gjelderReferanse = rolle.tilGrunnlagsreferanse(), + gjelderBarnReferanse = beregningBarn.inntektGjelderBarnIdent!!.verdi, + ) + } + } + fun byggGrunnlagForBeregning( behandling: Behandling, søknadsbarnRolle: Rolle, diff --git "a/src/main/resources/db/migration/V2.34.0__alter_table_rolle_add_column_har_gebyrs\303\270knad.sql" "b/src/main/resources/db/migration/V2.34.0__alter_table_rolle_add_column_har_gebyrs\303\270knad.sql" new file mode 100644 index 000000000..a4479fe5d --- /dev/null +++ "b/src/main/resources/db/migration/V2.34.0__alter_table_rolle_add_column_har_gebyrs\303\270knad.sql" @@ -0,0 +1 @@ +alter table rolle add column if not exists har_gebyrsøknad boolean not null default false; diff --git a/src/main/resources/db/migration/V2.34.1__alter_table_rolle_add_column_manuelt_overstyrt_gebyr.sql b/src/main/resources/db/migration/V2.34.1__alter_table_rolle_add_column_manuelt_overstyrt_gebyr.sql new file mode 100644 index 000000000..e722c1913 --- /dev/null +++ b/src/main/resources/db/migration/V2.34.1__alter_table_rolle_add_column_manuelt_overstyrt_gebyr.sql @@ -0,0 +1 @@ +alter table rolle add column if not exists manuelt_overstyrt_gebyr jsonb; diff --git a/src/test/kotlin/no/nav/bidrag/behandling/dto/v2/gebyr/GebyrValideringsfeilTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/dto/v2/gebyr/GebyrValideringsfeilTest.kt new file mode 100644 index 000000000..279cb48ac --- /dev/null +++ b/src/test/kotlin/no/nav/bidrag/behandling/dto/v2/gebyr/GebyrValideringsfeilTest.kt @@ -0,0 +1,72 @@ +package no.nav.bidrag.behandling.dto.v2.gebyr + +import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.shouldBe +import no.nav.bidrag.behandling.database.datamodell.RolleManueltOverstyrtGebyr +import no.nav.bidrag.behandling.utils.testdata.opprettGyldigBehandlingForBeregningOgVedtak +import no.nav.bidrag.domene.enums.behandling.TypeBehandling +import no.nav.bidrag.domene.enums.beregning.Resultatkode +import org.junit.jupiter.api.Test + +class GebyrValideringsfeilTest { + @Test + fun `skal feile validering hvis ingen begrunnelse for manuelt overstyrt gebyr`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.bidragspliktig!!.harGebyrsøknad = false + val bm = behandling.bidragsmottaker!! + bm.harGebyrsøknad = true + bm.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, false, null) + val resultat = behandling.validerGebyr() + resultat.shouldHaveSize(1) + resultat.first().manglerBegrunnelse shouldBe true + resultat.first().måBestemmeGebyr shouldBe false + } + + @Test + fun `skal feile validering hvis gebyr ikke satt ved avslag`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.avslag = Resultatkode.BIDRAGSPLIKTIG_ER_DØD + behandling.bidragspliktig!!.harGebyrsøknad = false + val bm = behandling.bidragsmottaker!! + bm.harGebyrsøknad = true + bm.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, null, null) + val resultat = behandling.validerGebyr() + resultat.shouldHaveSize(1) + resultat.first().manglerBegrunnelse shouldBe true + resultat.first().måBestemmeGebyr shouldBe true + } + + @Test + fun `skal ikke feile validering hvis gebyr og begrunnelse er satt ved avslag`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.avslag = Resultatkode.BIDRAGSPLIKTIG_ER_DØD + behandling.bidragspliktig!!.harGebyrsøknad = false + val bm = behandling.bidragsmottaker!! + bm.harGebyrsøknad = true + bm.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, true, "Begrunnelse") + val resultat = behandling.validerGebyr() + resultat.shouldHaveSize(0) + } + + @Test + fun `skal ikke feile validering hvis gebyr og begrunnelse er satt`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.bidragspliktig!!.harGebyrsøknad = false + val bm = behandling.bidragsmottaker!! + bm.harGebyrsøknad = true + bm.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, true, "Begrunnelse") + val resultat = behandling.validerGebyr() + resultat.shouldHaveSize(0) + } + + @Test + fun `skal ikke feile validering hvis ikke manuelt overstyrt`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.bidragspliktig!!.harGebyrsøknad = false + val bm = behandling.bidragsmottaker!! + bm.harGebyrsøknad = true + bm.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(false, null, null) + val resultat = behandling.validerGebyr() + resultat.shouldHaveSize(0) + } +} diff --git a/src/test/kotlin/no/nav/bidrag/behandling/service/BehandlingServiceTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/service/BehandlingServiceTest.kt index baaede521..f72cbde71 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/service/BehandlingServiceTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/service/BehandlingServiceTest.kt @@ -1332,6 +1332,19 @@ class BehandlingServiceTest : TestContainerRunner() { behandling.roller = mutableSetOf( + Rolle( + behandling, + ident = testdataBP.ident, + rolletype = Rolletype.BIDRAGSPLIKTIG, + fødselsdato = LocalDate.parse("2021-01-01"), + ), + Rolle( + behandling, + ident = testdataBM.ident, + rolletype = Rolletype.BIDRAGSMOTTAKER, + fødselsdato = LocalDate.parse("2021-01-01"), + harGebyrsøknad = true, + ), Rolle( behandling, ident = identOriginaltMedISaken, @@ -1367,6 +1380,24 @@ class BehandlingServiceTest : TestContainerRunner() { behandlingService.oppdaterRoller( behandling.id!!, listOf( + OpprettRolleDto( + Rolletype.BIDRAGSPLIKTIG, + Personident(testdataBP.ident), + null, + fødselsdato = LocalDate.now().minusMonths(144), + null, + false, + harGebyrsøknad = true, + ), + OpprettRolleDto( + Rolletype.BIDRAGSMOTTAKER, + Personident(testdataBM.ident), + null, + fødselsdato = LocalDate.now().minusMonths(144), + null, + false, + harGebyrsøknad = false, + ), OpprettRolleDto( Rolletype.BARN, Personident(identOriginaltMedISaken), @@ -1400,6 +1431,8 @@ class BehandlingServiceTest : TestContainerRunner() { ) val behandlingEtter = behandlingService.hentBehandlingById(behandling.id!!) response.status shouldBe OppdaterRollerStatus.ROLLER_OPPDATERT + behandlingEtter.bidragspliktig!!.harGebyrsøknad shouldBe true + behandlingEtter.bidragsmottaker!!.harGebyrsøknad shouldBe false behandlingEtter.søknadsbarn shouldHaveSize 3 behandlingEtter.søknadsbarn.find { it.ident == "1111234" }!!.innbetaltBeløp shouldBe BigDecimal("100.254") behandlingEtter.husstandsmedlem shouldHaveSize 3 diff --git a/src/test/kotlin/no/nav/bidrag/behandling/service/BeregningEvnevurderingServiceTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/service/BeregningEvnevurderingServiceTest.kt index 94995eea6..c280e61e9 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/service/BeregningEvnevurderingServiceTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/service/BeregningEvnevurderingServiceTest.kt @@ -27,6 +27,7 @@ import no.nav.bidrag.behandling.utils.testdata.testdataBP import no.nav.bidrag.behandling.utils.testdata.testdataBarn1 import no.nav.bidrag.behandling.utils.testdata.testdataBarn2 import no.nav.bidrag.behandling.utils.testdata.testdataHusstandsmedlem1 +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi import no.nav.bidrag.beregn.vedtak.Vedtaksfiltrering import no.nav.bidrag.commons.service.sjablon.SjablonService @@ -102,7 +103,7 @@ class BeregningEvnevurderingServiceTest { evnevurderingService = BeregningEvnevurderingService(bidragStønadConsumer, bidragVedtakConsumer, bidragBBMConsumer, beregingVedtaksfiltrering) - vedtakGrunnlagMapper = VedtakGrunnlagMapper(behandlingTilGrunnlagMapping, validerBeregning, evnevurderingService, personService) + vedtakGrunnlagMapper = VedtakGrunnlagMapper(behandlingTilGrunnlagMapping, validerBeregning, evnevurderingService, personService, BeregnGebyrApi(sjablonService)) stubSjablonProvider() initMockTestdata() } diff --git a/src/test/kotlin/no/nav/bidrag/behandling/service/BeregningServiceTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/service/BeregningServiceTest.kt index c6970bbab..4d32f8a55 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/service/BeregningServiceTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/service/BeregningServiceTest.kt @@ -23,6 +23,7 @@ import no.nav.bidrag.behandling.utils.testdata.oppretteUtgift import no.nav.bidrag.behandling.utils.testdata.testdataBarn1 import no.nav.bidrag.behandling.utils.testdata.testdataBarn2 import no.nav.bidrag.behandling.utils.testdata.testdataHusstandsmedlem1 +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi import no.nav.bidrag.beregn.forskudd.BeregnForskuddApi import no.nav.bidrag.beregn.særbidrag.BeregnSærbidragApi @@ -89,6 +90,7 @@ class BeregningServiceTest { ValiderBeregning(), evnevurderingService, personService, + BeregnGebyrApi(stubSjablonService()), ) } diff --git a/src/test/kotlin/no/nav/bidrag/behandling/service/CommonVedtakTilBehandlingTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/service/CommonVedtakTilBehandlingTest.kt index 452bcce93..8229fe1d6 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/service/CommonVedtakTilBehandlingTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/service/CommonVedtakTilBehandlingTest.kt @@ -16,6 +16,7 @@ import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.Behandling import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.BehandlingTilVedtakMapping import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.VedtakGrunnlagMapper import no.nav.bidrag.beregn.barnebidrag.BeregnBarnebidragApi +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi import no.nav.bidrag.commons.web.mock.stubKodeverkProvider import no.nav.bidrag.commons.web.mock.stubSjablonProvider @@ -62,6 +63,7 @@ abstract class CommonVedtakTilBehandlingTest { lateinit var sakConsumer: BidragSakConsumer lateinit var personConsumer: BidragPersonConsumer lateinit var vedtakService: VedtakService + lateinit var beregningService: BeregningService lateinit var dtomapper: Dtomapper val unleash = FakeUnleash() @@ -75,12 +77,20 @@ abstract class CommonVedtakTilBehandlingTest { personConsumer = stubPersonConsumer() val personService = PersonService(personConsumer) val behandlingTilGrunnlagMappingV2 = BehandlingTilGrunnlagMappingV2(personService, BeregnSamværsklasseApi(stubSjablonService())) + val vedtakGrunnlagMapper = + VedtakGrunnlagMapper( + behandlingTilGrunnlagMappingV2, + validerBeregning, + evnevurderingService, + personService, + BeregnGebyrApi(stubSjablonService()), + ) dtomapper = Dtomapper( tilgangskontrollService, validerBeregning, validerBehandlingService, - VedtakGrunnlagMapper(behandlingTilGrunnlagMappingV2, validerBeregning, evnevurderingService, personService), + vedtakGrunnlagMapper, BeregnBarnebidragApi(), ) val underholdService = @@ -91,20 +101,17 @@ abstract class CommonVedtakTilBehandlingTest { dtomapper, ) val vedtakTilBehandlingMapping = VedtakTilBehandlingMapping(validerBeregning, underholdService = underholdService) - val vedtakGrunnlagMapper = - VedtakGrunnlagMapper( - BehandlingTilGrunnlagMappingV2(personService, BeregnSamværsklasseApi(stubSjablonService())), - validerBeregning, - evnevurderingService, - personService, - ) - beregningService = BeregningService( behandlingService, vedtakGrunnlagMapper, ) - val behandlingTilVedtakMapping = BehandlingTilVedtakMapping(sakConsumer, vedtakGrunnlagMapper, beregningService) + val behandlingTilVedtakMapping = + BehandlingTilVedtakMapping( + sakConsumer, + vedtakGrunnlagMapper, + beregningService, + ) vedtakService = VedtakService( @@ -119,6 +126,7 @@ abstract class CommonVedtakTilBehandlingTest { behandlingTilVedtakMapping, validerBehandlingService, ) + unleash.enableAll() every { grunnlagService.oppdatereGrunnlagForBehandling(any()) } returns Unit every { tilgangskontrollService.sjekkTilgangPersonISak(any(), any()) } returns Unit diff --git a/src/test/kotlin/no/nav/bidrag/behandling/service/GebyrServiceTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/service/GebyrServiceTest.kt new file mode 100644 index 000000000..b0d8d76cb --- /dev/null +++ b/src/test/kotlin/no/nav/bidrag/behandling/service/GebyrServiceTest.kt @@ -0,0 +1,240 @@ +package no.nav.bidrag.behandling.service + +import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.shouldBe +import io.kotest.matchers.string.shouldContain +import io.mockk.impl.annotations.MockK +import io.mockk.junit5.MockKExtension +import no.nav.bidrag.behandling.database.datamodell.Behandling +import no.nav.bidrag.behandling.database.datamodell.Inntekt +import no.nav.bidrag.behandling.database.datamodell.RolleManueltOverstyrtGebyr +import no.nav.bidrag.behandling.dto.v2.gebyr.ManueltOverstyrGebyrDto +import no.nav.bidrag.behandling.dto.v2.gebyr.OppdaterManueltGebyrDto +import no.nav.bidrag.behandling.transformers.beregning.ValiderBeregning +import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.BehandlingTilGrunnlagMappingV2 +import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.VedtakGrunnlagMapper +import no.nav.bidrag.behandling.utils.testdata.opprettGyldigBehandlingForBeregningOgVedtak +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi +import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi +import no.nav.bidrag.commons.web.mock.stubSjablonProvider +import no.nav.bidrag.commons.web.mock.stubSjablonService +import no.nav.bidrag.domene.enums.behandling.TypeBehandling +import no.nav.bidrag.domene.enums.beregning.Resultatkode +import no.nav.bidrag.domene.enums.diverse.Kilde +import no.nav.bidrag.domene.enums.inntekt.Inntektsrapportering +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.web.client.HttpClientErrorException +import stubPersonConsumer +import java.math.BigDecimal + +@ExtendWith(MockKExtension::class) +class GebyrServiceTest { + @MockK + lateinit var evnevurderingService: BeregningEvnevurderingService + lateinit var gebyrService: GebyrService + lateinit var vedtakGrunnlagMapper: VedtakGrunnlagMapper + + @BeforeEach + fun initMocks() { + val personService = PersonService(stubPersonConsumer()) + stubSjablonProvider() + vedtakGrunnlagMapper = + VedtakGrunnlagMapper( + BehandlingTilGrunnlagMappingV2(personService, BeregnSamværsklasseApi(stubSjablonService())), + ValiderBeregning(), + evnevurderingService, + personService, + BeregnGebyrApi(stubSjablonService()), + ) + gebyrService = GebyrService(vedtakGrunnlagMapper) + } + + @Test + fun `skal oppdatere gebyr`() { + val behandling = opprettBehandlingForGebyrberegning() + val bm = behandling.bidragsmottaker!! + gebyrService.oppdaterManueltOverstyrtGebyr( + behandling, + OppdaterManueltGebyrDto( + rolleId = bm.id!!, + overstyrtGebyr = ManueltOverstyrGebyrDto(begrunnelse = "Begrunnelse"), + ), + ) + + bm.manueltOverstyrtGebyr.shouldNotBeNull() + bm.manueltOverstyrtGebyr!!.overstyrGebyr shouldBe true + bm.manueltOverstyrtGebyr!!.ilagtGebyr shouldBe false + bm.manueltOverstyrtGebyr!!.begrunnelse shouldBe "Begrunnelse" + } + + @Test + fun `skal feile hvis det settes gebyr for en rolle som ikke har gebyrsøknad`() { + val behandling = opprettBehandlingForGebyrberegning(BigDecimal(100)) + val bm = behandling.bidragsmottaker!! + val exception = + assertThrows { + gebyrService.oppdaterManueltOverstyrtGebyr( + behandling, + OppdaterManueltGebyrDto( + rolleId = bm.id!!, + overstyrtGebyr = ManueltOverstyrGebyrDto(ilagtGebyr = false, begrunnelse = "Begrunnelse"), + ), + ) + } + exception.message shouldContain "Kan ikke sette gebyr til samme som beregnet gebyr når det ikke er avslag" + } + + @Test + fun `skal feile hvis gebyrvalg blir satt hvis ikke avslag`() { + val behandling = opprettBehandlingForGebyrberegning(BigDecimal(100)) + val bm = behandling.bidragsmottaker!! + bm.harGebyrsøknad = false + val exception = + assertThrows { + gebyrService.oppdaterManueltOverstyrtGebyr( + behandling, + OppdaterManueltGebyrDto( + rolleId = bm.id!!, + overstyrtGebyr = ManueltOverstyrGebyrDto(begrunnelse = "Begrunnelse"), + ), + ) + } + exception.message shouldContain "Kan ikke endre gebyr på en rolle som ikke har gebyrsøknad" + } + + @Test + fun `skal oppdatere gebyr når inntekt er under gebyr grense`() { + val behandling = opprettBehandlingForGebyrberegning(BigDecimal(100)) + val bm = behandling.bidragsmottaker!! + gebyrService.oppdaterManueltOverstyrtGebyr( + behandling, + OppdaterManueltGebyrDto( + rolleId = bm.id!!, + overstyrtGebyr = ManueltOverstyrGebyrDto(begrunnelse = "Begrunnelse"), + ), + ) + + bm.manueltOverstyrtGebyr.shouldNotBeNull() + bm.manueltOverstyrtGebyr!!.overstyrGebyr shouldBe true + bm.manueltOverstyrtGebyr!!.ilagtGebyr shouldBe true + bm.manueltOverstyrtGebyr!!.begrunnelse shouldBe "Begrunnelse" + } + + @Test + fun `skal fjerne manuelt overstyrt gebyr`() { + val behandling = opprettBehandlingForGebyrberegning(BigDecimal(100)) + val bm = behandling.bidragsmottaker!! + bm.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(overstyrGebyr = true, ilagtGebyr = true, begrunnelse = "Begrunnelse") + gebyrService.oppdaterManueltOverstyrtGebyr( + behandling, + OppdaterManueltGebyrDto( + rolleId = bm.id!!, + overstyrtGebyr = null, + ), + ) + + bm.manueltOverstyrtGebyr.shouldNotBeNull() + bm.manueltOverstyrtGebyr!!.overstyrGebyr shouldBe false + bm.manueltOverstyrtGebyr!!.ilagtGebyr shouldBe true + bm.manueltOverstyrtGebyr!!.begrunnelse shouldBe "Begrunnelse" + } + + @Test + fun `skal oppdatere uten gebyrvalg ved avslag`() { + val behandling = opprettBehandlingForGebyrberegning(BigDecimal(100)) + val bm = behandling.bidragsmottaker!! + behandling.avslag = Resultatkode.BIDRAGSPLIKTIG_ER_DØD + gebyrService.oppdaterManueltOverstyrtGebyr( + behandling, + OppdaterManueltGebyrDto( + rolleId = bm.id!!, + overstyrtGebyr = ManueltOverstyrGebyrDto(ilagtGebyr = null, begrunnelse = "Begrunnelse"), + ), + ) + + bm.manueltOverstyrtGebyr.shouldNotBeNull() + bm.manueltOverstyrtGebyr!!.overstyrGebyr shouldBe true + bm.manueltOverstyrtGebyr!!.ilagtGebyr shouldBe null + bm.manueltOverstyrtGebyr!!.begrunnelse shouldBe "Begrunnelse" + } + + @Test + fun `skal sette gebyrvalg og begrunnelse ved avslag`() { + val behandling = opprettBehandlingForGebyrberegning(BigDecimal(100)) + val bm = behandling.bidragsmottaker!! + behandling.avslag = Resultatkode.BIDRAGSPLIKTIG_ER_DØD + gebyrService.oppdaterManueltOverstyrtGebyr( + behandling, + OppdaterManueltGebyrDto( + rolleId = bm.id!!, + overstyrtGebyr = ManueltOverstyrGebyrDto(ilagtGebyr = false, begrunnelse = "Begrunnelse"), + ), + ) + + bm.manueltOverstyrtGebyr.shouldNotBeNull() + bm.manueltOverstyrtGebyr!!.overstyrGebyr shouldBe true + bm.manueltOverstyrtGebyr!!.ilagtGebyr shouldBe false + bm.manueltOverstyrtGebyr!!.begrunnelse shouldBe "Begrunnelse" + } + + @Test + fun `skal oppdatere gebyr når det endres til avslag`() { + val behandling = opprettBehandlingForGebyrberegning(BigDecimal(100)) + val bm = behandling.bidragsmottaker!! + behandling.avslag = Resultatkode.BIDRAGSPLIKTIG_ER_DØD + gebyrService.oppdaterGebyrEtterEndringÅrsakAvslag(behandling) + + bm.manueltOverstyrtGebyr.shouldNotBeNull() + bm.manueltOverstyrtGebyr!!.overstyrGebyr shouldBe true + bm.manueltOverstyrtGebyr!!.ilagtGebyr shouldBe null + bm.manueltOverstyrtGebyr!!.begrunnelse shouldBe null + } + + @Test + fun `skal oppdatere gebyr når det endres til ikke avslag`() { + val behandling = opprettBehandlingForGebyrberegning(BigDecimal(100)) + val bm = behandling.bidragsmottaker!! + bm.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, false, "Begrunnelse") + gebyrService.oppdaterGebyrEtterEndringÅrsakAvslag(behandling) + + bm.manueltOverstyrtGebyr.shouldNotBeNull() + bm.manueltOverstyrtGebyr!!.overstyrGebyr shouldBe false + bm.manueltOverstyrtGebyr!!.ilagtGebyr shouldBe true + bm.manueltOverstyrtGebyr!!.begrunnelse shouldBe "Begrunnelse" + } + + @Test + fun `skal oppdatere gebyr når det endres til ikke avslag og sette ilagtGebyr basert på beregning`() { + val behandling = opprettBehandlingForGebyrberegning(BigDecimal(1000000000)) + val bm = behandling.bidragsmottaker!! + bm.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, false, "Begrunnelse") + gebyrService.oppdaterGebyrEtterEndringÅrsakAvslag(behandling) + + bm.manueltOverstyrtGebyr.shouldNotBeNull() + bm.manueltOverstyrtGebyr!!.overstyrGebyr shouldBe false + bm.manueltOverstyrtGebyr!!.ilagtGebyr shouldBe false + bm.manueltOverstyrtGebyr!!.begrunnelse shouldBe "Begrunnelse" + } +} + +private fun opprettBehandlingForGebyrberegning(inntektBeløp: BigDecimal = BigDecimal(500000)): Behandling { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(generateId = true, typeBehandling = TypeBehandling.BIDRAG) + behandling.bidragsmottaker!!.harGebyrsøknad = true + behandling.inntekter.add( + Inntekt( + belop = inntektBeløp, + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.PERSONINNTEKT_EGNE_OPPLYSNINGER, + id = 2, + ), + ) + return behandling +} diff --git a/src/test/kotlin/no/nav/bidrag/behandling/service/UnderholdServiceTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/service/UnderholdServiceTest.kt index a87be230e..52f208c6b 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/service/UnderholdServiceTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/service/UnderholdServiceTest.kt @@ -34,6 +34,7 @@ import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.Behandling import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.VedtakGrunnlagMapper import no.nav.bidrag.behandling.utils.testdata.oppretteTestbehandling import no.nav.bidrag.beregn.barnebidrag.BeregnBarnebidragApi +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi import no.nav.bidrag.commons.web.mock.stubSjablonProvider import no.nav.bidrag.commons.web.mock.stubSjablonService @@ -67,6 +68,9 @@ class UnderholdServiceTest { @MockkBean lateinit var personConsumer: BidragPersonConsumer + @MockkBean + lateinit var behandlingService: BehandlingService + @MockK lateinit var tilgangskontrollService: TilgangskontrollService @@ -104,8 +108,8 @@ class UnderholdServiceTest { ValiderBeregning(), evnevurderingService, personService, + BeregnGebyrApi(stubSjablonService()), ) - dtomapper = Dtomapper( tilgangskontrollService, diff --git a/src/test/kotlin/no/nav/bidrag/behandling/service/UtgiftserviceMockTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/service/UtgiftserviceMockTest.kt index 6831deae5..c032e99cd 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/service/UtgiftserviceMockTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/service/UtgiftserviceMockTest.kt @@ -50,6 +50,9 @@ class UtgiftserviceMockTest { @MockK lateinit var vedtakGrunnlagMapper: VedtakGrunnlagMapper + @MockK + lateinit var behandlingService: BehandlingService + @MockK lateinit var personService: PersonService diff --git a/src/test/kotlin/no/nav/bidrag/behandling/service/VedtakserviceBidragTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/service/VedtakserviceBidragTest.kt index fcf358c55..68324ce0e 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/service/VedtakserviceBidragTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/service/VedtakserviceBidragTest.kt @@ -11,7 +11,10 @@ import io.mockk.every import io.mockk.slot import io.mockk.verify import no.nav.bidrag.behandling.database.datamodell.Behandling +import no.nav.bidrag.behandling.database.datamodell.Inntekt +import no.nav.bidrag.behandling.database.datamodell.RolleManueltOverstyrtGebyr import no.nav.bidrag.behandling.service.NotatService.Companion.henteNotatinnhold +import no.nav.bidrag.behandling.transformers.grunnlag.tilGrunnlagsreferanse import no.nav.bidrag.behandling.utils.harReferanseTilGrunnlag import no.nav.bidrag.behandling.utils.hentGrunnlagstype import no.nav.bidrag.behandling.utils.hentGrunnlagstyper @@ -37,6 +40,8 @@ import no.nav.bidrag.behandling.utils.testdata.testdataBP import no.nav.bidrag.behandling.utils.testdata.testdataBarn1 import no.nav.bidrag.behandling.utils.testdata.testdataBarnBm import no.nav.bidrag.behandling.utils.testdata.testdataHusstandsmedlem1 +import no.nav.bidrag.behandling.utils.validerHarReferanseTilGrunnlagIReferanser +import no.nav.bidrag.behandling.utils.validerHarReferanseTilSjablonIReferanser import no.nav.bidrag.behandling.utils.virkningsdato import no.nav.bidrag.domene.enums.barnetilsyn.Skolealder import no.nav.bidrag.domene.enums.barnetilsyn.Tilsynstype @@ -48,6 +53,7 @@ import no.nav.bidrag.domene.enums.grunnlag.Grunnlagstype import no.nav.bidrag.domene.enums.inntekt.Inntektsrapportering import no.nav.bidrag.domene.enums.person.Bostatuskode import no.nav.bidrag.domene.enums.rolle.SøktAvType +import no.nav.bidrag.domene.enums.sjablon.SjablonTallNavn import no.nav.bidrag.domene.enums.vedtak.Beslutningstype import no.nav.bidrag.domene.enums.vedtak.Engangsbeløptype import no.nav.bidrag.domene.enums.vedtak.Innkrevingstype @@ -215,23 +221,33 @@ class VedtakserviceBidragTest : CommonVedtakTilBehandlingTest() { shouldHaveSize(2) val gebyrMottaker = it.find { it.type == Engangsbeløptype.GEBYR_MOTTAKER }!! - gebyrMottaker.beløp shouldBe BigDecimal(0) + gebyrMottaker.beløp shouldBe BigDecimal(1277) gebyrMottaker.kravhaver shouldBe Personident("NAV") gebyrMottaker.mottaker shouldBe Personident("NAV") gebyrMottaker.innkreving shouldBe Innkrevingstype.MED_INNKREVING - gebyrMottaker.resultatkode shouldBe Resultatkode.GEBYR_ILAGT.name + gebyrMottaker.resultatkode shouldBe Resultatkode.GEBYR_FRITTATT.name gebyrMottaker.sak shouldBe Saksnummer(SAKSNUMMER) gebyrMottaker.skyldner shouldBe Personident(testdataBM.ident) - + gebyrMottaker.grunnlagReferanseListe shouldHaveSize 1 + val sluttberegningGebyrBM = opprettVedtakRequest.grunnlagListe.finnGrunnlagSomErReferertFraGrunnlagsreferanseListe(Grunnlagstype.SLUTTBEREGNING_GEBYR, gebyrMottaker.grunnlagReferanseListe).firstOrNull() + sluttberegningGebyrBM!!.gjelderReferanse shouldBe behandling.bidragsmottaker!!.tilGrunnlagsreferanse() + sluttberegningGebyrBM.grunnlagsreferanseListe shouldHaveSize 2 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.DELBEREGNING_INNTEKTSBASERT_GEBYR, sluttberegningGebyrBM.grunnlagsreferanseListe) + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilSjablonIReferanser(SjablonTallNavn.FASTSETTELSESGEBYR_BELØP, sluttberegningGebyrBM.grunnlagsreferanseListe) val gebyrSkyldner = it.find { it.type == Engangsbeløptype.GEBYR_SKYLDNER }!! - gebyrSkyldner.beløp shouldBe BigDecimal(0) + gebyrSkyldner.beløp shouldBe BigDecimal(1277) gebyrSkyldner.kravhaver shouldBe Personident("NAV") gebyrSkyldner.mottaker shouldBe Personident("NAV") gebyrSkyldner.innkreving shouldBe Innkrevingstype.MED_INNKREVING gebyrSkyldner.resultatkode shouldBe Resultatkode.GEBYR_ILAGT.name gebyrSkyldner.sak shouldBe Saksnummer(SAKSNUMMER) gebyrSkyldner.skyldner shouldBe Personident(testdataBP.ident) + val sluttberegningGebyrBP = opprettVedtakRequest.grunnlagListe.finnGrunnlagSomErReferertFraGrunnlagsreferanseListe(Grunnlagstype.SLUTTBEREGNING_GEBYR, gebyrSkyldner.grunnlagReferanseListe).firstOrNull() + sluttberegningGebyrBP!!.gjelderReferanse shouldBe behandling.bidragspliktig!!.tilGrunnlagsreferanse() + sluttberegningGebyrBP.grunnlagsreferanseListe shouldHaveSize 2 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.DELBEREGNING_INNTEKTSBASERT_GEBYR, sluttberegningGebyrBP.grunnlagsreferanseListe) + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilSjablonIReferanser(SjablonTallNavn.FASTSETTELSESGEBYR_BELØP, sluttberegningGebyrBP.grunnlagsreferanseListe) } opprettVedtakRequest.validerVedtaksdetaljer(behandling) @@ -262,7 +278,9 @@ class VedtakserviceBidragTest : CommonVedtakTilBehandlingTest() { } } validerNotater(behandling) - hentGrunnlagstyper(Grunnlagstype.SJABLON_SJABLONTALL) shouldHaveSize 31 + hentGrunnlagstyper(Grunnlagstype.DELBEREGNING_INNTEKTSBASERT_GEBYR) shouldHaveSize 2 + hentGrunnlagstyper(Grunnlagstype.SLUTTBEREGNING_GEBYR) shouldHaveSize 2 + hentGrunnlagstyper(Grunnlagstype.SJABLON_SJABLONTALL) shouldHaveSize 28 hentGrunnlagstyper(Grunnlagstype.SJABLON_BIDRAGSEVNE) shouldHaveSize 3 hentGrunnlagstyper(Grunnlagstype.SJABLON_MAKS_FRADRAG) shouldHaveSize 2 hentGrunnlagstyper(Grunnlagstype.SJABLON_MAKS_TILSYN) shouldHaveSize 3 @@ -297,6 +315,213 @@ class VedtakserviceBidragTest : CommonVedtakTilBehandlingTest() { verify(exactly = 1) { notatOpplysningerService.opprettNotat(any()) } } + @Test + fun `Skal fatte vedtak med manuelt overstyrt gebyr`() { + stubPersonConsumer() + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.leggTilSamvær(ÅrMånedsperiode(behandling.virkningstidspunkt!!, behandling.virkningstidspunkt!!.plusMonths(1)), samværsklasse = Samværsklasse.SAMVÆRSKLASSE_1, medId = true) + behandling.leggTilSamvær(ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(1), null), medId = true) + behandling.leggTilTillegsstønad(ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(4), null), medId = true) + behandling.leggTilFaktiskTilsynsutgift(ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(1), null), testdataHusstandsmedlem1, medId = true) + behandling.leggTilFaktiskTilsynsutgift( + ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(1), null), + testdataBarnBm, + medId = true, + ) + behandling.leggTilFaktiskTilsynsutgift(ÅrMånedsperiode(behandling.virkningstidspunkt!!, null), medId = true) + behandling.leggTilBarnetilsyn(ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(1), null), generateId = true) + behandling.leggTilBarnetilsyn( + ÅrMånedsperiode(behandling.virkningstidspunkt!!, behandling.virkningstidspunkt!!.plusMonths(1)), + generateId = true, + tilsynstype = Tilsynstype.IKKE_ANGITT, + under_skolealder = null, + kilde = Kilde.OFFENTLIG, + ) + behandling.leggTilBarnetillegg(testdataBarn1, behandling.bidragsmottaker!!, medId = true) + behandling.leggTilBarnetillegg(testdataBarn1, behandling.bidragspliktig!!, medId = true) + + behandling.leggTilNotat( + "Inntektsbegrunnelse kun i notat", + NotatGrunnlag.NotatType.INNTEKT, + behandling.bidragsmottaker, + ) + behandling.leggTilNotat( + "Virkningstidspunkt kun i notat", + NotatGrunnlag.NotatType.VIRKNINGSTIDSPUNKT, + ) + behandling.leggTilNotat( + "Boforhold", + NotatGrunnlag.NotatType.BOFORHOLD, + ) + behandling.leggTilNotat( + "Samvær", + NotatGrunnlag.NotatType.SAMVÆR, + behandling.søknadsbarn.first(), + ) + behandling.leggTilNotat( + "Underhold barn", + NotatGrunnlag.NotatType.UNDERHOLDSKOSTNAD, + behandling.søknadsbarn.first(), + ) + behandling.leggTilNotat( + "Underhold andre barn", + NotatGrunnlag.NotatType.UNDERHOLDSKOSTNAD, + behandling.bidragsmottaker, + ) + behandling.refVedtaksid = 553 + behandling.grunnlag = + opprettAlleAktiveGrunnlagFraFil( + behandling, + erstattVariablerITestFil("grunnlagresponse_bp"), + ) + + every { behandlingService.hentBehandlingById(any()) } returns behandling + + every { sakConsumer.hentSak(any()) } returns opprettSakForBehandling(behandling) + + val opprettVedtakSlot = slot() + every { vedtakConsumer.fatteVedtak(capture(opprettVedtakSlot)) } returns + OpprettVedtakResponseDto( + 1, + emptyList(), + ) + + behandling.bidragsmottaker!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, false, "Begrunnelse") + + vedtakService.fatteVedtak(behandling.id!!) + + val opprettVedtakRequest = opprettVedtakSlot.captured + + assertSoftly(opprettVedtakRequest.engangsbeløpListe) { + shouldHaveSize(2) + val gebyrMottaker = it.find { it.type == Engangsbeløptype.GEBYR_MOTTAKER }!! + + gebyrMottaker.beløp shouldBe BigDecimal(1277) + gebyrMottaker.kravhaver shouldBe Personident("NAV") + gebyrMottaker.mottaker shouldBe Personident("NAV") + gebyrMottaker.innkreving shouldBe Innkrevingstype.MED_INNKREVING + gebyrMottaker.resultatkode shouldBe Resultatkode.GEBYR_FRITTATT.name + gebyrMottaker.sak shouldBe Saksnummer(SAKSNUMMER) + gebyrMottaker.skyldner shouldBe Personident(testdataBM.ident) + gebyrMottaker.grunnlagReferanseListe shouldHaveSize 1 + val sluttberegningGebyrBM = opprettVedtakRequest.grunnlagListe.finnGrunnlagSomErReferertFraGrunnlagsreferanseListe(Grunnlagstype.SLUTTBEREGNING_GEBYR, gebyrMottaker.grunnlagReferanseListe).firstOrNull() + sluttberegningGebyrBM!!.gjelderReferanse shouldBe behandling.bidragsmottaker!!.tilGrunnlagsreferanse() + sluttberegningGebyrBM.grunnlagsreferanseListe shouldHaveSize 3 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.MANUELT_OVERSTYRT_GEBYR, sluttberegningGebyrBM.grunnlagsreferanseListe) + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.DELBEREGNING_INNTEKTSBASERT_GEBYR, sluttberegningGebyrBM.grunnlagsreferanseListe) + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilSjablonIReferanser(SjablonTallNavn.FASTSETTELSESGEBYR_BELØP, sluttberegningGebyrBM.grunnlagsreferanseListe) + val gebyrSkyldner = it.find { it.type == Engangsbeløptype.GEBYR_SKYLDNER }!! + + gebyrSkyldner.beløp shouldBe BigDecimal(1277) + gebyrSkyldner.kravhaver shouldBe Personident("NAV") + gebyrSkyldner.mottaker shouldBe Personident("NAV") + gebyrSkyldner.innkreving shouldBe Innkrevingstype.MED_INNKREVING + gebyrSkyldner.resultatkode shouldBe Resultatkode.GEBYR_ILAGT.name + gebyrSkyldner.sak shouldBe Saksnummer(SAKSNUMMER) + gebyrSkyldner.skyldner shouldBe Personident(testdataBP.ident) + val sluttberegningGebyrBP = opprettVedtakRequest.grunnlagListe.finnGrunnlagSomErReferertFraGrunnlagsreferanseListe(Grunnlagstype.SLUTTBEREGNING_GEBYR, gebyrSkyldner.grunnlagReferanseListe).firstOrNull() + sluttberegningGebyrBP!!.gjelderReferanse shouldBe behandling.bidragspliktig!!.tilGrunnlagsreferanse() + sluttberegningGebyrBP.grunnlagsreferanseListe shouldHaveSize 2 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.DELBEREGNING_INNTEKTSBASERT_GEBYR, sluttberegningGebyrBP.grunnlagsreferanseListe) + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilSjablonIReferanser(SjablonTallNavn.FASTSETTELSESGEBYR_BELØP, sluttberegningGebyrBP.grunnlagsreferanseListe) + } + + verify(exactly = 1) { + vedtakConsumer.fatteVedtak(any()) + } + verify(exactly = 1) { notatOpplysningerService.opprettNotat(any()) } + } + + @Test + fun `Skal fatte vedtak hvor BM og BP ikke har gebyrsøknad`() { + stubPersonConsumer() + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.leggTilSamvær(ÅrMånedsperiode(behandling.virkningstidspunkt!!, behandling.virkningstidspunkt!!.plusMonths(1)), samværsklasse = Samværsklasse.SAMVÆRSKLASSE_1, medId = true) + behandling.leggTilSamvær(ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(1), null), medId = true) + behandling.leggTilTillegsstønad(ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(4), null), medId = true) + behandling.leggTilFaktiskTilsynsutgift(ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(1), null), testdataHusstandsmedlem1, medId = true) + behandling.leggTilFaktiskTilsynsutgift( + ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(1), null), + testdataBarnBm, + medId = true, + ) + behandling.leggTilFaktiskTilsynsutgift(ÅrMånedsperiode(behandling.virkningstidspunkt!!, null), medId = true) + behandling.leggTilBarnetilsyn(ÅrMånedsperiode(behandling.virkningstidspunkt!!.plusMonths(1), null), generateId = true) + behandling.leggTilBarnetilsyn( + ÅrMånedsperiode(behandling.virkningstidspunkt!!, behandling.virkningstidspunkt!!.plusMonths(1)), + generateId = true, + tilsynstype = Tilsynstype.IKKE_ANGITT, + under_skolealder = null, + kilde = Kilde.OFFENTLIG, + ) + behandling.leggTilBarnetillegg(testdataBarn1, behandling.bidragsmottaker!!, medId = true) + behandling.leggTilBarnetillegg(testdataBarn1, behandling.bidragspliktig!!, medId = true) + + behandling.leggTilNotat( + "Inntektsbegrunnelse kun i notat", + NotatGrunnlag.NotatType.INNTEKT, + behandling.bidragsmottaker, + ) + behandling.leggTilNotat( + "Virkningstidspunkt kun i notat", + NotatGrunnlag.NotatType.VIRKNINGSTIDSPUNKT, + ) + behandling.leggTilNotat( + "Boforhold", + NotatGrunnlag.NotatType.BOFORHOLD, + ) + behandling.leggTilNotat( + "Samvær", + NotatGrunnlag.NotatType.SAMVÆR, + behandling.søknadsbarn.first(), + ) + behandling.leggTilNotat( + "Underhold barn", + NotatGrunnlag.NotatType.UNDERHOLDSKOSTNAD, + behandling.søknadsbarn.first(), + ) + behandling.leggTilNotat( + "Underhold andre barn", + NotatGrunnlag.NotatType.UNDERHOLDSKOSTNAD, + behandling.bidragsmottaker, + ) + behandling.refVedtaksid = 553 + behandling.grunnlag = + opprettAlleAktiveGrunnlagFraFil( + behandling, + erstattVariablerITestFil("grunnlagresponse_bp"), + ) + + every { behandlingService.hentBehandlingById(any()) } returns behandling + + every { sakConsumer.hentSak(any()) } returns opprettSakForBehandling(behandling) + + val opprettVedtakSlot = slot() + every { vedtakConsumer.fatteVedtak(capture(opprettVedtakSlot)) } returns + OpprettVedtakResponseDto( + 1, + emptyList(), + ) + + behandling.bidragsmottaker!!.harGebyrsøknad = false + behandling.bidragspliktig!!.harGebyrsøknad = false + behandling.søknadsbarn.first().innbetaltBeløp = BigDecimal(10000) + + vedtakService.fatteVedtak(behandling.id!!) + + val opprettVedtakRequest = opprettVedtakSlot.captured + + assertSoftly(opprettVedtakRequest.engangsbeløpListe) { + shouldHaveSize(1) + it.any { it.type == Engangsbeløptype.DIREKTE_OPPGJØR }.shouldBeTrue() + } + + verify(exactly = 1) { + vedtakConsumer.fatteVedtak(any()) + } + verify(exactly = 1) { notatOpplysningerService.opprettNotat(any()) } + } + @Test fun `Skal fatte vedtak med reel mottaker`() { stubPersonConsumer() @@ -545,6 +770,8 @@ class VedtakserviceBidragTest : CommonVedtakTilBehandlingTest() { fun `Skal fatte vedtak med direkte avslag`() { stubPersonConsumer() val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.bidragspliktig!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, true, "Begrunnelse") + behandling.bidragsmottaker!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, false, "Begrunnelse") behandling.leggTilNotat( "Virkningstidspunkt kun i notat", NotatGrunnlag.NotatType.VIRKNINGSTIDSPUNKT, @@ -576,7 +803,10 @@ class VedtakserviceBidragTest : CommonVedtakTilBehandlingTest() { val request = opprettVedtakRequest request.type shouldBe Vedtakstype.FASTSETTELSE - request.grunnlagListe shouldHaveSize 5 + request.grunnlagListe shouldHaveSize 10 + hentGrunnlagstyper(Grunnlagstype.MANUELT_OVERSTYRT_GEBYR) shouldHaveSize 2 + hentGrunnlagstyper(Grunnlagstype.SLUTTBEREGNING_GEBYR) shouldHaveSize 2 + hentGrunnlagstyper(Grunnlagstype.SJABLON_SJABLONTALL) shouldHaveSize 1 hentGrunnlagstyper(Grunnlagstype.NOTAT) shouldHaveSize 1 hentGrunnlagstyper(Grunnlagstype.PERSON_BIDRAGSMOTTAKER) shouldHaveSize 1 hentGrunnlagstyper(Grunnlagstype.PERSON_SØKNADSBARN) shouldHaveSize 1 @@ -611,6 +841,133 @@ class VedtakserviceBidragTest : CommonVedtakTilBehandlingTest() { it.any { it.type == Engangsbeløptype.GEBYR_MOTTAKER }.shouldBeTrue() it.any { it.type == Engangsbeløptype.GEBYR_SKYLDNER }.shouldBeTrue() + assertSoftly(it.find { it.type == Engangsbeløptype.GEBYR_MOTTAKER }!!) { + beløp shouldBe BigDecimal(1277) + kravhaver shouldBe Personident("NAV") + mottaker shouldBe Personident("NAV") + innkreving shouldBe Innkrevingstype.MED_INNKREVING + resultatkode shouldBe Resultatkode.GEBYR_FRITTATT.name + sak shouldBe Saksnummer(SAKSNUMMER) + skyldner shouldBe Personident(testdataBM.ident) + grunnlagReferanseListe shouldHaveSize 1 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.SLUTTBEREGNING_GEBYR, grunnlagReferanseListe) + } + assertSoftly(it.find { it.type == Engangsbeløptype.GEBYR_SKYLDNER }!!) { + beløp shouldBe BigDecimal(1277) + kravhaver shouldBe Personident("NAV") + mottaker shouldBe Personident("NAV") + innkreving shouldBe Innkrevingstype.MED_INNKREVING + resultatkode shouldBe Resultatkode.GEBYR_ILAGT.name + sak shouldBe Saksnummer(SAKSNUMMER) + skyldner shouldBe Personident(testdataBP.ident) + grunnlagReferanseListe shouldHaveSize 1 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.SLUTTBEREGNING_GEBYR, grunnlagReferanseListe) + } + } + + verify(exactly = 1) { + vedtakConsumer.fatteVedtak(any()) + } + } + + @Test + fun `Skal fatte vedtak med direkte avslag og lage grunnlag for gebyr`() { + stubPersonConsumer() + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.inntekter.add( + Inntekt( + belop = BigDecimal(2000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + gjelderBarn = behandling.søknadsbarn.first().ident, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.BARNETILLEGG, + id = 1, + ), + ) + behandling.inntekter.add( + Inntekt( + belop = BigDecimal(90000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = false, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.AINNTEKT_BEREGNET_12MND, + id = 1, + ), + ) + behandling.bidragspliktig!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, true, "Begrunnelse") + behandling.bidragsmottaker!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, false, "Begrunnelse") + behandling.leggTilNotat( + "Virkningstidspunkt kun i notat", + NotatGrunnlag.NotatType.VIRKNINGSTIDSPUNKT, + ) + behandling.avslag = Resultatkode.BIDRAGSPLIKTIG_ER_DØD + behandling.refVedtaksid = 553 + behandling.grunnlag = + opprettAlleAktiveGrunnlagFraFil( + behandling, + erstattVariablerITestFil("grunnlagresponse_bp"), + ) + + every { behandlingService.hentBehandlingById(any()) } returns behandling + + every { sakConsumer.hentSak(any()) } returns opprettSakForBehandling(behandling) + + val opprettVedtakSlot = slot() + every { vedtakConsumer.fatteVedtak(capture(opprettVedtakSlot)) } returns + OpprettVedtakResponseDto( + 1, + emptyList(), + ) + + vedtakService.fatteVedtak(behandling.id!!) + + val opprettVedtakRequest = opprettVedtakSlot.captured + + assertSoftly(opprettVedtakRequest.engangsbeløpListe) { + shouldHaveSize(2) + + it.any { it.type == Engangsbeløptype.GEBYR_MOTTAKER }.shouldBeTrue() + it.any { it.type == Engangsbeløptype.GEBYR_SKYLDNER }.shouldBeTrue() + assertSoftly(it.find { it.type == Engangsbeløptype.GEBYR_MOTTAKER }!!) { + beløp shouldBe BigDecimal(1277) + kravhaver shouldBe Personident("NAV") + mottaker shouldBe Personident("NAV") + innkreving shouldBe Innkrevingstype.MED_INNKREVING + resultatkode shouldBe Resultatkode.GEBYR_FRITTATT.name + sak shouldBe Saksnummer(SAKSNUMMER) + skyldner shouldBe Personident(testdataBM.ident) + grunnlagReferanseListe shouldHaveSize 2 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.SLUTTBEREGNING_GEBYR, grunnlagReferanseListe) + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.INNTEKT_RAPPORTERING_PERIODE, grunnlagReferanseListe) + val sluttberegningGebyrBM = opprettVedtakRequest.grunnlagListe.finnGrunnlagSomErReferertFraGrunnlagsreferanseListe(Grunnlagstype.SLUTTBEREGNING_GEBYR, grunnlagReferanseListe).firstOrNull() + sluttberegningGebyrBM!!.gjelderReferanse shouldBe behandling.bidragsmottaker!!.tilGrunnlagsreferanse() + sluttberegningGebyrBM.grunnlagsreferanseListe shouldHaveSize 2 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.MANUELT_OVERSTYRT_GEBYR, sluttberegningGebyrBM.grunnlagsreferanseListe) + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilSjablonIReferanser(SjablonTallNavn.FASTSETTELSESGEBYR_BELØP, sluttberegningGebyrBM.grunnlagsreferanseListe) + } + assertSoftly(it.find { it.type == Engangsbeløptype.GEBYR_SKYLDNER }!!) { + beløp shouldBe BigDecimal(1277) + kravhaver shouldBe Personident("NAV") + mottaker shouldBe Personident("NAV") + innkreving shouldBe Innkrevingstype.MED_INNKREVING + resultatkode shouldBe Resultatkode.GEBYR_ILAGT.name + sak shouldBe Saksnummer(SAKSNUMMER) + skyldner shouldBe Personident(testdataBP.ident) + grunnlagReferanseListe shouldHaveSize 1 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.SLUTTBEREGNING_GEBYR, grunnlagReferanseListe) + val sluttberegningGebyrBP = opprettVedtakRequest.grunnlagListe.finnGrunnlagSomErReferertFraGrunnlagsreferanseListe(Grunnlagstype.SLUTTBEREGNING_GEBYR, grunnlagReferanseListe).firstOrNull() + sluttberegningGebyrBP!!.gjelderReferanse shouldBe behandling.bidragspliktig!!.tilGrunnlagsreferanse() + sluttberegningGebyrBP.grunnlagsreferanseListe shouldHaveSize 2 + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilGrunnlagIReferanser(Grunnlagstype.MANUELT_OVERSTYRT_GEBYR, sluttberegningGebyrBP.grunnlagsreferanseListe) + opprettVedtakRequest.grunnlagListe.validerHarReferanseTilSjablonIReferanser(SjablonTallNavn.FASTSETTELSESGEBYR_BELØP, sluttberegningGebyrBP.grunnlagsreferanseListe) + } } verify(exactly = 1) { @@ -622,6 +979,8 @@ class VedtakserviceBidragTest : CommonVedtakTilBehandlingTest() { fun `Skal fatte vedtak med direkte avslag med reel mottaker`() { stubPersonConsumer() val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.bidragspliktig!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, true, "Begrunnelse") + behandling.bidragsmottaker!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, true, "Begrunnelse") behandling.leggTilNotat( "Virkningstidspunkt kun i notat", NotatGrunnlag.NotatType.VIRKNINGSTIDSPUNKT, @@ -766,8 +1125,8 @@ private fun OpprettVedtakRequestDto.validerSluttberegning() { assertSoftly(sluttberegningPeriode) { val innhold = innholdTilObjekt() innhold.resultatVisningsnavn!!.intern shouldBe "Kostnadsberegnet bidrag" - innhold.beregnetBeløp shouldBe BigDecimal("6121.53") - innhold.resultatBeløp shouldBe BigDecimal("6120") + innhold.beregnetBeløp shouldBe BigDecimal("5741.53") + innhold.resultatBeløp shouldBe BigDecimal("5740") it.grunnlagsreferanseListe shouldHaveSize 8 hentGrunnlagstyperForReferanser(Grunnlagstype.PERSON_SØKNADSBARN, it.grunnlagsreferanseListe) shouldHaveSize 1 hentGrunnlagstyperForReferanser(Grunnlagstype.PERSON_SØKNADSBARN, it.grunnlagsreferanseListe).first().referanse shouldBe søknadsbarn1Grunnlag.referanse @@ -782,21 +1141,21 @@ private fun OpprettVedtakRequestDto.validerSluttberegning() { assertSoftly(hentGrunnlagstyperForReferanser(Grunnlagstype.DELBEREGNING_BIDRAGSEVNE, sluttberegningPeriode.grunnlagsreferanseListe).first()) { val innhold = innholdTilObjekt() innhold.beløp shouldBe BigDecimal("9482.45") - it.grunnlagsreferanseListe shouldHaveSize 14 + it.grunnlagsreferanseListe shouldHaveSize 11 } assertSoftly(hentGrunnlagstyperForReferanser(Grunnlagstype.DELBEREGNING_BIDRAGSPLIKTIGES_ANDEL, sluttberegningPeriode.grunnlagsreferanseListe).first()) { val innhold = innholdTilObjekt() - innhold.andelBeløp shouldBe BigDecimal("7132.53") - it.grunnlagsreferanseListe shouldHaveSize 10 + innhold.andelBeløp shouldBe BigDecimal("6752.53") + it.grunnlagsreferanseListe shouldHaveSize 6 } assertSoftly(hentGrunnlagstyperForReferanser(Grunnlagstype.DELBEREGNING_UNDERHOLDSKOSTNAD, sluttberegningPeriode.grunnlagsreferanseListe).first()) { val innhold = innholdTilObjekt() - innhold.underholdskostnad shouldBe BigDecimal("8559.04") + innhold.underholdskostnad shouldBe BigDecimal("8103.04") innhold.nettoTilsynsutgift shouldBe BigDecimal("1287.04") innhold.barnetilsynMedStønad shouldBe BigDecimal("630.00") - it.grunnlagsreferanseListe shouldHaveSize 6 + it.grunnlagsreferanseListe shouldHaveSize 7 } assertSoftly(hentGrunnlagstyperForReferanser(Grunnlagstype.DELBEREGNING_SAMVÆRSFRADRAG, sluttberegningPeriode.grunnlagsreferanseListe).first()) { diff --git a/src/test/kotlin/no/nav/bidrag/behandling/service/VedtakserviceTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/service/VedtakserviceTest.kt index 64683230c..fe32f1b59 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/service/VedtakserviceTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/service/VedtakserviceTest.kt @@ -45,6 +45,7 @@ import no.nav.bidrag.behandling.utils.testdata.taMedInntekt import no.nav.bidrag.behandling.utils.testdata.testdataBarn1 import no.nav.bidrag.behandling.utils.testdata.testdataHusstandsmedlem1 import no.nav.bidrag.beregn.barnebidrag.BeregnBarnebidragApi +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi import no.nav.bidrag.commons.web.mock.stubKodeverkProvider import no.nav.bidrag.commons.web.mock.stubSjablonProvider @@ -120,6 +121,7 @@ class VedtakserviceTest : TestContainerRunner() { lateinit var entityManager: EntityManager lateinit var vedtakService: VedtakService + lateinit var beregningService: BeregningService @MockK @@ -137,15 +139,29 @@ class VedtakserviceTest : TestContainerRunner() { stubTokenUtils() unleash.enableAll() bidragPersonConsumer = stubPersonConsumer() + val personService = PersonService(bidragPersonConsumer) val validerBeregning = ValiderBeregning() val behandlingTilGrunnlagMappingV2 = BehandlingTilGrunnlagMappingV2(personService, BeregnSamværsklasseApi(stubSjablonService())) + val vedtakGrunnlagMapper = + VedtakGrunnlagMapper( + behandlingTilGrunnlagMappingV2, + validerBeregning, + evnevurderingService, + personService, + BeregnGebyrApi(stubSjablonService()), + ) + beregningService = + BeregningService( + behandlingService, + vedtakGrunnlagMapper, + ) val dtomapper = Dtomapper( tilgangskontrollService, validerBeregning, validerBehandlingService, - VedtakGrunnlagMapper(behandlingTilGrunnlagMappingV2, validerBeregning, evnevurderingService, personService), + vedtakGrunnlagMapper, BeregnBarnebidragApi(), ) val underholdService = @@ -156,20 +172,13 @@ class VedtakserviceTest : TestContainerRunner() { dtomapper, ) val vedtakTilBehandlingMapping = VedtakTilBehandlingMapping(validerBeregning, underholdService) - val vedtakGrunnlagMapper = - VedtakGrunnlagMapper( - BehandlingTilGrunnlagMappingV2(personService, BeregnSamværsklasseApi(stubSjablonService())), - validerBeregning, - evnevurderingService, - personService, - ) - beregningService = - BeregningService( - behandlingService, + val behandlingTilVedtakMapping = + BehandlingTilVedtakMapping( + sakConsumer, vedtakGrunnlagMapper, + beregningService, ) - val behandlingTilVedtakMapping = BehandlingTilVedtakMapping(sakConsumer, vedtakGrunnlagMapper, beregningService) vedtakService = VedtakService( behandlingService, @@ -335,11 +344,13 @@ class VedtakserviceTest : TestContainerRunner() { request.stønadsendringListe.shouldHaveSize(1) request.engangsbeløpListe shouldHaveSize 3 withClue("Grunnlagliste skal inneholde ${request.grunnlagListe.size} grunnlag") { - request.grunnlagListe shouldHaveSize 177 + request.grunnlagListe shouldHaveSize 179 } } assertSoftly(opprettVedtakRequest) { + hentGrunnlagstyper(Grunnlagstype.SLUTTBEREGNING_GEBYR) shouldHaveSize 2 + hentGrunnlagstyper(Grunnlagstype.DELBEREGNING_INNTEKTSBASERT_GEBYR) shouldHaveSize 2 hentGrunnlagstyper(Grunnlagstype.NOTAT) shouldHaveSize 7 hentGrunnlagstyper(Grunnlagstype.TILLEGGSSTØNAD_PERIODE) shouldHaveSize 1 hentGrunnlagstyper(Grunnlagstype.FAKTISK_UTGIFT_PERIODE) shouldHaveSize 2 @@ -351,7 +362,7 @@ class VedtakserviceTest : TestContainerRunner() { hentGrunnlagstyper(Grunnlagstype.VIRKNINGSTIDSPUNKT) shouldHaveSize 1 hentGrunnlagstyper(Grunnlagstype.SØKNAD) shouldHaveSize 1 hentGrunnlagstyper(Grunnlagstype.BEREGNET_INNTEKT) shouldHaveSize 3 - hentGrunnlagstyper(Grunnlagstype.SJABLON_SJABLONTALL) shouldHaveSize 22 + hentGrunnlagstyper(Grunnlagstype.SJABLON_SJABLONTALL) shouldHaveSize 20 hentGrunnlagstyper(Grunnlagstype.SJABLON_BIDRAGSEVNE) shouldHaveSize 2 hentGrunnlagstyper(Grunnlagstype.SJABLON_MAKS_FRADRAG) shouldHaveSize 2 hentGrunnlagstyper(Grunnlagstype.SJABLON_MAKS_TILSYN) shouldHaveSize 2 diff --git a/src/test/kotlin/no/nav/bidrag/behandling/transformers/DtoMapperMockTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/transformers/DtoMapperMockTest.kt new file mode 100644 index 000000000..d560aaca6 --- /dev/null +++ b/src/test/kotlin/no/nav/bidrag/behandling/transformers/DtoMapperMockTest.kt @@ -0,0 +1,283 @@ +package no.nav.bidrag.behandling.transformers + +import io.kotest.assertions.assertSoftly +import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.nulls.shouldBeNull +import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.shouldBe +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.junit5.MockKExtension +import no.nav.bidrag.behandling.database.datamodell.Inntekt +import no.nav.bidrag.behandling.database.datamodell.RolleManueltOverstyrtGebyr +import no.nav.bidrag.behandling.service.BeregningEvnevurderingService +import no.nav.bidrag.behandling.service.PersonService +import no.nav.bidrag.behandling.service.TilgangskontrollService +import no.nav.bidrag.behandling.service.ValiderBehandlingService +import no.nav.bidrag.behandling.transformers.beregning.ValiderBeregning +import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.BehandlingTilGrunnlagMappingV2 +import no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak.VedtakGrunnlagMapper +import no.nav.bidrag.behandling.utils.testdata.opprettGyldigBehandlingForBeregningOgVedtak +import no.nav.bidrag.beregn.barnebidrag.BeregnBarnebidragApi +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi +import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi +import no.nav.bidrag.commons.web.mock.stubSjablonProvider +import no.nav.bidrag.commons.web.mock.stubSjablonService +import no.nav.bidrag.domene.enums.behandling.TypeBehandling +import no.nav.bidrag.domene.enums.beregning.Resultatkode +import no.nav.bidrag.domene.enums.diverse.Kilde +import no.nav.bidrag.domene.enums.inntekt.Inntektsrapportering +import no.nav.bidrag.domene.enums.rolle.Rolletype +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import stubPersonConsumer +import java.math.BigDecimal + +@ExtendWith(MockKExtension::class) +class DtoMapperMockTest { + lateinit var dtomapper: Dtomapper + + @MockK + lateinit var tilgangskontrollService: TilgangskontrollService + + @MockK + lateinit var evnevurderingService: BeregningEvnevurderingService + + @MockK + lateinit var validerBehandlingService: ValiderBehandlingService + + @BeforeEach + fun init() { + val personService = PersonService(stubPersonConsumer()) + val validerBeregning = ValiderBeregning() + val behandlingTilGrunnlagMappingV2 = BehandlingTilGrunnlagMappingV2(personService, BeregnSamværsklasseApi(stubSjablonService())) + val vedtakGrunnlagMapper = + VedtakGrunnlagMapper( + behandlingTilGrunnlagMappingV2, + ValiderBeregning(), + evnevurderingService, + personService, + BeregnGebyrApi(stubSjablonService()), + ) + dtomapper = + Dtomapper( + tilgangskontrollService, + validerBeregning, + validerBehandlingService, + vedtakGrunnlagMapper, + BeregnBarnebidragApi(), + ) + + stubPersonConsumer() + stubSjablonProvider() + every { validerBehandlingService.kanBehandlesINyLøsning(any()) } returns null + every { tilgangskontrollService.harBeskyttelse(any()) } returns false + every { tilgangskontrollService.harTilgang(any(), any()) } returns true + } + + @Test + fun `skal hente og mappe gebyr`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.inntekter = + mutableSetOf( + Inntekt( + belop = BigDecimal(900000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.PERSONINNTEKT_EGNE_OPPLYSNINGER, + id = 1, + ), + Inntekt( + belop = BigDecimal(20000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragspliktig!!.ident!!, + taMed = true, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.PERSONINNTEKT_EGNE_OPPLYSNINGER, + id = 1, + ), + Inntekt( + belop = BigDecimal(20000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + gjelderBarn = behandling.søknadsbarn.first().ident, + taMed = true, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.BARNETILLEGG, + id = 1, + ), + Inntekt( + belop = BigDecimal(10000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + gjelderBarn = "123123123", + taMed = true, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.BARNETILLEGG, + id = 1, + ), + ) + val behandlingDto = dtomapper.tilDto(behandling) + + behandlingDto.shouldNotBeNull() + val gebyr = behandlingDto.gebyr + gebyr.shouldNotBeNull() + gebyr.gebyrRoller.shouldHaveSize(2) + assertSoftly(gebyr.gebyrRoller.find { it.rolle.rolletype == Rolletype.BIDRAGSMOTTAKER }!!) { + it.inntekt.skattepliktigInntekt shouldBe BigDecimal(900000) + it.inntekt.maksBarnetillegg shouldBe BigDecimal(20000) + it.inntekt.totalInntekt shouldBe BigDecimal(920000) + it.beregnetIlagtGebyr shouldBe true + it.manueltOverstyrtGebyr.shouldBeNull() + } + assertSoftly(gebyr.gebyrRoller.find { it.rolle.rolletype == Rolletype.BIDRAGSPLIKTIG }!!) { + it.inntekt.skattepliktigInntekt shouldBe BigDecimal(20000) + it.inntekt.maksBarnetillegg shouldBe null + it.inntekt.totalInntekt shouldBe BigDecimal(20000) + it.beregnetIlagtGebyr shouldBe false + it.manueltOverstyrtGebyr.shouldBeNull() + } + } + + @Test + fun `skal hente og mappe manuelt overstyrt gebyr`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.inntekter.add( + Inntekt( + belop = BigDecimal(2000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = false, + gjelderBarn = behandling.søknadsbarn.first().ident, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.BARNETILLEGG, + id = 1, + ), + ) + behandling.inntekter.add( + Inntekt( + belop = BigDecimal(2000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragspliktig!!.ident!!, + gjelderBarn = behandling.søknadsbarn.first().ident, + taMed = true, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.BARNETILLEGG, + id = 1, + ), + ) + behandling.bidragsmottaker!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, true, "Begrunnelse") + val behandlingDto = dtomapper.tilDto(behandling) + + behandlingDto.shouldNotBeNull() + val gebyr = behandlingDto.gebyr + gebyr.shouldNotBeNull() + gebyr.gebyrRoller.shouldHaveSize(2) + assertSoftly(gebyr.gebyrRoller.find { it.rolle.rolletype == Rolletype.BIDRAGSMOTTAKER }!!) { + it.inntekt.skattepliktigInntekt shouldBe BigDecimal(50000) + it.inntekt.maksBarnetillegg shouldBe null + it.inntekt.totalInntekt shouldBe BigDecimal(50000) + it.beregnetIlagtGebyr shouldBe false + it.manueltOverstyrtGebyr.shouldNotBeNull() + it.manueltOverstyrtGebyr.ilagtGebyr shouldBe true + it.manueltOverstyrtGebyr.begrunnelse shouldBe "Begrunnelse" + } + assertSoftly(gebyr.gebyrRoller.find { it.rolle.rolletype == Rolletype.BIDRAGSPLIKTIG }!!) { + it.inntekt.skattepliktigInntekt shouldBe BigDecimal(500000) + it.inntekt.maksBarnetillegg shouldBe BigDecimal(2000) + it.inntekt.totalInntekt shouldBe BigDecimal(502000) + it.beregnetIlagtGebyr shouldBe true + it.manueltOverstyrtGebyr.shouldBeNull() + } + } + + @Test + fun `skal ikke mappe gebyr hvis rolle ikke har gebyrsøknad`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.bidragsmottaker!!.harGebyrsøknad = false + behandling.bidragspliktig!!.harGebyrsøknad = false + val behandlingDto = dtomapper.tilDto(behandling) + + behandlingDto.shouldNotBeNull() + behandlingDto.gebyr.shouldBeNull() + } + + @Test + fun `skal hente og mappe gebyr ved avslag`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.avslag = Resultatkode.AVSLAG + behandling.inntekter.add( + Inntekt( + belop = BigDecimal(2000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + gjelderBarn = behandling.søknadsbarn.first().ident, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.BARNETILLEGG, + id = 1, + ), + ) + behandling.inntekter.add( + Inntekt( + belop = BigDecimal(90000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = false, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.AINNTEKT_BEREGNET_12MND, + id = 1, + ), + ) + + behandling.bidragsmottaker!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, false, "Begrunnelse") + val behandlingDto = dtomapper.tilDto(behandling) + + behandlingDto.shouldNotBeNull() + val gebyr = behandlingDto.gebyr + gebyr.shouldNotBeNull() + gebyr.gebyrRoller.shouldHaveSize(2) + gebyr.valideringsfeil!!.shouldHaveSize(1) + assertSoftly(gebyr.valideringsfeil.first()) { + it.gjelder.rolletype shouldBe Rolletype.BIDRAGSPLIKTIG + it.måBestemmeGebyr shouldBe true + it.manglerBegrunnelse shouldBe false + it.harFeil shouldBe true + } + assertSoftly(gebyr.gebyrRoller.find { it.rolle.rolletype == Rolletype.BIDRAGSMOTTAKER }!!) { + it.inntekt.skattepliktigInntekt shouldBe BigDecimal(90000) + it.inntekt.maksBarnetillegg shouldBe null + it.inntekt.totalInntekt shouldBe BigDecimal(90000) + it.beregnetIlagtGebyr shouldBe false + it.manueltOverstyrtGebyr.shouldNotBeNull() + it.manueltOverstyrtGebyr.ilagtGebyr shouldBe false + it.manueltOverstyrtGebyr.begrunnelse shouldBe "Begrunnelse" + } + assertSoftly(gebyr.gebyrRoller.find { it.rolle.rolletype == Rolletype.BIDRAGSPLIKTIG }!!) { + it.inntekt.skattepliktigInntekt shouldBe BigDecimal(0) + it.inntekt.maksBarnetillegg shouldBe null + it.inntekt.totalInntekt shouldBe BigDecimal(0) + it.beregnetIlagtGebyr shouldBe false + it.manueltOverstyrtGebyr.shouldBeNull() + } + } +} diff --git a/src/test/kotlin/no/nav/bidrag/behandling/transformers/DtoMapperTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/transformers/DtoMapperTest.kt index c104a0331..c942011ab 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/transformers/DtoMapperTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/transformers/DtoMapperTest.kt @@ -13,6 +13,7 @@ import no.nav.bidrag.behandling.database.datamodell.Grunnlag import no.nav.bidrag.behandling.database.datamodell.Notat import no.nav.bidrag.behandling.database.datamodell.Person import no.nav.bidrag.behandling.dto.v2.behandling.Grunnlagsdatatype +import no.nav.bidrag.behandling.service.BehandlingService import no.nav.bidrag.behandling.service.BeregningEvnevurderingService import no.nav.bidrag.behandling.service.PersonService import no.nav.bidrag.behandling.service.TilgangskontrollService @@ -25,6 +26,7 @@ import no.nav.bidrag.behandling.utils.testdata.oppretteArbeidsforhold import no.nav.bidrag.behandling.utils.testdata.oppretteTestbehandling import no.nav.bidrag.behandling.utils.testdata.testdataBarn1 import no.nav.bidrag.beregn.barnebidrag.BeregnBarnebidragApi +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi import no.nav.bidrag.boforhold.dto.BoforholdResponseV2 import no.nav.bidrag.commons.web.mock.stubSjablonProvider @@ -60,6 +62,9 @@ class DtoMapperTest : TestContainerRunner() { @MockK lateinit var validering: ValiderBeregning + @MockK + lateinit var behandlingService: BehandlingService + @MockK lateinit var validerBehandlingService: ValiderBehandlingService @@ -81,6 +86,7 @@ class DtoMapperTest : TestContainerRunner() { ValiderBeregning(), evnevurderingService, personService, + BeregnGebyrApi(stubSjablonService()), ) dtomapper = Dtomapper(tilgangskontrollService, validering, validerBehandlingService, vedtakGrunnlagsmapper, BeregnBarnebidragApi()) stubUtils.stubTilgangskontrollPersonISak() diff --git a/src/test/kotlin/no/nav/bidrag/behandling/transformers/behandling/BehandlingDtoMappingTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/transformers/behandling/BehandlingDtoMappingTest.kt index 390169eb7..6539fb74c 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/transformers/behandling/BehandlingDtoMappingTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/transformers/behandling/BehandlingDtoMappingTest.kt @@ -14,6 +14,7 @@ import no.nav.bidrag.behandling.database.datamodell.Notat import no.nav.bidrag.behandling.database.datamodell.Utgiftspost import no.nav.bidrag.behandling.database.datamodell.konvertereData import no.nav.bidrag.behandling.dto.v2.behandling.Grunnlagsdatatype +import no.nav.bidrag.behandling.service.BehandlingService import no.nav.bidrag.behandling.service.BeregningEvnevurderingService import no.nav.bidrag.behandling.service.PersonService import no.nav.bidrag.behandling.service.TilgangskontrollService @@ -27,6 +28,7 @@ import no.nav.bidrag.behandling.utils.testdata.opprettGyldigBehandlingForBeregni import no.nav.bidrag.behandling.utils.testdata.oppretteTestbehandling import no.nav.bidrag.behandling.utils.testdata.oppretteUtgift import no.nav.bidrag.beregn.barnebidrag.BeregnBarnebidragApi +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi import no.nav.bidrag.boforhold.BoforholdApi import no.nav.bidrag.commons.web.mock.stubKodeverkProvider @@ -65,6 +67,9 @@ class BehandlingDtoMappingTest : TestContainerRunner() { @MockkBean lateinit var evnevurderingService: BeregningEvnevurderingService + @MockkBean + lateinit var behandlingService: BehandlingService + @MockK lateinit var personService: PersonService @@ -84,6 +89,7 @@ class BehandlingDtoMappingTest : TestContainerRunner() { ValiderBeregning(), evnevurderingService, personService, + BeregnGebyrApi(stubSjablonService()), ) mapper = Dtomapper( diff --git a/src/test/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagMappingTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagMappingTest.kt index 494b8ad5b..542621129 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagMappingTest.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/GrunnlagMappingTest.kt @@ -45,6 +45,7 @@ import no.nav.bidrag.behandling.utils.testdata.testdataBP import no.nav.bidrag.behandling.utils.testdata.testdataBarn1 import no.nav.bidrag.behandling.utils.testdata.testdataBarn2 import no.nav.bidrag.behandling.utils.testdata.testdataHusstandsmedlem1 +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi import no.nav.bidrag.commons.web.mock.stubKodeverkProvider import no.nav.bidrag.commons.web.mock.stubSjablonService @@ -169,7 +170,7 @@ class GrunnlagMappingTest { testdataHusstandsmedlem1 to Stønadstype.BIDRAG, ), ) - mapper = VedtakGrunnlagMapper(behandlingTilGrunnlagMapping, validering, evnevurderingService, personService) + mapper = VedtakGrunnlagMapper(behandlingTilGrunnlagMapping, validering, evnevurderingService, personService, BeregnGebyrApi(stubSjablonService())) } @Nested diff --git a/src/test/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/VedtakGrunnlagMapperTest.kt b/src/test/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/VedtakGrunnlagMapperTest.kt new file mode 100644 index 000000000..864a498a4 --- /dev/null +++ b/src/test/kotlin/no/nav/bidrag/behandling/transformers/vedtak/mapping/tilvedtak/VedtakGrunnlagMapperTest.kt @@ -0,0 +1,205 @@ +package no.nav.bidrag.behandling.transformers.vedtak.mapping.tilvedtak + +import io.kotest.assertions.assertSoftly +import io.kotest.matchers.collections.shouldContain +import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.shouldBe +import io.mockk.impl.annotations.MockK +import io.mockk.junit5.MockKExtension +import no.nav.bidrag.behandling.database.datamodell.Inntekt +import no.nav.bidrag.behandling.database.datamodell.RolleManueltOverstyrtGebyr +import no.nav.bidrag.behandling.service.BeregningEvnevurderingService +import no.nav.bidrag.behandling.service.PersonService +import no.nav.bidrag.behandling.transformers.beregning.ValiderBeregning +import no.nav.bidrag.behandling.utils.testdata.opprettGyldigBehandlingForBeregningOgVedtak +import no.nav.bidrag.behandling.utils.validerHarGrunnlag +import no.nav.bidrag.behandling.utils.validerHarReferanseTilSjablon +import no.nav.bidrag.beregn.barnebidrag.BeregnGebyrApi +import no.nav.bidrag.beregn.barnebidrag.BeregnSamværsklasseApi +import no.nav.bidrag.commons.web.mock.stubSjablonProvider +import no.nav.bidrag.commons.web.mock.stubSjablonService +import no.nav.bidrag.domene.enums.behandling.TypeBehandling +import no.nav.bidrag.domene.enums.beregning.Resultatkode +import no.nav.bidrag.domene.enums.diverse.Kilde +import no.nav.bidrag.domene.enums.grunnlag.Grunnlagstype +import no.nav.bidrag.domene.enums.inntekt.Inntektsrapportering +import no.nav.bidrag.domene.enums.sjablon.SjablonTallNavn +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import stubPersonConsumer +import java.math.BigDecimal + +@ExtendWith(MockKExtension::class) +class VedtakGrunnlagMapperTest { + lateinit var vedtakGrunnlagMapper: VedtakGrunnlagMapper + + @MockK + lateinit var evnevurderingService: BeregningEvnevurderingService + + @BeforeEach + fun init() { + val personService = PersonService(stubPersonConsumer()) + stubSjablonProvider() + val behandlingTilGrunnlagMappingV2 = BehandlingTilGrunnlagMappingV2(personService, BeregnSamværsklasseApi(stubSjablonService())) + vedtakGrunnlagMapper = + VedtakGrunnlagMapper( + behandlingTilGrunnlagMappingV2, + ValiderBeregning(), + evnevurderingService, + personService, + BeregnGebyrApi(stubSjablonService()), + ) + } + + @Test + fun `skal beregne gebyr`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.inntekter = + mutableSetOf( + Inntekt( + belop = BigDecimal(2000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + gjelderBarn = behandling.søknadsbarn.first().ident, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.BARNETILLEGG, + id = 1, + ), + Inntekt( + belop = BigDecimal(900000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + gjelderBarn = behandling.søknadsbarn.first().ident, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.AINNTEKT_BEREGNET_12MND, + id = 1, + ), + ) + + val resultat = vedtakGrunnlagMapper.beregnGebyr(behandling, behandling.bidragsmottaker!!) + assertSoftly(resultat) { + ilagtGebyr shouldBe true + skattepliktigInntekt shouldBe BigDecimal(900000) + maksBarnetillegg shouldBe BigDecimal(2000) + beløpGebyrsats shouldBe BigDecimal(1277) + resultatkode shouldBe Resultatkode.GEBYR_ILAGT + grunnlagsreferanseListeEngangsbeløp shouldHaveSize 1 + grunnlagsreferanseListeEngangsbeløp shouldContain grunnlagsliste.find { it.type == Grunnlagstype.SLUTTBEREGNING_GEBYR }!!.referanse + grunnlagsliste shouldHaveSize 5 + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.SLUTTBEREGNING_GEBYR) + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.SJABLON_SJABLONTALL, antall = 2) + grunnlagsliste.validerHarReferanseTilSjablon(SjablonTallNavn.NEDRE_INNTEKTSGRENSE_GEBYR_BELØP) + grunnlagsliste.validerHarReferanseTilSjablon(SjablonTallNavn.FASTSETTELSESGEBYR_BELØP) + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.DELBEREGNING_INNTEKTSBASERT_GEBYR, antall = 1) + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.DELBEREGNING_SUM_INNTEKT, antall = 1) + } + } + + @Test + fun `skal beregne gebyr ved avslag`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.avslag = Resultatkode.AVSLAG + behandling.inntekter = + mutableSetOf( + Inntekt( + belop = BigDecimal(2000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + gjelderBarn = behandling.søknadsbarn.first().ident, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.BARNETILLEGG, + id = 1, + ), + Inntekt( + belop = BigDecimal(900000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + gjelderBarn = behandling.søknadsbarn.first().ident, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.AINNTEKT_BEREGNET_12MND, + id = 1, + ), + ) + + val resultat = vedtakGrunnlagMapper.beregnGebyr(behandling, behandling.bidragsmottaker!!) + assertSoftly(resultat) { + ilagtGebyr shouldBe false + skattepliktigInntekt shouldBe BigDecimal(900000) + maksBarnetillegg shouldBe null + beløpGebyrsats shouldBe BigDecimal(1277) + resultatkode shouldBe Resultatkode.GEBYR_FRITTATT + grunnlagsreferanseListeEngangsbeløp shouldHaveSize 2 + grunnlagsreferanseListeEngangsbeløp shouldContain grunnlagsliste.find { it.type == Grunnlagstype.SLUTTBEREGNING_GEBYR }!!.referanse + grunnlagsreferanseListeEngangsbeløp shouldContain grunnlagsliste.find { it.type == Grunnlagstype.INNTEKT_RAPPORTERING_PERIODE }!!.referanse + grunnlagsliste shouldHaveSize 3 + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.SLUTTBEREGNING_GEBYR) + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.INNTEKT_RAPPORTERING_PERIODE) + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.SJABLON_SJABLONTALL, antall = 1) + grunnlagsliste.validerHarReferanseTilSjablon(SjablonTallNavn.FASTSETTELSESGEBYR_BELØP) + } + } + + @Test + fun `skal beregne gebyr ved avslag når manuelt gebyr er lagt inn`() { + val behandling = opprettGyldigBehandlingForBeregningOgVedtak(true, typeBehandling = TypeBehandling.BIDRAG) + behandling.avslag = Resultatkode.AVSLAG + behandling.inntekter = + mutableSetOf( + Inntekt( + belop = BigDecimal(2000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + gjelderBarn = behandling.søknadsbarn.first().ident, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.BARNETILLEGG, + id = 1, + ), + Inntekt( + belop = BigDecimal(900000), + datoFom = behandling.virkningstidspunkt, + datoTom = null, + ident = behandling.bidragsmottaker!!.ident!!, + taMed = true, + gjelderBarn = behandling.søknadsbarn.first().ident, + kilde = Kilde.MANUELL, + behandling = behandling, + type = Inntektsrapportering.AINNTEKT_BEREGNET_12MND, + id = 1, + ), + ) + + behandling.bidragsmottaker!!.manueltOverstyrtGebyr = RolleManueltOverstyrtGebyr(true, true, "test") + val resultat = vedtakGrunnlagMapper.beregnGebyr(behandling, behandling.bidragsmottaker!!) + assertSoftly(resultat) { + ilagtGebyr shouldBe false + skattepliktigInntekt shouldBe BigDecimal(900000) + maksBarnetillegg shouldBe null + beløpGebyrsats shouldBe BigDecimal(1277) + resultatkode shouldBe Resultatkode.GEBYR_FRITTATT + grunnlagsreferanseListeEngangsbeløp shouldHaveSize 2 + grunnlagsreferanseListeEngangsbeløp shouldContain grunnlagsliste.find { it.type == Grunnlagstype.SLUTTBEREGNING_GEBYR }!!.referanse + grunnlagsreferanseListeEngangsbeløp shouldContain grunnlagsliste.find { it.type == Grunnlagstype.INNTEKT_RAPPORTERING_PERIODE }!!.referanse + grunnlagsliste shouldHaveSize 3 + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.SLUTTBEREGNING_GEBYR) + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.INNTEKT_RAPPORTERING_PERIODE) + grunnlagsliste.validerHarGrunnlag(Grunnlagstype.SJABLON_SJABLONTALL, antall = 1) + grunnlagsliste.validerHarReferanseTilSjablon(SjablonTallNavn.FASTSETTELSESGEBYR_BELØP) + } + } +} diff --git a/src/test/kotlin/no/nav/bidrag/behandling/utils/TestdataExtensions.kt b/src/test/kotlin/no/nav/bidrag/behandling/utils/TestdataExtensions.kt index a0ef15d92..c9e27ccda 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/utils/TestdataExtensions.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/utils/TestdataExtensions.kt @@ -1,10 +1,20 @@ package no.nav.bidrag.behandling.utils +import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.collections.shouldNotBeEmpty +import io.kotest.matchers.shouldBe import no.nav.bidrag.domene.enums.grunnlag.Grunnlagstype +import no.nav.bidrag.domene.enums.sjablon.SjablonTallNavn import no.nav.bidrag.domene.ident.Personident import no.nav.bidrag.transport.behandling.beregning.felles.InntektPerBarn import no.nav.bidrag.transport.behandling.felles.grunnlag.BaseGrunnlag +import no.nav.bidrag.transport.behandling.felles.grunnlag.Grunnlagsreferanse +import no.nav.bidrag.transport.behandling.felles.grunnlag.SjablonSjablontallPeriode +import no.nav.bidrag.transport.behandling.felles.grunnlag.filtrerBasertPåEgenReferanse +import no.nav.bidrag.transport.behandling.felles.grunnlag.filtrerOgKonverterBasertPåEgenReferanse import no.nav.bidrag.transport.behandling.felles.grunnlag.finnGrunnlagSomErReferertAv +import no.nav.bidrag.transport.behandling.felles.grunnlag.finnGrunnlagSomErReferertFraGrunnlagsreferanseListe +import no.nav.bidrag.transport.behandling.felles.grunnlag.finnOgKonverterGrunnlagSomErReferertFraGrunnlagsreferanseListe fun List.hentInntektForBarn(barnIdent: String) = find { it.inntektGjelderBarnIdent == Personident(barnIdent) } @@ -12,3 +22,39 @@ fun List.harReferanseTilGrunnlag( grunnlag: Grunnlagstype, baseGrunnlag: BaseGrunnlag, ) = finnGrunnlagSomErReferertAv(grunnlag, baseGrunnlag).isNotEmpty() + +fun List.validerHarReferanseTilGrunnlagIReferanser( + grunnlag: Grunnlagstype, + referanse: List, + antall: Int? = null, +) = if (antall != null) { + finnGrunnlagSomErReferertFraGrunnlagsreferanseListe(grunnlag, referanse).shouldHaveSize(antall) +} else { + finnGrunnlagSomErReferertFraGrunnlagsreferanseListe(grunnlag, referanse).shouldNotBeEmpty() +} + +fun List.validerHarGrunnlag( + grunnlag: Grunnlagstype, + antall: Int? = null, +) = if (antall != null) { + filtrerBasertPåEgenReferanse(grunnlag).shouldHaveSize(antall) +} else { + filtrerBasertPåEgenReferanse(grunnlag).shouldNotBeEmpty() +} + +fun List.validerHarReferanseTilSjablon( + sjablon: SjablonTallNavn, +) { + val grunnlag = filtrerOgKonverterBasertPåEgenReferanse(Grunnlagstype.SJABLON_SJABLONTALL) + grunnlag.shouldNotBeEmpty() + grunnlag.any { it.innhold.sjablon == sjablon } shouldBe true +} + +fun List.validerHarReferanseTilSjablonIReferanser( + sjablon: SjablonTallNavn, + referanse: List, +) { + val grunnlag = finnOgKonverterGrunnlagSomErReferertFraGrunnlagsreferanseListe(Grunnlagstype.SJABLON_SJABLONTALL, referanse) + grunnlag.shouldNotBeEmpty() + grunnlag.first().innhold.sjablon shouldBe sjablon +} diff --git a/src/test/kotlin/no/nav/bidrag/behandling/utils/testdata/Testdata.kt b/src/test/kotlin/no/nav/bidrag/behandling/utils/testdata/Testdata.kt index 0b1c52c22..825c8491f 100644 --- a/src/test/kotlin/no/nav/bidrag/behandling/utils/testdata/Testdata.kt +++ b/src/test/kotlin/no/nav/bidrag/behandling/utils/testdata/Testdata.kt @@ -390,6 +390,7 @@ fun oppretteBehandlingRoller( behandling = behandling, fødselsdato = testdataBM.fødselsdato, id = if (generateId) (1).toLong() else null, + harGebyrsøknad = typeBehandling == TypeBehandling.BIDRAG, ), Rolle( ident = testdataBarn1.ident, @@ -419,6 +420,7 @@ fun oppretteBehandlingRoller( behandling = behandling, fødselsdato = testdataBP.fødselsdato, id = if (generateId) (4).toLong() else null, + harGebyrsøknad = typeBehandling == TypeBehandling.BIDRAG, ), ) }