From cd9b892e9899076130ed3e5fe4d066ccb7ccbb04 Mon Sep 17 00:00:00 2001 From: John Andre Hestad Date: Mon, 23 Oct 2023 19:45:15 +0200 Subject: [PATCH] Legg til bedre logging ved mapping-feil for simulering --- .../simulering/SimuleringResponseMapper.kt | 146 ++++++++----- .../simulering/SimuleringSoapClient.kt | 29 +-- .../SimuleringResponseMapperTest.kt | 192 +++++++++++------- .../kotlin/simulering/SimuleringTestData.kt | 61 +++++- 4 files changed, 277 insertions(+), 151 deletions(-) diff --git a/client/src/main/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringResponseMapper.kt b/client/src/main/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringResponseMapper.kt index 08d75b101e..72fa8cc911 100644 --- a/client/src/main/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringResponseMapper.kt +++ b/client/src/main/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringResponseMapper.kt @@ -1,17 +1,23 @@ package no.nav.su.se.bakover.client.oppdrag.simulering +import arrow.core.Either +import arrow.core.getOrElse import no.nav.su.se.bakover.common.domain.Saksnummer +import no.nav.su.se.bakover.common.infrastructure.xml.xmlMapper import no.nav.su.se.bakover.common.person.Fnr import no.nav.su.se.bakover.common.sikkerLogg import no.nav.su.se.bakover.common.tid.periode.Måned import no.nav.su.se.bakover.common.tid.periode.Periode import no.nav.su.se.bakover.domain.oppdrag.Fagområde import no.nav.su.se.bakover.domain.oppdrag.Utbetaling +import no.nav.su.se.bakover.domain.oppdrag.simulering.SimulerUtbetalingRequest +import no.nav.su.se.bakover.domain.oppdrag.simulering.SimuleringFeilet import no.nav.system.os.entiteter.beregningskjema.BeregningStoppnivaa import no.nav.system.os.entiteter.beregningskjema.BeregningStoppnivaaDetaljer import no.nav.system.os.entiteter.beregningskjema.BeregningsPeriode -import no.nav.system.os.tjenester.simulerfpservice.simulerfpserviceservicetypes.SimulerBeregningRequest +import no.nav.system.os.tjenester.simulerfpservice.simulerfpservicegrensesnitt.SimulerBeregningRequest import no.nav.system.os.tjenester.simulerfpservice.simulerfpserviceservicetypes.SimulerBeregningResponse +import org.slf4j.Logger import org.slf4j.LoggerFactory import økonomi.domain.KlasseKode import økonomi.domain.KlasseType @@ -22,57 +28,92 @@ import økonomi.domain.simulering.SimulertUtbetaling import java.time.Clock import java.time.LocalDate -private val log = LoggerFactory.getLogger("SimuleringResponseMapper") +private val defaultLog = LoggerFactory.getLogger("SimuleringResponseMapper") /** * https://confluence.adeo.no/display/OKSY/Returdata+fra+Oppdragssystemet+til+fagrutinen + * + * @param log For testing. + * @param sikkerLogg For testing. */ -internal class SimuleringResponseMapper private constructor( - val simulering: Simulering, - val clock: Clock, -) { - - constructor( - rawResponse: String, - oppdragResponse: SimulerBeregningResponse, - clock: Clock, - saksnummer: Saksnummer, - ) : this(oppdragResponse.toSimulering(saksnummer, rawResponse), clock) - - constructor( - utbetaling: Utbetaling, - simuleringsperiode: SimulerBeregningRequest.SimuleringsPeriode, - clock: Clock, - ) : this( - utbetaling.mapTomResponsFraOppdrag( - simuleringsperiode = simuleringsperiode.toPeriode(), - clock = clock, - ), - clock, - ) -} - -private fun SimulerBeregningRequest.SimuleringsPeriode.toPeriode(): Periode { - return Periode.create(LocalDate.parse(datoSimulerFom), LocalDate.parse(datoSimulerTom)) +fun SimulerBeregningResponse?.toSimulering( + request: SimulerUtbetalingRequest, + clock: Clock, + soapRequest: SimulerBeregningRequest, + log: Logger = defaultLog, + sikkerLogg: Logger = no.nav.su.se.bakover.common.sikkerLogg, +): Either { + val saksnummer = request.utbetaling.saksnummer + // TODO jah: Ideelt sett burde vi fått tak i den rå XMLen, men CXF gjør det ikke så lett for oss (OutInterceptor). + // Siden dette er javaklasser uten toString() så serialiserer vi de før vi lagrer/logger. + val rawResponse: String? = this?.let { + serializeSoapMessage(log = log, sikkerLogg = sikkerLogg, message = this, request = request) + } + val rawRequest: String = serializeSoapMessage(log = log, sikkerLogg = sikkerLogg, message = soapRequest, request = request) + return Either.catch { + if (this == null) { + request.utbetaling.mapTomResponsFraOppdrag( + simuleringsperiode = request.simuleringsperiode, + clock = clock, + ) + } else { + Simulering( + gjelderId = Fnr(simulering.gjelderId), + gjelderNavn = simulering.gjelderNavn.trim(), + datoBeregnet = LocalDate.parse(simulering.datoBeregnet), + nettoBeløp = simulering.belop.toInt(), + måneder = simulering.beregningsPeriode.map { + it.toSimulertPeriode( + saksnummer = saksnummer, + request = request, + rawRequest = rawRequest, + rawResponse = rawResponse!!, + log = log, + ) + }, + rawResponse = rawResponse!!, + ) + } + }.mapLeft { throwable -> + log.error("Kunne ikke mappe SimulerBeregningResponse til Simulering for saksnummer $saksnummer. Se sikkerlogg for stacktrace og context.") + sikkerLogg.error( + "Kunne ikke mappe SimulerBeregningResponse til Simulering for saksnummer $saksnummer. Response: $rawResponse, SoapRequest: $rawRequest, Request: $request", + throwable, + ) + SimuleringFeilet.TekniskFeil + } } -private fun SimulerBeregningResponse.toSimulering( - saksnummer: Saksnummer, - rawResponse: String, -): Simulering { - return Simulering( - gjelderId = Fnr(simulering.gjelderId), - gjelderNavn = simulering.gjelderNavn.trim(), - datoBeregnet = LocalDate.parse(simulering.datoBeregnet), - nettoBeløp = simulering.belop.toInt(), - måneder = simulering.beregningsPeriode.map { it.toSimulertPeriode(saksnummer, rawResponse) }, - rawResponse = rawResponse, - ) +private fun serializeSoapMessage( + log: Logger, + sikkerLogg: Logger, + message: Any, + request: SimulerUtbetalingRequest, +): String { + return Either.catch { + xmlMapper.writeValueAsString(message) + }.getOrElse { throwable -> + "Kunne ikke serialisere ${message.javaClass.simpleName} til XML, se sikkerlogg for stacktrace og context. Lagrer denne strengen istedenfor.".also { errorMessage -> + log.error(errorMessage) + sikkerLogg.error( + "Kunne ikke serialisere ${message.javaClass.simpleName} til XML. Request: $request", + throwable, + ) + } + } } +/** + * @param rawResponse Brukes kun for logging. + * @param request Brukes kun for logging. + * @param rawRequest Brukes kun for logging. + */ private fun BeregningsPeriode.toSimulertPeriode( saksnummer: Saksnummer, rawResponse: String, + request: SimulerUtbetalingRequest, + rawRequest: String, + log: Logger, ): SimulertMåned { return SimulertMåned( måned = Måned.fra(LocalDate.parse(periodeFom), LocalDate.parse(periodeTom)), @@ -87,10 +128,12 @@ private fun BeregningsPeriode.toSimulertPeriode( fagsystemId, ) sikkerLogg.debug( - "Simuleringen filtrerte vekk uønsket fagsystemid for saksnummer {}. fagsystemId={}. rawResponse: {}", + "Simuleringen filtrerte vekk uønsket fagsystemid for saksnummer {}. fagsystemId={}. soapResponse: {}, soapRequest: {}, request: {}", saksnummer, fagsystemId, rawResponse, + rawRequest, + request, ) } } @@ -104,30 +147,32 @@ private fun BeregningsPeriode.toSimulertPeriode( kodeFagomraade, ) sikkerLogg.debug( - "Simuleringen filtrerte vekk uønsket kodeFagomraade for saksnummer {}. kodeFagomraade={}. rawResponse: {}", + "Simuleringen filtrerte vekk uønsket kodeFagomraade for saksnummer {}. kodeFagomraade={}. soapResponse: {}, soapRequest: {}, request: {}", saksnummer, kodeFagomraade, rawResponse, + rawRequest, + request, ) } } }.map { - it.toSimulertUtbetaling() + it.toSimulertUtbetaling(log = log) }.let { when { it.isEmpty() -> null - it.size > 1 -> throw IllegalStateException("Simulering inneholder flere utbetalinger for samme sak $saksnummer. Se sikkerlogg for flere detaljer og feilmelding.").also { - sikkerLogg.error("Simulering inneholder flere utbetalinger for samme sak $saksnummer. rawResponse: $rawResponse") - } - + // Vi fanger og logger exceptions ytterst. + it.size > 1 -> throw IllegalStateException("Simulering inneholder flere utbetalinger for samme sak $saksnummer.") else -> it.first() } }, ) } -private fun BeregningStoppnivaa.toSimulertUtbetaling() = - SimulertUtbetaling( +private fun BeregningStoppnivaa.toSimulertUtbetaling( + log: Logger, +): SimulertUtbetaling { + return SimulertUtbetaling( fagSystemId = fagsystemId.trim(), utbetalesTilNavn = utbetalesTilNavn.trim(), utbetalesTilId = Fnr(utbetalesTilId), @@ -152,6 +197,7 @@ private fun BeregningStoppnivaa.toSimulertUtbetaling() = } .map { it.toSimulertDetalj() }, ) +} private fun BeregningStoppnivaaDetaljer.toSimulertDetalj() = SimulertDetaljer( diff --git a/client/src/main/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringSoapClient.kt b/client/src/main/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringSoapClient.kt index 12321c2d0e..9069be1098 100644 --- a/client/src/main/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringSoapClient.kt +++ b/client/src/main/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringSoapClient.kt @@ -1,11 +1,8 @@ package no.nav.su.se.bakover.client.oppdrag.simulering import arrow.core.Either -import arrow.core.getOrElse import arrow.core.left -import arrow.core.right import com.ctc.wstx.exc.WstxEOFException -import no.nav.su.se.bakover.common.infrastructure.xml.xmlMapper import no.nav.su.se.bakover.common.serialize import no.nav.su.se.bakover.common.sikkerLogg import no.nav.su.se.bakover.domain.oppdrag.simulering.SimulerUtbetalingRequest @@ -14,6 +11,7 @@ import no.nav.su.se.bakover.domain.oppdrag.simulering.SimuleringFeilet import no.nav.system.os.eksponering.simulerfpservicewsbinding.SimulerBeregningFeilUnderBehandling import no.nav.system.os.eksponering.simulerfpservicewsbinding.SimulerFpService import no.nav.system.os.tjenester.simulerfpservice.simulerfpservicegrensesnitt.SimulerBeregningRequest +import no.nav.system.os.tjenester.simulerfpservice.simulerfpserviceservicetypes.SimulerBeregningResponse import org.slf4j.LoggerFactory import økonomi.domain.simulering.Simulering import java.net.SocketException @@ -34,26 +32,13 @@ internal class SimuleringSoapClient( ): Either { val simulerRequest = SimuleringRequestBuilder(request).build() return try { - simulerFpService.simulerBeregning(simulerRequest)?.response?.let { - // TODO jah: Ideelt sett burde vi fått tak i den rå XMLen, men CXF gjør det ikke så lett for oss (OutInterceptor). - val rawResponse: String = Either.catch { - xmlMapper.writeValueAsString(it) - }.getOrElse { - log.error("Kunne ikke simulere SimulerBeregningResponse til xml, se sikkerlogg for stacktrace.") - sikkerLogg.error("Kunne ikke simulere SimulerBeregningResponse til xml.", it) - "Kunne ikke simulere SimulerBeregningResponse til xml, se sikkerlogg for stacktrace." - } - SimuleringResponseMapper( - rawResponse = rawResponse, - oppdragResponse = it, + simulerFpService.simulerBeregning(simulerRequest)?.response.let { response: SimulerBeregningResponse? -> + response.toSimulering( + request = request, + soapRequest = simulerRequest, clock = clock, - saksnummer = request.utbetaling.saksnummer, - ).simulering.right() - } ?: SimuleringResponseMapper( - utbetaling = request.utbetaling, - simuleringsperiode = simulerRequest.request.simuleringsPeriode, - clock = clock, - ).simulering.right() + ) + } } catch (e: SimulerBeregningFeilUnderBehandling) { log.warn("Funksjonell feil ved simulering, se sikkerlogg for detaljer", e) sikkerLogg.warn( diff --git a/client/src/test/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringResponseMapperTest.kt b/client/src/test/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringResponseMapperTest.kt index 0ce84fb977..c1c0eb8ef5 100644 --- a/client/src/test/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringResponseMapperTest.kt +++ b/client/src/test/kotlin/no/nav/su/se/bakover/client/oppdrag/simulering/SimuleringResponseMapperTest.kt @@ -1,8 +1,10 @@ package no.nav.su.se.bakover.client.oppdrag.simulering +import arrow.core.left import com.fasterxml.jackson.module.kotlin.readValue -import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.equality.shouldBeEqualToIgnoringFields import io.kotest.matchers.shouldBe +import io.kotest.matchers.string.shouldContain import no.nav.su.se.bakover.common.Beløp import no.nav.su.se.bakover.common.MånedBeløp import no.nav.su.se.bakover.common.Månedsbeløp @@ -18,10 +20,17 @@ import no.nav.su.se.bakover.common.tid.periode.februar import no.nav.su.se.bakover.common.tid.periode.januar import no.nav.su.se.bakover.common.tid.periode.mai import no.nav.su.se.bakover.common.tid.periode.mars +import no.nav.su.se.bakover.domain.oppdrag.simulering.SimuleringFeilet +import no.nav.su.se.bakover.test.argThat import no.nav.su.se.bakover.test.fixedClock +import no.nav.su.se.bakover.test.getOrFail import no.nav.su.se.bakover.test.simulering.SimuleringResponseData.Companion.simuleringXml +import no.nav.su.se.bakover.test.simulering.simuleringUtbetalingRequest import no.nav.system.os.tjenester.simulerfpservice.simulerfpserviceservicetypes.SimulerBeregningResponse import org.junit.jupiter.api.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.slf4j.Logger import økonomi.domain.KlasseKode import økonomi.domain.KlasseType import økonomi.domain.simulering.Kontobeløp @@ -66,12 +75,13 @@ internal class SimuleringResponseMapperTest { GrensesnittResponse::class.java, ).response - SimuleringResponseMapper( - rawResponse = rawResponse, - oppdragResponse = responseMedFremtidigUtbetaling, + val request = simuleringUtbetalingRequest() + val actualSimulering = responseMedFremtidigUtbetaling.toSimulering( + request = request, clock = fixedClock, - saksnummer = saksnummer, - ).simulering shouldBe Simulering( + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail() + val expectedSimulering = Simulering( gjelderId = fnr, gjelderNavn = navn, datoBeregnet = 14.april(2021), @@ -105,7 +115,9 @@ internal class SimuleringResponseMapperTest { ), ), rawResponse = rawResponse, - ).also { + ) + actualSimulering.shouldBeEqualToIgnoringFields(expectedSimulering, Simulering::rawResponse) + actualSimulering.also { it.erAlleMånederUtenUtbetaling() shouldBe false it.hentTilUtbetaling() shouldBe Månedsbeløp( listOf( @@ -160,12 +172,13 @@ internal class SimuleringResponseMapperTest { simuleringXml, GrensesnittResponse::class.java, ).response - SimuleringResponseMapper( - simuleringXml, - responseMedFremtidigUtbetaling, - fixedClock, - saksnummer, - ).simulering shouldBe Simulering( + val request = simuleringUtbetalingRequest() + val actualSimulering = responseMedFremtidigUtbetaling.toSimulering( + request = request, + clock = fixedClock, + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail() + val expectedSimulering = Simulering( gjelderId = fnr, gjelderNavn = navn, datoBeregnet = 14.april(2021), @@ -200,7 +213,9 @@ internal class SimuleringResponseMapperTest { ), ), rawResponse = simuleringXml, - ).also { + ) + actualSimulering.shouldBeEqualToIgnoringFields(expectedSimulering, Simulering::rawResponse) + actualSimulering.also { it.kontooppstilling() shouldBe mapOf( april(2021) to Kontooppstilling( debetYtelse = Kontobeløp.Debet(20779), @@ -251,12 +266,8 @@ internal class SimuleringResponseMapperTest { GrensesnittResponse::class.java, ).response - SimuleringResponseMapper( - simuleringXml, - responseMedFeilutbetaling, - fixedClock, - saksnummer, - ).simulering shouldBe Simulering( + val request = simuleringUtbetalingRequest() + val expectedSimulering = Simulering( gjelderId = fnr, gjelderNavn = navn, datoBeregnet = 14.april(2021), @@ -373,7 +384,15 @@ internal class SimuleringResponseMapperTest { ), ), rawResponse = simuleringXml, - ).also { + ) + val actualSimulering = responseMedFeilutbetaling.toSimulering( + request = request, + clock = fixedClock, + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail() + actualSimulering.shouldBeEqualToIgnoringFields(expectedSimulering, Simulering::rawResponse) + + actualSimulering.also { it.erAlleMånederUtenUtbetaling() shouldBe false it.hentTilUtbetaling() shouldBe Månedsbeløp( listOf( @@ -495,12 +514,13 @@ internal class SimuleringResponseMapperTest { GrensesnittResponse::class.java, ).response - SimuleringResponseMapper( - simuleringXml, - responseMedEtterbetaling, - fixedClock, - saksnummer, - ).simulering shouldBe Simulering( + val request = simuleringUtbetalingRequest() + val actualSimulering = responseMedEtterbetaling.toSimulering( + request = request, + clock = fixedClock, + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail() + val expectedSimulering = Simulering( gjelderId = fnr, gjelderNavn = navn, datoBeregnet = 14.april(2021), @@ -575,7 +595,9 @@ internal class SimuleringResponseMapperTest { ), ), rawResponse = simuleringXml, - ).also { + ) + actualSimulering.shouldBeEqualToIgnoringFields(expectedSimulering, Simulering::rawResponse) + actualSimulering.also { it.erAlleMånederUtenUtbetaling() shouldBe false it.hentTilUtbetaling() shouldBe Månedsbeløp( listOf( @@ -691,12 +713,8 @@ internal class SimuleringResponseMapperTest { GrensesnittResponse::class.java, ).response - SimuleringResponseMapper( - simuleringXml, - responseMedFremtidigUtbetaling, - fixedClock, - saksnummer, - ).simulering shouldBe Simulering( + val request = simuleringUtbetalingRequest() + val expectedSimulering = Simulering( gjelderId = fnr, gjelderNavn = navn, datoBeregnet = 14.april(2021), @@ -731,7 +749,14 @@ internal class SimuleringResponseMapperTest { ), ), rawResponse = simuleringXml, - ).also { + ) + val actualSimulering = responseMedFremtidigUtbetaling.toSimulering( + request = request, + clock = fixedClock, + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail() + actualSimulering.shouldBeEqualToIgnoringFields(expectedSimulering, Simulering::rawResponse) + actualSimulering.also { it.kontooppstilling() shouldBe mapOf( april(2021).tilPeriode() to Kontooppstilling( debetYtelse = Kontobeløp.Debet(20779), @@ -762,14 +787,29 @@ internal class SimuleringResponseMapperTest { GrensesnittResponse::class.java, ).response - shouldThrow { - SimuleringResponseMapper( - simuleringXml, - responseMedFremtidigUtbetaling, - fixedClock, - saksnummer, - ) - }.message.shouldBe("Simulering inneholder flere utbetalinger for samme sak $saksnummer. Se sikkerlogg for flere detaljer og feilmelding.") + val request = simuleringUtbetalingRequest() + val logMock = mock() + val sikkerLoggMock = mock() + val soapRequest = SimuleringRequestBuilder(request).build() + responseMedFremtidigUtbetaling.toSimulering( + request = request, + clock = fixedClock, + soapRequest = soapRequest, + log = logMock, + sikkerLogg = sikkerLoggMock, + ) shouldBe SimuleringFeilet.TekniskFeil.left() + verify(logMock).error( + // Simulering inneholder flere utbetalinger for samme sak $saksnummer. Se sikkerlogg for flere detaljer og feilmelding. + argThat { it shouldBe "Kunne ikke mappe SimulerBeregningResponse til Simulering for saksnummer $saksnummer. Se sikkerlogg for stacktrace og context." }, + ) + verify(sikkerLoggMock).error( + argThat { + it shouldContain "Kunne ikke mappe SimulerBeregningResponse til Simulering for saksnummer $saksnummer." + }, + argThat { + it shouldBe IllegalStateException("Simulering inneholder flere utbetalinger for samme sak $saksnummer.") + }, + ) } @Test @@ -788,12 +828,12 @@ internal class SimuleringResponseMapperTest { GrensesnittResponse::class.java, ).response - SimuleringResponseMapper( - simuleringXml, - responseMedFremtidigUtbetaling, - fixedClock, - saksnummer, - ).simulering.måneder.map { it.utbetaling!!.fagSystemId } shouldBe listOf(fagsystemId) + val request = simuleringUtbetalingRequest() + responseMedFremtidigUtbetaling.toSimulering( + request = request, + clock = fixedClock, + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail().måneder.map { it.utbetaling!!.fagSystemId } shouldBe listOf(fagsystemId) } @Test @@ -812,13 +852,12 @@ internal class SimuleringResponseMapperTest { GrensesnittResponse::class.java, ).response - SimuleringResponseMapper( - simuleringXml, - responseMedFremtidigUtbetaling, - fixedClock, - // Vi tar ikke vare på kodeFagomraade (da domenet vårt ikke forholder seg til andre fagområder) - saksnummer, - ).simulering.måneder.map { it.utbetaling!! }.size.shouldBe(1) + val request = simuleringUtbetalingRequest() + responseMedFremtidigUtbetaling.toSimulering( + request = request, + clock = fixedClock, + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail().måneder.map { it.utbetaling!! }.size.shouldBe(1) } @Test @@ -829,12 +868,12 @@ internal class SimuleringResponseMapperTest { rawResponse, ) - SimuleringResponseMapper( - rawResponse = rawResponse, - oppdragResponse = responseMedÅpenFeilkonto, + val request = simuleringUtbetalingRequest() + responseMedÅpenFeilkonto.toSimulering( + request = request, clock = fixedClock, - saksnummer = saksnummer, - ).simulering.also { + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail().also { it.erAlleMånederUtenUtbetaling() shouldBe false it.hentTilUtbetaling() shouldBe Månedsbeløp(emptyList()) it.hentTotalUtbetaling() shouldBe Månedsbeløp( @@ -1042,12 +1081,12 @@ internal class SimuleringResponseMapperTest { rawResponse, ) - SimuleringResponseMapper( - rawResponse = rawResponse, - oppdragResponse = responseMedÅpenFeilkonto, + val request = simuleringUtbetalingRequest() + responseMedÅpenFeilkonto.toSimulering( + request = request, clock = fixedClock, - saksnummer = saksnummer, - ).simulering.also { + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail().also { it.erAlleMånederUtenUtbetaling() shouldBe false it.hentTilUtbetaling() shouldBe Månedsbeløp( listOf( @@ -1280,12 +1319,12 @@ internal class SimuleringResponseMapperTest { rawResponse, ) - SimuleringResponseMapper( - rawResponse = rawResponse, - oppdragResponse = responseMedÅpenFeilkonto, + val request = simuleringUtbetalingRequest() + responseMedÅpenFeilkonto.toSimulering( + request = request, clock = fixedClock, - saksnummer = saksnummer, - ).simulering.also { + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail().also { it.erAlleMånederUtenUtbetaling() shouldBe false it.hentTilUtbetaling() shouldBe Månedsbeløp(emptyList()) it.hentTotalUtbetaling() shouldBe Månedsbeløp( @@ -1504,9 +1543,16 @@ internal class SimuleringResponseMapperTest { response.simulering.belop shouldBe BigDecimal("2480.00") - val simulering = SimuleringResponseMapper(rawXml, response, fixedClock, Saksnummer(2021)).simulering + val request = simuleringUtbetalingRequest( + saksnummer = Saksnummer.parse("2021"), + ) + val actualSimulering = response.toSimulering( + request = request, + clock = fixedClock, + soapRequest = SimuleringRequestBuilder(request).build(), + ).getOrFail() - simulering.hentTotalUtbetaling() shouldBe Månedsbeløp(listOf(MånedBeløp(mai(2023), Beløp(2480)))) + actualSimulering.hentTotalUtbetaling() shouldBe Månedsbeløp(listOf(MånedBeløp(mai(2023), Beløp(2480)))) } private val jsonMedReduksjonAvFeilkonto = """ diff --git a/test-common/src/main/kotlin/simulering/SimuleringTestData.kt b/test-common/src/main/kotlin/simulering/SimuleringTestData.kt index f1d1982e0e..b84d1c7f80 100644 --- a/test-common/src/main/kotlin/simulering/SimuleringTestData.kt +++ b/test-common/src/main/kotlin/simulering/SimuleringTestData.kt @@ -27,6 +27,7 @@ import no.nav.su.se.bakover.domain.oppdrag.Utbetalingslinje import no.nav.su.se.bakover.domain.oppdrag.Utbetalingsstrategi import no.nav.su.se.bakover.domain.oppdrag.avstemming.Avstemmingsnøkkel import no.nav.su.se.bakover.domain.oppdrag.simulering.SimulerUtbetalingForPeriode +import no.nav.su.se.bakover.domain.oppdrag.simulering.SimulerUtbetalingRequest import no.nav.su.se.bakover.domain.oppdrag.simulering.SimuleringFeilet import no.nav.su.se.bakover.domain.oppdrag.utbetaling.UtbetalingRepo import no.nav.su.se.bakover.domain.oppdrag.utbetaling.Utbetalinger @@ -383,19 +384,15 @@ fun simuleringNy( ), ), ): Simulering { - return Utbetalingsstrategi.NyUføreUtbetaling( + return utbetalingForSimulering( sakId = sakId, saksnummer = saksnummer, fnr = fnr, eksisterendeUtbetalinger = eksisterendeUtbetalinger, - behandler = saksbehandler, beregning = beregning, clock = clock, uføregrunnlag = uføregrunnlag, - kjøreplan = UtbetalingsinstruksjonForEtterbetalinger.SåFortSomMulig, - // TODO("simulering_utbetaling_alder utled fra sak/behandling") - sakstype = Sakstype.UFØRE, - ).generate().let { + ).let { SimuleringStub( // Overstyr klokke slik at vi kan simulere feilutbetalinger tilbake i tid, clock = nåtidForSimuleringStub, @@ -409,6 +406,40 @@ fun simuleringNy( }.getOrFail() } +fun utbetalingForSimulering( + beregning: Beregning = beregning(periode = år(2021)), + fnr: Fnr = no.nav.su.se.bakover.test.fnr, + sakId: UUID = no.nav.su.se.bakover.test.sakId, + saksnummer: Saksnummer = no.nav.su.se.bakover.test.saksnummer, + eksisterendeUtbetalinger: Utbetalinger = Utbetalinger(), + clock: Clock = fixedClock, + sakstype: Sakstype = Sakstype.UFØRE, + behandler: NavIdentBruker = saksbehandler, + kjøreplan: UtbetalingsinstruksjonForEtterbetalinger = UtbetalingsinstruksjonForEtterbetalinger.SåFortSomMulig, + uføregrunnlag: List = listOf( + Grunnlag.Uføregrunnlag( + id = UUID.randomUUID(), + opprettet = Tidspunkt.now(clock), + periode = beregning.periode, + uføregrad = Uføregrad.parse(50), + forventetInntekt = 0, + ), + ), +): Utbetaling.UtbetalingForSimulering { + return Utbetalingsstrategi.NyUføreUtbetaling( + sakId = sakId, + saksnummer = saksnummer, + fnr = fnr, + eksisterendeUtbetalinger = eksisterendeUtbetalinger, + behandler = behandler, + beregning = beregning, + clock = clock, + uføregrunnlag = uføregrunnlag, + kjøreplan = kjøreplan, + sakstype = sakstype, + ).generate() +} + fun simuleringOpphørt( opphørsperiode: Periode, eksisterendeUtbetalinger: Utbetalinger, @@ -694,6 +725,24 @@ fun simulertDetaljTilbakeføring( ) } +/** + * @param saksnummer ignoreres dersom [utbetaling] sendes inn + * @param utbetaling Default + * @param simuleringsperiode Default 2021 + */ +fun simuleringUtbetalingRequest( + saksnummer: Saksnummer = no.nav.su.se.bakover.test.saksnummer, + utbetaling: Utbetaling.UtbetalingForSimulering = utbetalingForSimulering( + saksnummer = saksnummer, + ), + simuleringsperiode: Periode = år(2021), +): SimulerUtbetalingRequest { + return SimulerUtbetalingForPeriode( + utbetaling = utbetaling, + simuleringsperiode = simuleringsperiode, + ) +} + data class SimuleringResponseData( var gjelderId: String = fnr.toString(), var gjelderNavn: String = "Test Testesen",