diff --git a/apps/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt b/apps/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt index 4ab437a0be..62ad413554 100644 --- a/apps/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt +++ b/apps/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt @@ -15,6 +15,7 @@ import no.nav.helsearbeidsgiver.felles.metrics.Metrics import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisConnection import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisPrefix import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore +import no.nav.helsearbeidsgiver.felles.utils.konverterEndringAarsakTilListe import no.nav.helsearbeidsgiver.inntektsmelding.api.RedisPoller import no.nav.helsearbeidsgiver.inntektsmelding.api.Routes import no.nav.helsearbeidsgiver.inntektsmelding.api.auth.Tilgangskontroll @@ -105,6 +106,7 @@ private suspend fun PipelineContext.lesRequestOrNull(): S sikkerLogger.info("$it\n${json.toPretty()}") } }.fromJson(SkjemaInntektsmelding.serializer()) + .konverterEndringAarsakTilListe() }.getOrElse { error -> "Klarte ikke parse json for inntektsmeldingsskjema.".also { logger.error(it) diff --git a/apps/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentselvbestemtim/HentSelvbestemtImRouteKtTest.kt b/apps/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentselvbestemtim/HentSelvbestemtImRouteKtTest.kt index a989a770df..5c7a4c9ee2 100644 --- a/apps/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentselvbestemtim/HentSelvbestemtImRouteKtTest.kt +++ b/apps/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentselvbestemtim/HentSelvbestemtImRouteKtTest.kt @@ -318,7 +318,8 @@ private fun Inntekt.hardcodedJson(): String = "beloep": $beloep, "inntektsdato": "$inntektsdato", "naturalytelser": [${naturalytelser.joinToString(transform = Naturalytelse::hardcodedJson)}], - "endringAarsak": ${endringAarsak?.hardcodedJson()} + "endringAarsak": ${endringAarsak?.hardcodedJson()}, + "endringAarsaker": [${endringAarsak?.hardcodedJson()}] } """ diff --git a/apps/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/utils/EndringsAarsakUtils.kt b/apps/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/utils/EndringsAarsakUtils.kt new file mode 100644 index 0000000000..43170f249b --- /dev/null +++ b/apps/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/utils/EndringsAarsakUtils.kt @@ -0,0 +1,16 @@ +package no.nav.helsearbeidsgiver.felles.utils + +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding + +// midlertidlig duplisering for å støtte flere endringsÅrsaker +fun SkjemaInntektsmelding.konverterEndringAarsakTilListe(): SkjemaInntektsmelding = + if (this.inntekt?.endringAarsaker != null) { + this + } else { + this.copy( + inntekt = + this.inntekt?.copy( + endringAarsaker = listOfNotNull(this.inntekt?.endringAarsak), + ), + ) + } diff --git a/apps/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockInntektsmelding.kt b/apps/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockInntektsmelding.kt index ebbc1b8fa3..62fcdaa376 100644 --- a/apps/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockInntektsmelding.kt +++ b/apps/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockInntektsmelding.kt @@ -130,6 +130,12 @@ fun mockInntekt(): Inntekt = NyStillingsprosent( gjelderFra = 16.oktober, ), + endringAarsaker = + listOf( + NyStillingsprosent( + gjelderFra = 16.oktober, + ), + ), ) fun mockRefusjon(): Refusjon = diff --git a/apps/joark/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/joark/dokument/PdfDokument.kt b/apps/joark/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/joark/dokument/PdfDokument.kt index e1b8ea4c62..abcf0b5562 100644 --- a/apps/joark/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/joark/dokument/PdfDokument.kt +++ b/apps/joark/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/joark/dokument/PdfDokument.kt @@ -7,6 +7,7 @@ import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Bonus import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Feilregistrert import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Ferie import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Ferietrekk +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.InntektEndringAarsak import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Inntektsmelding import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.NyStilling import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.NyStillingsprosent @@ -18,8 +19,9 @@ import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Sykefravaer import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Tariffendring import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.VarigLoennsendring import no.nav.helsearbeidsgiver.felles.utils.tilNorskFormat +import no.nav.helsearbeidsgiver.utils.pipe.orDefault -private const val FORKLARING_ENDRING = "Forklaring for endring" +private const val FORKLARING_ENDRING = "Endringsårsak" class PdfDokument( val inntektsmelding: Inntektsmelding, @@ -197,87 +199,85 @@ class PdfDokument( "Registrert inntekt (per ${inntektsmelding.inntekt?.inntektsdato?.tilNorskFormat()})", "${inntektsmelding.inntekt?.beloep?.tilNorskFormat()} kr/måned", ) - val endringAarsak = inntektsmelding.inntekt?.endringAarsak - when (endringAarsak) { - null -> return // trenger ikke sende inn årsak... - is Bonus -> addBonus() - is Feilregistrert -> addFeilregistrert() - is Ferie -> addFerie(endringAarsak) - is Ferietrekk -> addFerietrekk() - is NyStilling -> addNyStilling(endringAarsak) - is NyStillingsprosent -> addNyStillingsprosent(endringAarsak) - is Nyansatt -> addNyAnsatt() - is Permisjon -> addPermisjon(endringAarsak) - is Permittering -> addPermittering(endringAarsak) - is Sykefravaer -> addSykefravaer(endringAarsak) - is Tariffendring -> addTariffendring(endringAarsak) - is VarigLoennsendring -> addVarigLonnsendring(endringAarsak) + + val endringAarsaker = inntektsmelding.inntekt?.endringAarsaker.orDefault(emptyList()) + val antall = endringAarsaker.size + endringAarsaker.forEachIndexed { indeks, endringAarsak -> + + val forklaringEndring = + if (antall > 1) { + "$FORKLARING_ENDRING (${indeks + 1} av $antall)" + } else { + FORKLARING_ENDRING + } + + when (endringAarsak) { + is Bonus, is Feilregistrert, is Nyansatt, is Ferietrekk -> + addLabel(forklaringEndring, endringAarsak.beskrivelse()) + + is Ferie -> + addInntektEndringPerioder(forklaringEndring, endringAarsak.beskrivelse(), endringAarsak.ferier) + is Permisjon -> + addInntektEndringPerioder(forklaringEndring, endringAarsak.beskrivelse(), endringAarsak.permisjoner) + is Permittering -> + addInntektEndringPerioder(forklaringEndring, endringAarsak.beskrivelse(), endringAarsak.permitteringer) + is Sykefravaer -> + addInntektEndringPerioder(forklaringEndring, endringAarsak.beskrivelse(), endringAarsak.sykefravaer) + + is NyStilling -> + addNyStilling(forklaringEndring, endringAarsak) + is Tariffendring -> + addTariffendring(forklaringEndring, endringAarsak) + is VarigLoennsendring -> + addVarigLonnsendring(forklaringEndring, endringAarsak) + is NyStillingsprosent -> + addNyStillingsprosent(forklaringEndring, endringAarsak) + } } } private fun addInntektEndringPerioder( + forklaringEndring: String, endringAarsak: String, perioder: List, ) { - addLabel(FORKLARING_ENDRING, endringAarsak, linefeed = false) + addLabel(forklaringEndring, endringAarsak, linefeed = false) addPerioder(kolonneTo, perioder) } - private fun addPermisjon(permisjon: Permisjon) { - addInntektEndringPerioder("Permisjon", permisjon.permisjoner) - } - - private fun addFerie(ferie: Ferie) { - addInntektEndringPerioder("Ferie", ferie.ferier) - } - - private fun addPermittering(permittering: Permittering) { - addInntektEndringPerioder("Permittering", permittering.permitteringer) - } - - private fun addSykefravaer(sykefravaer: Sykefravaer) { - addInntektEndringPerioder("Sykefravær", sykefravaer.sykefravaer) - } - - private fun addNyAnsatt() { - addLabel(FORKLARING_ENDRING, "Nyansatt") - } - - private fun addFeilregistrert() { - addLabel(FORKLARING_ENDRING, "Mangelfull eller uriktig rapportering til A-ordningen") - } - - private fun addTariffendring(tariffendring: Tariffendring) { - addLabel(FORKLARING_ENDRING, "Tariffendring") + private fun addTariffendring( + forklaringEndring: String, + tariffendring: Tariffendring, + ) { + addLabel(forklaringEndring, tariffendring.beskrivelse()) addLabel("Gjelder fra", tariffendring.gjelderFra.tilNorskFormat(), linefeed = false) addLabel("Ble kjent", tariffendring.bleKjent.tilNorskFormat(), kolonneTo) } - private fun addVarigLonnsendring(varigLoennsendring: VarigLoennsendring) { - addLabel(FORKLARING_ENDRING, "Varig lønnsendring") + private fun addVarigLonnsendring( + forklaringEndring: String, + varigLoennsendring: VarigLoennsendring, + ) { + addLabel(forklaringEndring, varigLoennsendring.beskrivelse()) addLabel("Gjelder fra", varigLoennsendring.gjelderFra.tilNorskFormat()) } - private fun addNyStilling(nyStilling: NyStilling) { - addLabel(FORKLARING_ENDRING, "Ny stilling", linefeed = false) + private fun addNyStilling( + forklaringEndring: String, + nyStilling: NyStilling, + ) { + addLabel(forklaringEndring, nyStilling.beskrivelse(), linefeed = false) addLabel("Gjelder fra", nyStilling.gjelderFra.tilNorskFormat(), kolonneTo) } - private fun addNyStillingsprosent(nyStillingsprosent: NyStillingsprosent) { - addLabel(FORKLARING_ENDRING, "Ny stillingsprosent", linefeed = false) + private fun addNyStillingsprosent( + forklaringEndring: String, + nyStillingsprosent: NyStillingsprosent, + ) { + addLabel(forklaringEndring, nyStillingsprosent.beskrivelse(), linefeed = false) addLabel("Gjelder fra", nyStillingsprosent.gjelderFra.tilNorskFormat(), kolonneTo) } - private fun addBonus() { - addLabel(FORKLARING_ENDRING, "Bonus") - // addLabel("Estimert årlig bonus", årligBonus.tilNorskFormat()) - // addLabel("Dato siste bonus", datoBonus.tilNorskFormat()) - } - - private fun addFerietrekk() { - addLabel(FORKLARING_ENDRING, "Ferietrekk/Utbetaling av feriepenger") - } - private fun addRefusjon() { val redusertLoennIAgp = inntektsmelding.agp?.redusertLoennIAgp val refusjon = inntektsmelding.refusjon @@ -332,3 +332,21 @@ class PdfDokument( moveCursorBy(pdf.bodySize) } } + +fun InntektEndringAarsak.beskrivelse(): String = + when (this) { + is Bonus -> "Bonus" + is Feilregistrert -> "Mangelfull eller uriktig rapportering til A-ordningen" + is Nyansatt -> "Nyansatt" + is Ferietrekk -> "Ferietrekk/Utbetaling av feriepenger" + is Ferie -> "Ferie" + is Permisjon -> "Permisjon" + is Permittering -> "Permittering" + is Sykefravaer -> "Sykefravær" + is NyStilling -> "Ny stilling" + is Tariffendring -> "Tariffendring" + is VarigLoennsendring -> "Varig lønnsendring" + is NyStillingsprosent -> "Ny stillingsprosent" + + else -> throw NotImplementedError("Ingen beskrivelse definert for InntektEndringAarsak") + } diff --git a/apps/joark/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/joark/dokument/PdfDokumentTest.kt b/apps/joark/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/joark/dokument/PdfDokumentTest.kt index a86198f176..6ba7a7084a 100644 --- a/apps/joark/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/joark/dokument/PdfDokumentTest.kt +++ b/apps/joark/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/joark/dokument/PdfDokumentTest.kt @@ -1,6 +1,7 @@ package no.nav.helsearbeidsgiver.inntektsmelding.joark.dokument import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.string.shouldContain import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Bonus import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Feilregistrert import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Ferie @@ -30,6 +31,7 @@ import java.time.LocalDate class PdfDokumentTest { private val dag = LocalDate.of(2022, 12, 24) private val im = mockInntektsmeldingV1() + private val endringAarsaker = endringAarsakMap().values.toList() @Test fun `betaler full lønn i arbeidsgiverperioden`() { @@ -224,20 +226,7 @@ class PdfDokumentTest { @Test fun `med inntekt endring årsak - alle varianter`() { - val perioder = listOf(Periode(dag, dag.plusDays(12)), Periode(dag.plusDays(13), dag.plusDays(18))) - val map = HashMap() - map["bonus"] = Bonus - map["feilregistrert"] = Feilregistrert - map["ferie"] = Ferie(perioder) - map["ferietrekk"] = Ferietrekk - map["nyansatt"] = Nyansatt - map["nystilling"] = NyStilling(dag) - map["nystillingsprosent"] = NyStillingsprosent(dag) - map["permisjon"] = Permisjon(perioder) - map["permittering"] = Permittering(perioder) - map["sykefravaer"] = Sykefravaer(perioder) - map["tariffendring"] = Tariffendring(dag, dag.plusDays(2)) - map["variglonnsendring"] = VarigLoennsendring(dag) + val map = endringAarsakMap() map.forEach { writePDF( @@ -247,6 +236,7 @@ class PdfDokumentTest { im.inntekt.shouldNotBeNull().copy( beloep = 123.0, endringAarsak = it.value, + endringAarsaker = listOf(it.value), ), ), ) @@ -258,16 +248,58 @@ class PdfDokumentTest { im.inntekt.shouldNotBeNull().copy( beloep = 123.0, endringAarsak = null, + endringAarsaker = emptyList(), ), ), ) } + @Test + fun `med en begrunnelse blir teksten lagt til`() { + endringAarsaker.map { listOf(it) }.map { it.tilIm() }.forEach { im -> + im.inntekt?.endringAarsaker?.forEach { endring -> + pdfTekstFraIm(im) shouldContain "Endringsårsak\n${endring.beskrivelse()}" + } + } + } + + @Test + fun `med 2, 3, 4, 5 eller 6 begrunnelser blir teksten lagt til`() { + (2..6).forEach { n -> + endringAarsaker + .windowed(n, 1, partialWindows = false) + .map { it.tilIm() } + .forEach { im -> + im.inntekt?.endringAarsaker?.forEachIndexed { indeks, endring -> + val tekst = pdfTekstFraIm(im) + tekst shouldContain "Endringsårsak (${indeks + 1} av $n)" + tekst shouldContain endring.beskrivelse() + } + } + } + } + + private fun List.tilIm(): Inntektsmelding = + im.copy( + inntekt = + im.inntekt.shouldNotBeNull().copy( + beloep = 123.0, + endringAarsaker = this, + endringAarsak = null, + ), + ) + + private fun pdfTekstFraIm(im: Inntektsmelding): String { + val pdfDok = PdfDokument(im).export() + val pdfTekst = extractTextFromPdf(pdfDok) + return pdfTekst.shouldNotBeNull() + } + private fun writePDF( title: String, im: Inntektsmelding, ) { - // val file = File(System.getProperty("user.home"), "/Desktop/$title.pdf") +// val file = File(System.getProperty("user.home"), "/Desktop/pdf/$title.pdf") val file = File.createTempFile(title, ".pdf") val writer = FileOutputStream(file) writer.write(PdfDokument(im).export()) @@ -282,4 +314,22 @@ class PdfDokumentTest { pdfReader.close() return allTextInDocument } + + private fun endringAarsakMap(): HashMap { + val perioder = listOf(Periode(dag, dag.plusDays(12)), Periode(dag.plusDays(13), dag.plusDays(18))) + val map = HashMap() + map["bonus"] = Bonus + map["feilregistrert"] = Feilregistrert + map["ferie"] = Ferie(perioder) + map["ferietrekk"] = Ferietrekk + map["nyansatt"] = Nyansatt + map["nystilling"] = NyStilling(dag) + map["nystillingsprosent"] = NyStillingsprosent(dag) + map["permisjon"] = Permisjon(perioder) + map["permittering"] = Permittering(perioder) + map["sykefravaer"] = Sykefravaer(perioder) + map["tariffendring"] = Tariffendring(dag, dag.plusDays(2)) + map["variglonnsendring"] = VarigLoennsendring(dag) + return map + } } diff --git a/gradle.properties b/gradle.properties index e2eb60c9b1..72fe916829 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ kotlinVersion=2.0.21 kotlinterVersion=4.4.0 # Dependency versions -hagDomeneInntektsmeldingVersion=0.1.7 +hagDomeneInntektsmeldingVersion=0.1.8 junitJupiterVersion=5.11.3 kotestVersion=5.9.1 kotlinCoroutinesVersion=1.9.0