Skip to content

Commit

Permalink
Merge pull request #806 from navikt/ny-utbetalingsgenerator
Browse files Browse the repository at this point in the history
Ny utbetalingsgenerator
  • Loading branch information
charliemidtlyng authored Oct 2, 2023
2 parents 08c1d6c + af275ca commit 4792bdd
Show file tree
Hide file tree
Showing 53 changed files with 1,029 additions and 183 deletions.
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<familie.eksterne-kontrakter.saksstatistikk-ef>2.0_20230214104704_706e9c0</familie.eksterne-kontrakter.saksstatistikk-ef>
<familie.eksterne-kontrakter.arbeidsoppfolging>2.0_20230214104704_706e9c0</familie.eksterne-kontrakter.arbeidsoppfolging>
<prosessering.version>2.20230807154047_d770f01</prosessering.version>
<utbetalingsgenerator.version>1.0_20230927085000_900743f</utbetalingsgenerator.version>
<brukernotifikasjon-schemas.version>2.5.2</brukernotifikasjon-schemas.version>
<maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version>
<confluent.version>7.5.0</confluent.version>
Expand Down Expand Up @@ -206,6 +207,12 @@
<version>${brukernotifikasjon-schemas.version}</version>
</dependency>

<dependency>
<groupId>no.nav.familie.felles</groupId>
<artifactId>familie-utbetalingsgenerator</artifactId>
<version>${utbetalingsgenerator.version}</version>
</dependency>

<!-- Database -->
<dependency>
<groupId>org.postgresql</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ class FeatureToggleService(val unleashService: UnleashService) {
fun isEnabled(toggleId: String): Boolean {
return unleashService.isEnabled(toggleId)
}

fun isEnabledMedFagsakId(toggleId: String, fagsakId: Long): Boolean {
return unleashService.isEnabled(toggleId, mapOf("fagsakId" to fagsakId.toString()))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ class CustomUnleashStrategies {
fun strategies(): List<Strategy> {
return listOf(ByEnvironmentStrategy())
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import no.nav.familie.ef.iverksett.iverksetting.domene.IverksettSkolepenger
import no.nav.familie.ef.iverksett.iverksetting.domene.OppdragResultat
import no.nav.familie.ef.iverksett.iverksetting.domene.TilbakekrevingResultat
import no.nav.familie.ef.iverksett.iverksetting.domene.TilkjentYtelse
import no.nav.familie.ef.iverksett.økonomi.simulering.kontroll.SimuleringskontrollInput
import no.nav.familie.ef.iverksett.økonomi.simulering.kontroll.SimuleringskontrollResultat
import no.nav.familie.eksterne.kontrakter.saksstatistikk.ef.BehandlingDVH
import no.nav.familie.kontrakter.felles.ef.StønadType
import no.nav.familie.kontrakter.felles.objectMapper
Expand Down Expand Up @@ -66,6 +68,11 @@ class DatabaseConfiguration : AbstractJdbcConfiguration() {
StringTilBrevmottakereConverter(),
YearTilLocalDateConverter(),
LocalDateTilYearConverter(),

SimuleringskontrollInputTilStringConverter(),
StringTilSimuleringskontrollInputConverter(),
SimuleringskontrollResultatTilStringConverter(),
StringTilSimuleringskontrollResultatConverter(),
),
)
}
Expand All @@ -90,7 +97,11 @@ class DatabaseConfiguration : AbstractJdbcConfiguration() {
val fagsakdetaljer: Fagsakdetaljer = objectMapper.treeToValue(fagsakNode)
return when (fagsakdetaljer.stønadstype) {
StønadType.BARNETILSYN -> objectMapper.readValue(pGobject.value, IverksettBarnetilsyn::class.java)
StønadType.OVERGANGSSTØNAD -> objectMapper.readValue(pGobject.value, IverksettOvergangsstønad::class.java)
StønadType.OVERGANGSSTØNAD -> objectMapper.readValue(
pGobject.value,
IverksettOvergangsstønad::class.java,
)

StønadType.SKOLEPENGER -> objectMapper.readValue(pGobject.value, IverksettSkolepenger::class.java)
}
}
Expand Down Expand Up @@ -202,4 +213,40 @@ class DatabaseConfiguration : AbstractJdbcConfiguration() {
return Year.from(date.toLocalDate())
}
}

@WritingConverter
class SimuleringskontrollInputTilStringConverter : Converter<SimuleringskontrollInput, PGobject> {

override fun convert(data: SimuleringskontrollInput): PGobject =
PGobject().apply {
type = "json"
value = objectMapper.writeValueAsString(data)
}
}

@ReadingConverter
class StringTilSimuleringskontrollInputConverter : Converter<PGobject, SimuleringskontrollInput> {

override fun convert(pgObject: PGobject): SimuleringskontrollInput {
return objectMapper.readValue(pgObject.value!!)
}
}

@WritingConverter
class SimuleringskontrollResultatTilStringConverter : Converter<SimuleringskontrollResultat, PGobject> {

override fun convert(data: SimuleringskontrollResultat): PGobject =
PGobject().apply {
type = "json"
value = objectMapper.writeValueAsString(data)
}
}

@ReadingConverter
class StringTilSimuleringskontrollResultatConverter : Converter<PGobject, SimuleringskontrollResultat> {

override fun convert(pgObject: PGobject): SimuleringskontrollResultat {
return objectMapper.readValue(pgObject.value!!)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@ data class AndelTilkjentYtelse(
)
}

fun erNull() = this.beløp == 0
fun harNullBeløp() = this.beløp == 0

fun erFullOvergangsstønad() = this.inntektsreduksjon == 0 && this.samordningsfradrag == 0

fun utbetalingsgrad(): Int =
fun utbetalingsgrad(): Int = if (this.beløp != 0) {
(100 * (this.beløp.toDouble() / (this.beløp + this.inntektsreduksjon + this.samordningsfradrag))).roundToInt()
} else {
0
}

companion object {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package no.nav.familie.ef.iverksett.iverksetting.domene

import no.nav.familie.felles.utbetalingsgenerator.domain.Utbetalingsoppdrag
import no.nav.familie.kontrakter.ef.felles.TilkjentYtelseStatus
import no.nav.familie.kontrakter.felles.ef.StønadType
import no.nav.familie.kontrakter.felles.oppdrag.Utbetalingsoppdrag
import java.time.LocalDate
import java.time.YearMonth
import java.util.UUID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import no.nav.familie.ef.iverksett.iverksetting.tilstand.IverksettResultatServic
import no.nav.familie.ef.iverksett.repository.findByIdOrThrow
import no.nav.familie.ef.iverksett.økonomi.simulering.SimuleringService
import no.nav.familie.ef.iverksett.økonomi.simulering.harFeilutbetaling
import no.nav.familie.ef.iverksett.økonomi.simulering.kontroll.SimuleringskontrollService
import no.nav.familie.kontrakter.ef.felles.BehandlingType
import no.nav.familie.kontrakter.felles.simulering.BeriketSimuleringsresultat
import no.nav.familie.kontrakter.felles.tilbakekreving.OpprettTilbakekrevingRequest
Expand Down Expand Up @@ -37,6 +38,7 @@ class OpprettTilbakekrevingTask(
private val iverksettResultatService: IverksettResultatService,
private val simuleringService: SimuleringService,
private val familieIntegrasjonerClient: FamilieIntegrasjonerClient,
private val simuleringskontrollService: SimuleringskontrollService,
) : AsyncTaskStep {

private val logger: Logger = LoggerFactory.getLogger(this::class.java)
Expand All @@ -46,13 +48,17 @@ class OpprettTilbakekrevingTask(
val iverksett = iverksettingRepository.findByIdOrThrow(behandlingId).data
if (skalOppretteTilbakekreving(iverksett, behandlingId)) {
val nyBeriketSimuleringsresultat = hentBeriketSimulering(iverksett)
simuleringskontrollService.kontrollerMedNyUtbetalingsgenerator(iverksett) { nyBeriketSimuleringsresultat }

val nyIverksett = iverksett.oppfriskTilbakekreving(nyBeriketSimuleringsresultat)
loggForskjell(nyIverksett, iverksett, behandlingId)
if (nyBeriketSimuleringsresultat.harFeilutbetaling()) {
opprettTilbakekreving(behandlingId, nyIverksett)
} else {
logger.info("Behandling=$behandlingId har ikke (lenger) positiv feilutbetaling i simuleringen")
}
} else {
simuleringskontrollService.kontrollerMedNyUtbetalingsgenerator(iverksett) { hentBeriketSimulering(iverksett) }
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package no.nav.familie.ef.iverksett.økonomi

import no.nav.familie.ef.iverksett.featuretoggle.FeatureToggleService
import no.nav.familie.ef.iverksett.infrastruktur.task.opprettNesteTask
import no.nav.familie.ef.iverksett.iverksetting.IverksettingRepository
import no.nav.familie.ef.iverksett.iverksetting.tilstand.IverksettResultatService
import no.nav.familie.ef.iverksett.repository.findByIdOrThrow
import no.nav.familie.ef.iverksett.økonomi.utbetalingsoppdrag.UtbetalingsoppdragGenerator.lagTilkjentYtelseMedUtbetalingsoppdrag
import no.nav.familie.ef.iverksett.økonomi.utbetalingsoppdrag.UtbetalingsoppdragGenerator.lagTilkjentYtelseMedUtbetalingsoppdragNy
import no.nav.familie.prosessering.AsyncTaskStep
import no.nav.familie.prosessering.TaskStepBeskrivelse
import no.nav.familie.prosessering.domene.Task
Expand All @@ -24,6 +26,7 @@ class IverksettMotOppdragTask(
private val oppdragClient: OppdragClient,
private val taskService: TaskService,
private val iverksettResultatService: IverksettResultatService,
private val featureToggleService: FeatureToggleService,
) : AsyncTaskStep {

private val log: Logger = LoggerFactory.getLogger(this::class.java)
Expand All @@ -32,7 +35,8 @@ class IverksettMotOppdragTask(
val behandlingId = UUID.fromString(task.payload)
val iverksett = iverksettingRepository.findByIdOrThrow(behandlingId).data
val forrigeTilkjentYtelse = iverksett.behandling.forrigeBehandlingId?.let {
iverksettResultatService.hentTilkjentYtelse(it) ?: error("Kunne ikke finne tilkjent ytelse for behandlingId=$it")
iverksettResultatService.hentTilkjentYtelse(it)
?: error("Kunne ikke finne tilkjent ytelse for behandlingId=$it")
}
val nyTilkjentYtelseMedMetaData =
iverksett.vedtak.tilkjentYtelse?.toMedMetadata(
Expand All @@ -45,11 +49,23 @@ class IverksettMotOppdragTask(
vedtaksdato = iverksett.vedtak.vedtakstidspunkt.toLocalDate(),
) ?: error("Mangler tilkjent ytelse på vedtaket")

val utbetaling = lagTilkjentYtelseMedUtbetalingsoppdrag(
nyTilkjentYtelseMedMetaData,
forrigeTilkjentYtelse,
iverksett.erGOmregning(),
)
val brukNyUtbetalingsgenerator = featureToggleService.isEnabledMedFagsakId("familie.ef.iverksett.ny-utbetalingsgenerator", nyTilkjentYtelseMedMetaData.eksternFagsakId)

val utbetaling = if (brukNyUtbetalingsgenerator) {
log.info("Bruker ny utbetalingsgenerator for behandling=${iverksett.behandling.behandlingId}")
lagTilkjentYtelseMedUtbetalingsoppdragNy(
nyTilkjentYtelseMedMetaData,
forrigeTilkjentYtelse,
iverksett.erGOmregning(),
)
} else {
log.info("Bruker gammel utbetalingsgenerator for behandling=${iverksett.behandling.behandlingId}")
lagTilkjentYtelseMedUtbetalingsoppdrag(
nyTilkjentYtelseMedMetaData,
forrigeTilkjentYtelse,
iverksett.erGOmregning(),
)
}

iverksettResultatService.oppdaterTilkjentYtelseForUtbetaling(behandlingId = behandlingId, utbetaling)
utbetaling.utbetalingsoppdrag?.let {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package no.nav.familie.ef.iverksett.økonomi

import no.nav.familie.ef.iverksett.økonomi.utbetalingsoppdrag.UtbetalingsgeneratorHelper.KonsistensavstemmingUtbetalingsoppdrag
import no.nav.familie.felles.utbetalingsgenerator.domain.Utbetalingsoppdrag
import no.nav.familie.http.client.AbstractPingableRestClient
import no.nav.familie.kontrakter.felles.Ressurs
import no.nav.familie.kontrakter.felles.getDataOrThrow
import no.nav.familie.kontrakter.felles.oppdrag.GrensesnittavstemmingRequest
import no.nav.familie.kontrakter.felles.oppdrag.KonsistensavstemmingUtbetalingsoppdrag
import no.nav.familie.kontrakter.felles.oppdrag.OppdragId
import no.nav.familie.kontrakter.felles.oppdrag.OppdragStatus
import no.nav.familie.kontrakter.felles.oppdrag.Utbetalingsoppdrag
import no.nav.familie.kontrakter.felles.simulering.DetaljertSimuleringResultat
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.beans.factory.annotation.Value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class KonsistensavstemmingController(
private val konsistensavstemmingService: KonsistensavstemmingService,
) {

// TODO må verifisere at man ikke lagrer ned kildeBehandlingId i iverksett
// Og må verifisere at man ikke bruker kildeBehandlingId på andelsnivå fra KonsistensavstemmingDto
@PostMapping
fun startKonsistensavstemming(
@RequestBody konsistensavstemmingDto: KonsistensavstemmingDto,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import no.nav.familie.ef.iverksett.iverksetting.domene.TilkjentYtelse
import no.nav.familie.ef.iverksett.iverksetting.tilstand.IverksettResultatService
import no.nav.familie.ef.iverksett.util.tilKlassifisering
import no.nav.familie.ef.iverksett.økonomi.OppdragClient
import no.nav.familie.ef.iverksett.økonomi.utbetalingsoppdrag.UtbetalingsgeneratorHelper
import no.nav.familie.ef.iverksett.økonomi.utbetalingsoppdrag.lagPeriodeFraAndel
import no.nav.familie.felles.utbetalingsgenerator.domain.Utbetalingsoppdrag
import no.nav.familie.kontrakter.ef.iverksett.KonsistensavstemmingDto
import no.nav.familie.kontrakter.ef.iverksett.KonsistensavstemmingTilkjentYtelseDto
import no.nav.familie.kontrakter.felles.ef.StønadType
import no.nav.familie.kontrakter.felles.oppdrag.KonsistensavstemmingUtbetalingsoppdrag
import no.nav.familie.kontrakter.felles.oppdrag.Utbetalingsoppdrag
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import java.time.LocalDate
Expand All @@ -34,10 +34,10 @@ class KonsistensavstemmingService(
) {
try {
val utbetalingsoppdrag = lagUtbetalingsoppdragForKonsistensavstemming(konsistensavstemmingDto)
val konsistensavstemmingUtbetalingsoppdrag = KonsistensavstemmingUtbetalingsoppdrag(
konsistensavstemmingDto.stønadType.tilKlassifisering(),
utbetalingsoppdrag,
konsistensavstemmingDto.avstemmingstidspunkt ?: LocalDateTime.now(),
val konsistensavstemmingUtbetalingsoppdrag = UtbetalingsgeneratorHelper.KonsistensavstemmingUtbetalingsoppdrag(
fagsystem = konsistensavstemmingDto.stønadType.tilKlassifisering(),
utbetalingsoppdrag = utbetalingsoppdrag,
avstemmingstidspunkt = konsistensavstemmingDto.avstemmingstidspunkt ?: LocalDateTime.now(),
)
oppdragKlient.konsistensavstemming(
konsistensavstemmingUtbetalingsoppdrag,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import no.nav.familie.ef.iverksett.iverksetting.domene.Simulering
import no.nav.familie.ef.iverksett.iverksetting.tilstand.IverksettResultatService
import no.nav.familie.ef.iverksett.økonomi.OppdragClient
import no.nav.familie.ef.iverksett.økonomi.utbetalingsoppdrag.UtbetalingsoppdragGenerator
import no.nav.familie.felles.utbetalingsgenerator.domain.Utbetalingsoppdrag
import no.nav.familie.http.client.RessursException
import no.nav.familie.kontrakter.felles.ef.StønadType
import no.nav.familie.kontrakter.felles.oppdrag.Utbetalingsoppdrag
import no.nav.familie.kontrakter.felles.simulering.BeriketSimuleringsresultat
import no.nav.familie.kontrakter.felles.simulering.DetaljertSimuleringResultat
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service
import org.springframework.web.client.HttpClientErrorException
Expand All @@ -22,8 +24,12 @@ class SimuleringService(
private val iverksettResultatService: IverksettResultatService,
private val featureToggleService: FeatureToggleService,
) {
private val log: Logger = LoggerFactory.getLogger(this::class.java)

private fun hentDetaljertSimuleringResultat(simulering: Simulering): DetaljertSimuleringResultat {
private fun hentDetaljertSimuleringResultat(
simulering: Simulering,
brukNyUtbetalingsgenerator: Boolean,
): DetaljertSimuleringResultat {
if (featureToggleService.isEnabled("familie.ef.iverksett.stopp-iverksetting")) {
error("Kan ikke sende inn simmulere")
}
Expand All @@ -32,11 +38,25 @@ class SimuleringService(
iverksettResultatService.hentTilkjentYtelse(simulering.forrigeBehandlingId)
}

val tilkjentYtelseMedUtbetalingsoppdrag =
val brukNyUtbetalingsgeneratorFeature =
featureToggleService.isEnabledMedFagsakId(
"familie.ef.iverksett.ny-utbetalingsgenerator",
simulering.nyTilkjentYtelseMedMetaData.eksternFagsakId,
)

val tilkjentYtelseMedUtbetalingsoppdrag = if (brukNyUtbetalingsgenerator || brukNyUtbetalingsgeneratorFeature) {
log.info("Simulerer med ny utbetalingsgenerator for behandling=${simulering.nyTilkjentYtelseMedMetaData.behandlingId}")
UtbetalingsoppdragGenerator.lagTilkjentYtelseMedUtbetalingsoppdragNy(
simulering.nyTilkjentYtelseMedMetaData,
forrigeTilkjentYtelse,
)
} else {
log.info("Simulerer med gammel utbetalingsgenerator for behandling=${simulering.nyTilkjentYtelseMedMetaData.behandlingId}")
UtbetalingsoppdragGenerator.lagTilkjentYtelseMedUtbetalingsoppdrag(
simulering.nyTilkjentYtelseMedMetaData,
forrigeTilkjentYtelse,
)
}

val utbetalingsoppdrag = tilkjentYtelseMedUtbetalingsoppdrag.utbetalingsoppdrag
?: error("Utbetalingsoppdraget finnes ikke for tilkjent ytelse")
Expand All @@ -57,11 +77,14 @@ class SimuleringService(
}
}

fun hentBeriketSimulering(simulering: Simulering): BeriketSimuleringsresultat {
fun hentBeriketSimulering(
simulering: Simulering,
brukNyUtbetalingsgenerator: Boolean = false,
): BeriketSimuleringsresultat {
if (featureToggleService.isEnabled("familie.ef.iverksett.stopp-iverksetting")) {
error("Kan ikke sende inn simmulere")
}
val detaljertSimuleringResultat = hentDetaljertSimuleringResultat(simulering)
val detaljertSimuleringResultat = hentDetaljertSimuleringResultat(simulering, brukNyUtbetalingsgenerator)
val simuleringsresultatDto = lagSimuleringsoppsummering(detaljertSimuleringResultat, LocalDate.now())

return BeriketSimuleringsresultat(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package no.nav.familie.ef.iverksett.økonomi.simulering.kontroll

import no.nav.familie.ef.iverksett.iverksetting.domene.Simulering
import no.nav.familie.ef.iverksett.repository.InsertUpdateRepository
import no.nav.familie.ef.iverksett.repository.RepositoryInterface
import no.nav.familie.kontrakter.felles.simulering.BeriketSimuleringsresultat
import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Column
import org.springframework.stereotype.Repository
import java.util.UUID

@Repository
interface SimuleringskontrollRepository :
RepositoryInterface<Simuleringskontroll, UUID>,
InsertUpdateRepository<Simuleringskontroll>

data class Simuleringskontroll(
@Id
val behandlingId: UUID,
@Column("input")
val input: SimuleringskontrollInput,
@Column("resultat")
val resultat: SimuleringskontrollResultat,
)

data class SimuleringskontrollInput(
val simulering: Simulering,
val resultat: BeriketSimuleringsresultat,
)

data class SimuleringskontrollResultat(
val resultat: BeriketSimuleringsresultat,
)
Loading

0 comments on commit 4792bdd

Please sign in to comment.