From c8c3dc2a678aa702fae99bf65b4e070eb91b4d98 Mon Sep 17 00:00:00 2001 From: "Geir A. Lund" Date: Wed, 20 Dec 2023 10:23:47 +0100 Subject: [PATCH] Flytte inntekt kontrakter fra dagpenger-events til inntekt APIet. (#163) --- .github/workflows/deploy.yaml | 2 + .github/workflows/publish.yaml | 66 +++++ dp-inntekt-api/build.gradle.kts | 3 +- .../inntekt/BehandlingsInntektsGetter.kt | 4 +- .../nav/dagpenger/inntekt/db/InntektStore.kt | 2 +- .../inntekt/db/KronetilleggUttrekk.kt | 2 +- .../inntekt/db/PostgresInntektStore.kt | 2 +- .../klassifiserer/KlassifisertInntekt.kt | 10 +- .../klassifiserer/KlassifisertPostering.kt | 6 +- .../mapping/MapToSpesifisertInntekt.kt | 14 +- .../inntekt/mapping/PosteringsTypeMapping.kt | 2 +- .../klassifiser/KlassifiserInntektTest.kt | 16 +- .../klassifiser/KlassifiserPosteringTest.kt | 4 +- .../mapping/MapToSpesifisertInntektTest.kt | 16 +- .../mapping/PosteringsTypeMappingTest.kt | 2 +- .../dagpenger/inntekt/v1/InntektRouteSpec.kt | 7 +- dp-inntekt-kontrakter/build.gradle.kts | 65 +++++ .../no/nav/dagpenger/inntekt/v1/Inntekt.kt | 48 ++++ .../inntekt/v1/KlassifisertInntekt.kt | 21 ++ .../v1/KlassifisertInntektM\303\245ned.kt" | 21 ++ .../dagpenger/inntekt/v1/PosteringsType.kt | 112 +++++++++ .../inntekt/v1/SpesifisertInntekt.kt | 75 ++++++ .../nav/dagpenger/inntekt/v1/InntektTest.kt | 229 ++++++++++++++++++ .../KlassifisertInntektM\303\245nedTest.kt" | 118 +++++++++ settings.gradle.kts | 5 +- 25 files changed, 805 insertions(+), 47 deletions(-) create mode 100644 .github/workflows/publish.yaml create mode 100644 dp-inntekt-kontrakter/build.gradle.kts create mode 100644 dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/Inntekt.kt create mode 100644 dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntekt.kt create mode 100644 "dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntektM\303\245ned.kt" create mode 100644 dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/PosteringsType.kt create mode 100644 dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/SpesifisertInntekt.kt create mode 100644 dp-inntekt-kontrakter/src/test/kotlin/no/nav/dagpenger/inntekt/v1/InntektTest.kt create mode 100644 "dp-inntekt-kontrakter/src/test/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntektM\303\245nedTest.kt" diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index a9d0c36e..2d6315ac 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -4,6 +4,8 @@ on: push: branches-ignore: - 'dependabot/**' + paths-ignore: + - 'dp-inntekt-kontrakter/**' jobs: build: diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 00000000..43cddda9 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,66 @@ +name: Publish dp-inntekt-kontrakter + +on: + push: + paths: + - 'dp-inntekt-kontrakter/**' +jobs: + + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Java and build + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + - uses: gradle/wrapper-validation-action@v1.1.0 + - uses: gradle/gradle-build-action@v2.11.0 + env: + # Eksluder test dependencies + DEPENDENCY_GRAPH_INCLUDE_CONFIGURATIONS: compileClasspath|runtimeClasspath + with: + gradle-version: wrapper + dependency-graph: generate-and-submit + arguments: --configuration-cache test + + + release: + name: Create Release + needs: build + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' && !contains(github.event.head_commit.message, 'ci skip') + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + - name: Set release tag + run: | + export TAG_NAME="1_$(TZ="Europe/Oslo" date +%Y%m%d).$(echo $GITHUB_SHA | cut -c 1-6)" + echo "RELEASE_TAG=$TAG_NAME" >> $GITHUB_ENV + - uses: ncipollo/release-action@6c75be85e571768fa31b40abf38de58ba0397db5 # ratchet:ncipollo/release-action@v1 + with: + tag: ${{ env.RELEASE_TAG }} + generateReleaseNotes: true + outputs: + tag: ${{ env.RELEASE_TAG }} + publish: + runs-on: ubuntu-latest + needs: release + permissions: + packages: write + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17.x + cache: 'gradle' + - name: publish + run: ./gradlew -Pversion="$(echo ${{ needs.release.outputs.tag }})" publish + env: + ORG_GRADLE_PROJECT_githubUser: x-access-token + ORG_GRADLE_PROJECT_githubPassword: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/dp-inntekt-api/build.gradle.kts b/dp-inntekt-api/build.gradle.kts index b2628862..035cabe5 100644 --- a/dp-inntekt-api/build.gradle.kts +++ b/dp-inntekt-api/build.gradle.kts @@ -27,7 +27,8 @@ val log4j2Version = "2.20.0" dependencies { - implementation("com.github.navikt:dagpenger-events:20231204.ee1cc3") + implementation(project(":dp-inntekt-kontrakter")) + implementation("com.github.navikt:dagpenger-streams:20230831.f3d785") implementation(libs.bundles.ktor.server) diff --git a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/BehandlingsInntektsGetter.kt b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/BehandlingsInntektsGetter.kt index 595837bf..0f43e5a2 100644 --- a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/BehandlingsInntektsGetter.kt +++ b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/BehandlingsInntektsGetter.kt @@ -1,8 +1,6 @@ package no.nav.dagpenger.inntekt import mu.KotlinLogging -import no.nav.dagpenger.events.inntekt.v1.Inntekt -import no.nav.dagpenger.events.inntekt.v1.SpesifisertInntekt import no.nav.dagpenger.inntekt.db.InntektId import no.nav.dagpenger.inntekt.db.InntektStore import no.nav.dagpenger.inntekt.db.Inntektparametre @@ -12,6 +10,8 @@ import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektkomponentRequest import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektskomponentClient import no.nav.dagpenger.inntekt.klassifiserer.klassifiserOgMapInntekt import no.nav.dagpenger.inntekt.mapping.mapToSpesifisertInntekt +import no.nav.dagpenger.inntekt.v1.Inntekt +import no.nav.dagpenger.inntekt.v1.SpesifisertInntekt private val LOGGER = KotlinLogging.logger {} diff --git a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/InntektStore.kt b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/InntektStore.kt index eef85177..978932cf 100644 --- a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/InntektStore.kt +++ b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/InntektStore.kt @@ -1,9 +1,9 @@ package no.nav.dagpenger.inntekt.db import de.huxhorn.sulky.ulid.ULID -import no.nav.dagpenger.events.inntekt.v1.SpesifisertInntekt import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektkomponentResponse import no.nav.dagpenger.inntekt.opptjeningsperiode.Opptjeningsperiode +import no.nav.dagpenger.inntekt.v1.SpesifisertInntekt import java.time.LocalDate import java.time.LocalDateTime import java.time.ZoneOffset diff --git a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/KronetilleggUttrekk.kt b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/KronetilleggUttrekk.kt index 3195ec75..9de1babc 100644 --- a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/KronetilleggUttrekk.kt +++ b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/KronetilleggUttrekk.kt @@ -3,12 +3,12 @@ package no.nav.dagpenger.inntekt.db import kotliquery.queryOf import kotliquery.sessionOf import kotliquery.using -import no.nav.dagpenger.events.inntekt.v1.InntektKlasse import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektkomponentResponse import no.nav.dagpenger.inntekt.klassifiserer.klassifiserOgMapInntekt import no.nav.dagpenger.inntekt.mapping.mapToSpesifisertInntekt import no.nav.dagpenger.inntekt.opptjeningsperiode.Opptjeningsperiode import no.nav.dagpenger.inntekt.serder.jacksonObjectMapper +import no.nav.dagpenger.inntekt.v1.InntektKlasse import java.time.LocalDate import javax.sql.DataSource diff --git a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/PostgresInntektStore.kt b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/PostgresInntektStore.kt index 31546014..492e751a 100644 --- a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/PostgresInntektStore.kt +++ b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/PostgresInntektStore.kt @@ -7,13 +7,13 @@ import kotliquery.queryOf import kotliquery.sessionOf import kotliquery.using import mu.KotlinLogging -import no.nav.dagpenger.events.inntekt.v1.SpesifisertInntekt import no.nav.dagpenger.inntekt.HealthCheck import no.nav.dagpenger.inntekt.HealthStatus import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektkomponentResponse import no.nav.dagpenger.inntekt.mapping.mapToSpesifisertInntekt import no.nav.dagpenger.inntekt.opptjeningsperiode.Opptjeningsperiode import no.nav.dagpenger.inntekt.serder.jacksonObjectMapper +import no.nav.dagpenger.inntekt.v1.SpesifisertInntekt import org.intellij.lang.annotations.Language import org.postgresql.util.PGobject import org.postgresql.util.PSQLException diff --git a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/klassifiserer/KlassifisertInntekt.kt b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/klassifiserer/KlassifisertInntekt.kt index cdd97c69..fd3f83af 100644 --- a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/klassifiserer/KlassifisertInntekt.kt +++ b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/klassifiserer/KlassifisertInntekt.kt @@ -1,10 +1,10 @@ package no.nav.dagpenger.inntekt.klassifiserer -import no.nav.dagpenger.events.inntekt.v1.Avvik -import no.nav.dagpenger.events.inntekt.v1.Inntekt -import no.nav.dagpenger.events.inntekt.v1.KlassifisertInntekt -import no.nav.dagpenger.events.inntekt.v1.KlassifisertInntektMåned -import no.nav.dagpenger.events.inntekt.v1.SpesifisertInntekt +import no.nav.dagpenger.inntekt.v1.Avvik +import no.nav.dagpenger.inntekt.v1.Inntekt +import no.nav.dagpenger.inntekt.v1.KlassifisertInntekt +import no.nav.dagpenger.inntekt.v1.KlassifisertInntektMåned +import no.nav.dagpenger.inntekt.v1.SpesifisertInntekt import java.math.BigDecimal import java.time.YearMonth diff --git a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/klassifiserer/KlassifisertPostering.kt b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/klassifiserer/KlassifisertPostering.kt index e0ca06a4..e6b385ea 100644 --- a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/klassifiserer/KlassifisertPostering.kt +++ b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/klassifiserer/KlassifisertPostering.kt @@ -1,8 +1,8 @@ package no.nav.dagpenger.inntekt.klassifiserer -import no.nav.dagpenger.events.inntekt.v1.InntektKlasse -import no.nav.dagpenger.events.inntekt.v1.Postering -import no.nav.dagpenger.events.inntekt.v1.PosteringsType +import no.nav.dagpenger.inntekt.v1.InntektKlasse +import no.nav.dagpenger.inntekt.v1.Postering +import no.nav.dagpenger.inntekt.v1.PosteringsType internal data class KlassifisertPostering(val postering: Postering, val inntektKlasse: InntektKlasse) diff --git a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/mapping/MapToSpesifisertInntekt.kt b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/mapping/MapToSpesifisertInntekt.kt index 050a703c..15151b1d 100644 --- a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/mapping/MapToSpesifisertInntekt.kt +++ b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/mapping/MapToSpesifisertInntekt.kt @@ -1,15 +1,15 @@ package no.nav.dagpenger.inntekt.mapping -import no.nav.dagpenger.events.inntekt.v1.Aktør -import no.nav.dagpenger.events.inntekt.v1.AktørType -import no.nav.dagpenger.events.inntekt.v1.Avvik -import no.nav.dagpenger.events.inntekt.v1.InntektId -import no.nav.dagpenger.events.inntekt.v1.Periode -import no.nav.dagpenger.events.inntekt.v1.Postering -import no.nav.dagpenger.events.inntekt.v1.SpesifisertInntekt import no.nav.dagpenger.inntekt.db.StoredInntekt import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Aktoer import no.nav.dagpenger.inntekt.inntektskomponenten.v1.ArbeidsInntektMaaned +import no.nav.dagpenger.inntekt.v1.Aktør +import no.nav.dagpenger.inntekt.v1.AktørType +import no.nav.dagpenger.inntekt.v1.Avvik +import no.nav.dagpenger.inntekt.v1.InntektId +import no.nav.dagpenger.inntekt.v1.Periode +import no.nav.dagpenger.inntekt.v1.Postering +import no.nav.dagpenger.inntekt.v1.SpesifisertInntekt import java.time.LocalDateTime import java.time.YearMonth diff --git a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/mapping/PosteringsTypeMapping.kt b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/mapping/PosteringsTypeMapping.kt index 0ac06768..9baadd22 100644 --- a/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/mapping/PosteringsTypeMapping.kt +++ b/dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/mapping/PosteringsTypeMapping.kt @@ -1,10 +1,10 @@ package no.nav.dagpenger.inntekt.mapping import com.uchuhimo.collections.biMapOf -import no.nav.dagpenger.events.inntekt.v1.PosteringsType import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektBeskrivelse import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektType import no.nav.dagpenger.inntekt.inntektskomponenten.v1.SpesielleInntjeningsforhold +import no.nav.dagpenger.inntekt.v1.PosteringsType data class PosteringsTypeGrunnlag( val type: InntektType, diff --git a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/klassifiser/KlassifiserInntektTest.kt b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/klassifiser/KlassifiserInntektTest.kt index 03c8e4c1..2ea3b6bd 100644 --- a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/klassifiser/KlassifiserInntektTest.kt +++ b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/klassifiser/KlassifiserInntektTest.kt @@ -1,16 +1,16 @@ package no.nav.dagpenger.inntekt.klassifiser import io.kotest.matchers.shouldBe -import no.nav.dagpenger.events.inntekt.v1.Aktør -import no.nav.dagpenger.events.inntekt.v1.AktørType -import no.nav.dagpenger.events.inntekt.v1.Avvik -import no.nav.dagpenger.events.inntekt.v1.InntektId -import no.nav.dagpenger.events.inntekt.v1.InntektKlasse -import no.nav.dagpenger.events.inntekt.v1.Postering -import no.nav.dagpenger.events.inntekt.v1.PosteringsType -import no.nav.dagpenger.events.inntekt.v1.SpesifisertInntekt import no.nav.dagpenger.inntekt.klassifiserer.klassifiserOgMapInntekt import no.nav.dagpenger.inntekt.serder.jacksonObjectMapper +import no.nav.dagpenger.inntekt.v1.Aktør +import no.nav.dagpenger.inntekt.v1.AktørType +import no.nav.dagpenger.inntekt.v1.Avvik +import no.nav.dagpenger.inntekt.v1.InntektId +import no.nav.dagpenger.inntekt.v1.InntektKlasse +import no.nav.dagpenger.inntekt.v1.Postering +import no.nav.dagpenger.inntekt.v1.PosteringsType +import no.nav.dagpenger.inntekt.v1.SpesifisertInntekt import org.junit.jupiter.api.Test import java.math.BigDecimal import java.time.LocalDateTime diff --git a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/klassifiser/KlassifiserPosteringTest.kt b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/klassifiser/KlassifiserPosteringTest.kt index c53f966b..525b611c 100644 --- a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/klassifiser/KlassifiserPosteringTest.kt +++ b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/klassifiser/KlassifiserPosteringTest.kt @@ -1,8 +1,8 @@ package no.nav.dagpenger.inntekt.klassifiser -import no.nav.dagpenger.events.inntekt.v1.InntektKlasse -import no.nav.dagpenger.events.inntekt.v1.PosteringsType import no.nav.dagpenger.inntekt.klassifiserer.klassifiserOgMapInntekt +import no.nav.dagpenger.inntekt.v1.InntektKlasse +import no.nav.dagpenger.inntekt.v1.PosteringsType import org.junit.jupiter.api.Test import kotlin.test.assertEquals diff --git a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/mapping/MapToSpesifisertInntektTest.kt b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/mapping/MapToSpesifisertInntektTest.kt index 8d80566a..09114b36 100644 --- a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/mapping/MapToSpesifisertInntektTest.kt +++ b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/mapping/MapToSpesifisertInntektTest.kt @@ -1,11 +1,5 @@ package no.nav.dagpenger.inntekt.mapping -import no.nav.dagpenger.events.inntekt.v1.Aktør -import no.nav.dagpenger.events.inntekt.v1.AktørType -import no.nav.dagpenger.events.inntekt.v1.InntektId -import no.nav.dagpenger.events.inntekt.v1.Postering -import no.nav.dagpenger.events.inntekt.v1.PosteringsType -import no.nav.dagpenger.events.inntekt.v1.SpesifisertInntekt import no.nav.dagpenger.inntekt.db.StoredInntekt import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Aktoer import no.nav.dagpenger.inntekt.inntektskomponenten.v1.AktoerType @@ -20,6 +14,12 @@ import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Periode import no.nav.dagpenger.inntekt.inntektskomponenten.v1.SpesielleInntjeningsforhold import no.nav.dagpenger.inntekt.inntektskomponenten.v1.TilleggInformasjon import no.nav.dagpenger.inntekt.inntektskomponenten.v1.TilleggInformasjonsDetaljer +import no.nav.dagpenger.inntekt.v1.Aktør +import no.nav.dagpenger.inntekt.v1.AktørType +import no.nav.dagpenger.inntekt.v1.InntektId +import no.nav.dagpenger.inntekt.v1.Postering +import no.nav.dagpenger.inntekt.v1.PosteringsType +import no.nav.dagpenger.inntekt.v1.SpesifisertInntekt import org.junit.jupiter.api.Test import java.math.BigDecimal import java.time.LocalDate @@ -122,7 +122,7 @@ private val spesifisertInntekt = inntektId = InntektId("01DGCVFS44PT6B6ZGEYH2WXVMA"), avvik = listOf( - no.nav.dagpenger.events.inntekt.v1.Avvik( + no.nav.dagpenger.inntekt.v1.Avvik( ident = Aktør(AktørType.AKTOER_ID, "11111111"), opplysningspliktig = Aktør(AktørType.AKTOER_ID, "21111111"), virksomhet = Aktør(AktørType.ORGANISASJON, "31111111"), @@ -163,7 +163,7 @@ private val spesifisertInntekt = leveringstidspunkt = YearMonth.of(2019, 3), opptjeningsland = "Norge", opptjeningsperiode = - no.nav.dagpenger.events.inntekt.v1.Periode( + no.nav.dagpenger.inntekt.v1.Periode( LocalDate.of(2019, 2, 3), LocalDate.of(2019, 5, 12), ), diff --git a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/mapping/PosteringsTypeMappingTest.kt b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/mapping/PosteringsTypeMappingTest.kt index 8d926418..db7df8dc 100644 --- a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/mapping/PosteringsTypeMappingTest.kt +++ b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/mapping/PosteringsTypeMappingTest.kt @@ -1,9 +1,9 @@ package no.nav.dagpenger.inntekt.mapping -import no.nav.dagpenger.events.inntekt.v1.PosteringsType import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektBeskrivelse import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektType import no.nav.dagpenger.inntekt.inntektskomponenten.v1.SpesielleInntjeningsforhold +import no.nav.dagpenger.inntekt.v1.PosteringsType import org.junit.jupiter.api.Test import kotlin.test.assertEquals diff --git a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/v1/InntektRouteSpec.kt b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/v1/InntektRouteSpec.kt index 16a7f28a..954dd169 100644 --- a/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/v1/InntektRouteSpec.kt +++ b/dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/v1/InntektRouteSpec.kt @@ -19,9 +19,6 @@ import io.mockk.coVerify import io.mockk.mockk import io.mockk.spyk import no.bekk.bekkopen.person.FodselsnummerCalculator.getFodselsnummerForDate -import no.nav.dagpenger.events.inntekt.v1.InntektKlasse -import no.nav.dagpenger.events.inntekt.v1.KlassifisertInntekt -import no.nav.dagpenger.events.inntekt.v1.KlassifisertInntektMåned import no.nav.dagpenger.inntekt.ApiKeyVerifier import no.nav.dagpenger.inntekt.AuthApiKeyVerifier import no.nav.dagpenger.inntekt.BehandlingsInntektsGetter @@ -130,7 +127,7 @@ internal class InntektRouteSpec { val uKjentInntektsId = ULID().nextULID() val kjentInntektsId = ULID().nextULID() val kjentInntekt = - no.nav.dagpenger.events.inntekt.v1.Inntekt( + no.nav.dagpenger.inntekt.v1.Inntekt( kjentInntektsId, sisteAvsluttendeKalenderMåned = YearMonth.of(2023, 10), inntektsListe = @@ -401,7 +398,7 @@ internal class InntektRouteSpec { val hentetInntekt = jacksonObjectMapper.readValue( kjentInntektIdresponse.bodyAsText(), - no.nav.dagpenger.events.inntekt.v1.Inntekt::class.java, + no.nav.dagpenger.inntekt.v1.Inntekt::class.java, ) assertSoftly { hentetInntekt.inntektsId shouldBe kjentInntekt.inntektsId diff --git a/dp-inntekt-kontrakter/build.gradle.kts b/dp-inntekt-kontrakter/build.gradle.kts new file mode 100644 index 00000000..be25e9e2 --- /dev/null +++ b/dp-inntekt-kontrakter/build.gradle.kts @@ -0,0 +1,65 @@ +plugins { + id("common") + `java-library` + id("maven-publish") +} + +dependencies { + implementation("de.huxhorn.sulky:de.huxhorn.sulky.ulid:8.3.0") +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(sourceSets["main"].allSource) +} + +val githubUser: String? by project +val githubPassword: String? by project + +publishing { + + repositories { + maven { + url = uri("https://maven.pkg.github.com/navikt/dp-inntekt-kontrakter") + credentials { + username = githubUser + password = githubPassword + } + } + } + publications { + create("mavenJava") { + from(components["java"]) + artifact(sourcesJar.get()) + + pom { + name.set("dp-inntekt-kontrakter") + description.set( + "Holder definisjonen av dagpenger inntekt", + ) + url.set("https://github.com/navikt/dp-inntekt") + withXml { + asNode().appendNode("packaging", "jar") + } + licenses { + license { + name.set("MIT License") + name.set("https://opensource.org/licenses/MIT") + } + } + developers { + developer { + organization.set("NAV (Arbeids- og velferdsdirektoratet) - The Norwegian Labour and Welfare Administration") + organizationUrl.set("https://www.nav.no") + } + } + + scm { + connection.set("scm:git:git://github.com/navikt/dp-inntekt.git") + developerConnection.set("scm:git:git://github.com/navikt/dp-inntekt.git") + url.set("https://github.com/navikt/dp-inntekt") + } + } + } + } +} diff --git a/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/Inntekt.kt b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/Inntekt.kt new file mode 100644 index 00000000..c5af0e39 --- /dev/null +++ b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/Inntekt.kt @@ -0,0 +1,48 @@ +package no.nav.dagpenger.inntekt.v1 + +import java.time.YearMonth + +class Inntekt( + val inntektsId: String, + val inntektsListe: List, + val manueltRedigert: Boolean? = false, + val sisteAvsluttendeKalenderMåned: YearMonth, +) { + fun splitIntoInntektsPerioder(): InntektsPerioder { + return Triple( + (0L..11L).map { i -> + inntektsListe.find { it.årMåned == sisteAvsluttendeKalenderMåned.minusMonths(i) } + ?: KlassifisertInntektMåned( + sisteAvsluttendeKalenderMåned.minusMonths(i), + emptyList(), + ) + }.sortedBy { it.årMåned }, + (12L..23L).map { i -> + inntektsListe.find { it.årMåned == sisteAvsluttendeKalenderMåned.minusMonths(i) } + ?: KlassifisertInntektMåned( + sisteAvsluttendeKalenderMåned.minusMonths(i), + emptyList(), + ) + }.sortedBy { it.årMåned }, + (24L..35L).map { i -> + inntektsListe.find { it.årMåned == sisteAvsluttendeKalenderMåned.minusMonths(i) } + ?: KlassifisertInntektMåned( + sisteAvsluttendeKalenderMåned.minusMonths(i), + emptyList(), + ) + }.sortedBy { it.årMåned }, + ) + } + + fun filterPeriod( + from: YearMonth, + to: YearMonth, + ): Inntekt { + if (from.isAfter(to)) throw IllegalArgumentException("Argument from=$from is after argument to=$to") + return Inntekt( + inntektsId, + inntektsListe.filter { it.årMåned !in from..to }, + sisteAvsluttendeKalenderMåned = sisteAvsluttendeKalenderMåned, + ) + } +} diff --git a/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntekt.kt b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntekt.kt new file mode 100644 index 00000000..0f6a2d62 --- /dev/null +++ b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntekt.kt @@ -0,0 +1,21 @@ +package no.nav.dagpenger.inntekt.v1 + +import java.math.BigDecimal + +data class KlassifisertInntekt( + val beløp: BigDecimal, + val inntektKlasse: InntektKlasse, +) + +enum class InntektKlasse { + ARBEIDSINNTEKT, + DAGPENGER, + DAGPENGER_FANGST_FISKE, + SYKEPENGER_FANGST_FISKE, + FANGST_FISKE, + SYKEPENGER, + TILTAKSLØNN, + PLEIEPENGER, + OMSORGSPENGER, + OPPLÆRINGSPENGER, +} diff --git "a/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntektM\303\245ned.kt" "b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntektM\303\245ned.kt" new file mode 100644 index 00000000..047b1387 --- /dev/null +++ "b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntektM\303\245ned.kt" @@ -0,0 +1,21 @@ +package no.nav.dagpenger.inntekt.v1 + +import java.math.BigDecimal +import java.time.YearMonth + +data class KlassifisertInntektMåned( + val årMåned: YearMonth, + val klassifiserteInntekter: List, + val harAvvik: Boolean? = null, +) + +fun Collection.sumInntekt(inntektsKlasserToSum: List) = + this.flatMap { klassifisertInntektMåned -> + klassifisertInntektMåned.klassifiserteInntekter + .filter { it.inntektKlasse in inntektsKlasserToSum } + .map { it.beløp } + }.fold(BigDecimal.ZERO, BigDecimal::add) + +typealias InntektsPerioder = Triple, List, List> + +fun InntektsPerioder.all() = this.toList().flatten() diff --git a/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/PosteringsType.kt b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/PosteringsType.kt new file mode 100644 index 00000000..b3c0a7b4 --- /dev/null +++ b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/PosteringsType.kt @@ -0,0 +1,112 @@ +package no.nav.dagpenger.inntekt.v1 + +enum class PosteringsType(val beskrivelse: String) { + L_AKSJER_GRUNNFONDSBEVIS_TIL_UNDERKURS("Aksjer/grunnfondsbevis til underkurs"), + L_ANNET("Annen arbeidsinntekt"), + L_ANNET_H("Hyre - Annet"), + L_ANNET_IKKE_SKATTEPLIKTIG("Annen arbeidsinntekt - Ikke skattepliktig"), + L_ANNET_UTLANDET("Annen arbeidsinntekt - Utlandet"), + L_ANNET_KONKURS("Annen arbeidsinntekt - Konkurs"), + L_ANNET_T("Tiltak - Annet"), + L_ARBEIDSOPPHOLD_KOST("Arbeidsopphold kost"), + L_ARBEIDSOPPHOLD_LOSJI("Arbeidsopphold losji"), + L_BEREGNET_SKATT("Beregnet skatt"), + L_BESØKSREISER_HJEMMET_ANNET("Besøksreiser hjemmet annet"), + L_BESØKSREISER_HJEMMET_KILOMETERGODTGJØRELSE_BIL("Besøksreiser hjemmet kilometergodtgjørelse bil"), + L_BETALT_UTENLANDSK_SKATT("Betalt utenlandsk skatt"), + L_BIL("Bil"), + L_BOLIG("Bolig"), + L_BONUS("Bonus"), + L_BONUS_FRA_FORSVARET("Bonus fra forsvaret"), + L_BONUS_H("Hyre - Bonus"), + L_BONUS_T("Tiltak - Bonus"), + L_ELEKTRONISK_KOMMUNIKASJON("Elektronisk kommunikasjon"), + L_FAST_BILGODTGJØRELSE("Fast bilgodtgjørelse"), + L_FAST_TILLEGG("Faste tillegg"), + L_FAST_TILLEGG_H("Hyre - Faste tillegg"), + L_FAST_TILLEGG_T("Tiltak - Faste tillegg"), + L_FASTLØNN("Fastlønn"), + L_FASTLØNN_H("Hyre - Fastlønn"), + L_FASTLØNN_T("Tiltak - Fastlønn"), + L_FERIEPENGER("Feriepenger"), + L_FERIEPENGER_H("Hyre - Feriepenger"), + L_FERIEPENGER_T("Tiltak - Feriepenger"), + L_FOND_FOR_IDRETTSUTØVERE("Fond for idrettsutøvere"), + L_HELLIGDAGSTILLEGG("Helligdagstillegg"), + L_HELLIGDAGSTILLEGG_H("Hyre - Helligdagstillegg"), + L_HELLIGDAGSTILLEGG_T("Tiltak - Helligdagstillegg"), + L_HONORAR_AKKORD_PROSENT_PROVISJON("Honorar, akkord, prosent eller provisjonslønn"), + L_HONORAR_AKKORD_PROSENT_PROVISJON_H("Hyre - Honorar, akkord, prosent eller provisjonslønn"), + L_HYRETILLEGG("Hyretillegg"), + L_IKKE_SKATTEPLIKTIG_LØNN_FRA_UTENLANDSK_DIPLOM_KONSUL_STASJON( + "Lønn mv som ikke er skattepliktig i Norge fra utenlandsk diplomatisk eller konsulær stasjon", + ), + L_INNBETALING_TIL_UTENLANDSK_PENSJONSORDNING("Innbetaling til utenlandsk pensjonsordning"), + L_KILOMETERGODTGJØRELSE_BIL("Kilometergodtgjørelse bil"), + L_KOMMUNAL_OMSORGSLØNN_OG_FOSTERHJEMSGODTGJØRELSE("Kommunal omsorgslønn og fosterhjemsgodtgjørelse"), + L_KOST_DAGER("Kost (dager)"), + L_KOST_DØGN("Kost (døgn)"), + L_KOSTBESPARELSE_I_HJEMMET("Kostbesparelse i hjemmet"), + L_LØNN_FOR_BARNEPASS_I_BARNETS_HJEM("Lønn og godtgjørelse til dagmamma eller praktikant som passer barn i barnets hjem"), + L_LØNN_TIL_PRIVATPERSONER_FOR_ARBEID_I_HJEMMET("Lønn og godtgjørelse til privatpersoner for arbeidsoppdrag i oppdragsgivers hjem"), + L_LØNN_TIL_VERGE_FRA_FYLKESMANNEN("Lønn til verge fra Fylkesmannen"), + L_LØNN_TIL_VERGE_FRA_STATSFORVALTEREN("Lønn til verge fra Statsforvalteren"), + L_LØNN_UTBETALT_AV_VELDEDIG_ELLER_ALLMENNYTTIG_INSTITUSJON_ELLER_ORGANISASJON( + "Lønn og godtgjørelse utbetalt av veldedig eller allmennyttig institusjon eller organisasjon", + ), + L_LOSJI("Losji"), + L_OPSJONER("Opsjoner"), + L_OVERTIDSGODTGJØRELSE("Overtidsgodtgjørelse"), + L_OVERTIDSGODTGJØRELSE_H("Hyre - Overtidsgodtgjørelse"), + L_OVERTIDSGODTGJØRELSE_T("Tiltak - Overtidsgodtgjørelse"), + L_REISE_ANNET("Reise annet"), + L_REISE_KOST("Reise kost"), + L_REISE_LOSJI("Reise losji"), + L_RENTEFORDEL_LÅN("Rentefordel lån"), + L_SKATTEPLIKTIG_DEL_FORSIKRINGER("Skattepliktig del av visse typer forsikringer"), + L_SKATTEPLIKTIG_PERSONALRABATT("Skattepliktig personalrabatt"), + L_SKATTEPLIKTIG_GODTGJOERELSE_SAERAVTALE_UTLAND("Skattepliktig godtgjørelse særavtale utland"), + L_SLUTTVEDERLAG(" Sluttvederlag"), + L_SLUTTVEDERLAG_H("Hyre - Sluttvederlag"), + L_SLUTTVEDERLAG_T("Tiltak - Sluttvederlag"), + L_SMUSSTILLEGG("Smusstillegg"), + L_STIPEND("Stipend"), + L_STYREHONORAR_OG_GODTGJØRELSE_VERV("Styrehonorar og godtgjørelse i forbindelse med verv"), + L_TIMELØNN("Timelønn"), + L_TIMELØNN_H("Hyre - Timelønn"), + L_TIMELØNN_T("Tiltak - Timelønn"), + L_TIPS("Tips"), + L_TREKK_I_LØNN_FOR_FERIE("Trekk i lønn for ferie"), + L_TREKK_I_LØNN_FOR_FERIE_H("Trekk i lønn for ferie - Hyre"), + L_TREKK_I_LØNN_FOR_FERIE_T("Trekk i lønn for ferie - Tiltak"), + L_UREGELMESSIGE_TILLEGG_KNYTTET_TIL_ARBEIDET_TID("Uregelmessige tillegg knyttet til arbeidet tid"), + L_UREGELMESSIGE_TILLEGG_KNYTTET_TIL_ARBEIDET_TID_H("Hyre - Uregelmessige tillegg knyttet til arbeidet tid"), + L_UREGELMESSIGE_TILLEGG_KNYTTET_TIL_ARBEIDET_TID_T("Tiltak - Uregelmessige tillegg knyttet til arbeidet tid"), + L_UREGELMESSIGE_TILLEGG_KNYTTET_TIL_IKKE_ARBEIDET_TID("Uregelmessige tillegg knyttet til ikke-arbeidet tid"), + L_UREGELMESSIGE_TILLEGG_KNYTTET_TIL_IKKE_ARBEIDET_TID_H("Hyre - Uregelmessige tillegg knyttet til ikke-arbeidet tid"), + L_UREGELMESSIGE_TILLEGG_KNYTTET_TIL_IKKE_ARBEIDET_TID_T("Tiltak - Uregelmessige tillegg knyttet til ikke-arbeidet tid"), + L_YRKEBIL_TJENESTLIGBEHOV_KILOMETER("Yrkebil tjenestligbehov kilometer"), + L_YRKEBIL_TJENESTLIGBEHOV_LISTEPRIS("Yrkebil tjenestligbehov listepris"), + N_DAGPENGER_TIL_FISKER("Dagpenger til fisker"), + N_LOTT_KUN_TRYGDEAVGIFT("Lott det skal beregnes trygdeavgift av"), + N_SYKEPENGER_TIL_FISKER("Sykepenger til fisker"), + N_VEDERLAG("Vederlag lott"), + Y_DAGPENGER_TIL_FISKER_SOM_BARE_HAR_HYRE("Dagpenger til fisker som bare har hyre"), + Y_DAGPENGER_TIL_FISKER_SOM_BARE_HAR_HYRE_FERIETILLEGG("Ferietillegg for dagpenger til fisker som bare har hyre"), + Y_DAGPENGER_VED_ARBEIDSLØSHET("Dagpenger ved arbeidsløshet"), + Y_DAGPENGER_VED_ARBEIDSLØSHET_FERIETILLEGG("Ferietillegg for dagpenger ved arbeidsløshet"), + Y_FORELDREPENGER("Foreldrepenger fra folketrygden"), + Y_FORELDREPENGER_FERIEPENGER("Feriepenger av foreldrepenger fra folketrygden"), + Y_SVANGERSKAPSPENGER("Svangerskapspenger"), + Y_SVANGERSKAPSPENGER_FERIEPENGER("Feriepenger av svangerskapspenger"), + Y_SYKEPENGER("Sykepenger fra folketrygden"), + Y_SYKEPENGER_FERIEPENGER("Feriepenger av sykepenger fra folketrygden"), + Y_SYKEPENGER_TIL_FISKER_SOM_BARE_HAR_HYRE("Sykepenger til fisker som bare har hyre"), + Y_SYKEPENGER_TIL_FISKER_SOM_BARE_HAR_HYRE_FERIEPENGER("Feriepenger av sykepenger til fisker som bare har hyre"), + Y_PLEIEPENGER("Pleiepenger fra folketrygden"), + Y_PLEIEPENGER_FERIEPENGER("Feriepenger av pleiepenger fra folketrygden"), + Y_OMSORGSPENGER("Omsorgspenger fra folketrygden"), + Y_OMSORGSPENGER_FERIEPENGER("Feriepenger av omsorgspenger fra folketrygden"), + Y_OPPLÆRINGSPENGER("Opplæringspenger fra folketrygden"), + Y_OPPLÆRINGSPENGER_FERIEPENGER("Feriepenger av opplæringspenger fra folketrygden"), +} diff --git a/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/SpesifisertInntekt.kt b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/SpesifisertInntekt.kt new file mode 100644 index 00000000..0658090d --- /dev/null +++ b/dp-inntekt-kontrakter/src/main/kotlin/no/nav/dagpenger/inntekt/v1/SpesifisertInntekt.kt @@ -0,0 +1,75 @@ +package no.nav.dagpenger.inntekt.v1 + +import de.huxhorn.sulky.ulid.ULID +import java.math.BigDecimal +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.YearMonth + +data class SpesifisertInntekt( + val inntektId: InntektId, + val avvik: List, + val posteringer: List, + val sisteAvsluttendeKalenderMåned: YearMonth, + val ident: Aktør, + val manueltRedigert: Boolean, + val timestamp: LocalDateTime, +) + +data class Avvik( + val ident: Aktør, + val opplysningspliktig: Aktør, + val virksomhet: Aktør? = null, + val avvikPeriode: YearMonth, + val tekst: String, +) + +data class Postering( + val posteringsMåned: YearMonth, + val beløp: BigDecimal, + val fordel: String, + val inntektskilde: String, + val inntektsstatus: String, + val inntektsperiodetype: String, + val leveringstidspunkt: YearMonth? = null, + val opptjeningsland: String? = null, + val opptjeningsperiode: Periode? = null, + val skattemessigBosattLand: String? = null, + val utbetaltIMåned: YearMonth, + val opplysningspliktig: Aktør? = null, + val inntektsinnsender: Aktør? = null, + val virksomhet: Aktør? = null, + val inntektsmottaker: Aktør? = null, + val inngårIGrunnlagForTrekk: Boolean? = null, + val utløserArbeidsgiveravgift: Boolean? = null, + val informasjonsstatus: String? = null, + val posteringsType: PosteringsType, +) + +data class InntektId(val id: String) { + init { + try { + ULID.parseULID(id) + } catch (e: IllegalArgumentException) { + throw IllegalInntektIdException("ID $id is not a valid ULID", e) + } + } +} + +data class Periode( + val startDato: LocalDate, + val sluttDato: LocalDate, +) + +data class Aktør( + val aktørType: AktørType, + val identifikator: String, +) + +enum class AktørType { + AKTOER_ID, + NATURLIG_IDENT, + ORGANISASJON, +} + +class IllegalInntektIdException(override val message: String, override val cause: Throwable?) : java.lang.RuntimeException(message, cause) diff --git a/dp-inntekt-kontrakter/src/test/kotlin/no/nav/dagpenger/inntekt/v1/InntektTest.kt b/dp-inntekt-kontrakter/src/test/kotlin/no/nav/dagpenger/inntekt/v1/InntektTest.kt new file mode 100644 index 00000000..a4a9245c --- /dev/null +++ b/dp-inntekt-kontrakter/src/test/kotlin/no/nav/dagpenger/inntekt/v1/InntektTest.kt @@ -0,0 +1,229 @@ +package no.nav.dagpenger.inntekt.v1 + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.math.BigDecimal +import java.time.YearMonth + +class InntektTest { + private val sisteAvsluttendeKalenderMåned = YearMonth.of(2019, 3) + + val testInntektsListe = + (0..38).toList().map { + KlassifisertInntektMåned( + sisteAvsluttendeKalenderMåned.minusMonths(it.toLong()), + listOf( + KlassifisertInntekt( + BigDecimal(1000), + InntektKlasse.ARBEIDSINNTEKT, + ), + KlassifisertInntekt( + BigDecimal(2000), + InntektKlasse.DAGPENGER_FANGST_FISKE, + ), + ), + ) + } + + val testInntekt = Inntekt("id", testInntektsListe, sisteAvsluttendeKalenderMåned = sisteAvsluttendeKalenderMåned) + + @Test + fun `filtering period of last three months affects sum of inntekt`() { + val filteredInntekt = + testInntekt.filterPeriod( + sisteAvsluttendeKalenderMåned.minusMonths(2), + sisteAvsluttendeKalenderMåned.minusMonths(0), + ) + assertEquals( + BigDecimal(9000), + filteredInntekt.splitIntoInntektsPerioder().first.sumInntekt(listOf(InntektKlasse.ARBEIDSINNTEKT)), + ) + assertEquals( + BigDecimal(33000), + filteredInntekt.splitIntoInntektsPerioder().all().sumInntekt(listOf(InntektKlasse.ARBEIDSINNTEKT)), + ) + } + + @Test + fun `filtering period not overlapping exisiting months does not affect sum `() { + val filteredInntekt = + testInntekt.filterPeriod( + sisteAvsluttendeKalenderMåned.minusMonths(48), + sisteAvsluttendeKalenderMåned.minusMonths(37), + ) + assertEquals( + testInntekt.splitIntoInntektsPerioder().first.sumInntekt(listOf(InntektKlasse.ARBEIDSINNTEKT)), + filteredInntekt.splitIntoInntektsPerioder().first.sumInntekt(listOf(InntektKlasse.ARBEIDSINNTEKT)), + ) + assertEquals( + testInntekt.splitIntoInntektsPerioder().all().sumInntekt(listOf(InntektKlasse.ARBEIDSINNTEKT)), + filteredInntekt.splitIntoInntektsPerioder().all().sumInntekt(listOf(InntektKlasse.ARBEIDSINNTEKT)), + ) + } + + @Test + fun `filter period throws exception if from-argument is more recent than to`() { + assertThrows { + testInntekt.filterPeriod( + YearMonth.of(2019, 5), + YearMonth.of(2019, 4), + ) + } + } + + @Test + fun `inntektsPerioder splits up inntekt correctly`() { + val inntekt = + Inntekt( + "id", + inntektsListe = + (0..36).toList().map { + KlassifisertInntektMåned( + sisteAvsluttendeKalenderMåned.minusMonths(it.toLong()), + listOf( + KlassifisertInntekt( + BigDecimal(1000), + InntektKlasse.ARBEIDSINNTEKT, + ), + ), + ) + }, + sisteAvsluttendeKalenderMåned = sisteAvsluttendeKalenderMåned, + ) + + val (first, second, third) = inntekt.splitIntoInntektsPerioder() + + assertEquals(12, first.size) + assertEquals(12, second.size) + assertEquals(12, third.size) + + assertTrue(first.all { it.årMåned in YearMonth.of(2018, 4)..YearMonth.of(2019, 3) }) + assertEquals(YearMonth.of(2019, 3), first.last().årMåned) + assertEquals(YearMonth.of(2018, 4), first.first().årMåned) + + assertTrue(second.all { it.årMåned in YearMonth.of(2017, 4)..YearMonth.of(2018, 3) }) + assertEquals(YearMonth.of(2018, 3), second.last().årMåned) + assertEquals(YearMonth.of(2017, 4), second.first().årMåned) + + assertTrue(third.all { it.årMåned in YearMonth.of(2016, 4)..YearMonth.of(2017, 3) }) + assertEquals(YearMonth.of(2017, 3), third.last().årMåned) + assertEquals(YearMonth.of(2016, 4), third.first().årMåned) + } + + @Test + fun `inntektsPerioder correctly splits up inntekt for only last year`() { + val senesteMåned = YearMonth.of(2019, 3) + val onlyInntektLastYear = + Inntekt( + "id", + inntektsListe = + (0..11).toList().map { + KlassifisertInntektMåned( + senesteMåned.minusMonths(it.toLong()), + listOf(KlassifisertInntekt(BigDecimal(1000), InntektKlasse.ARBEIDSINNTEKT)), + ) + }, + sisteAvsluttendeKalenderMåned = senesteMåned, + ) + val (first, second, third) = onlyInntektLastYear.splitIntoInntektsPerioder() + + assertEquals(12, first.size) + assertEquals(12, second.size) + assertEquals(12, third.size) + + assertTrue(first.all { it.årMåned in YearMonth.of(2018, 4)..YearMonth.of(2019, 3) }) + assertEquals(YearMonth.of(2019, 3), first.last().årMåned) + assertEquals(YearMonth.of(2018, 4), first.first().årMåned) + + assertTrue(second.all { it.årMåned in YearMonth.of(2017, 4)..YearMonth.of(2018, 3) }) + assertEquals(YearMonth.of(2018, 3), second.last().årMåned) + assertEquals(YearMonth.of(2017, 4), second.first().årMåned) + + assertTrue(third.all { it.årMåned in YearMonth.of(2016, 4)..YearMonth.of(2017, 3) }) + assertEquals(YearMonth.of(2017, 3), third.last().årMåned) + assertEquals(YearMonth.of(2016, 4), third.first().årMåned) + + assertTrue(first.all { it.klassifiserteInntekter.isNotEmpty() }) + assertTrue(second.all { it.klassifiserteInntekter.isEmpty() }) + assertTrue(third.all { it.klassifiserteInntekter.isEmpty() }) + } + + @Test + fun `inntektsPerioder correctly splits up inntekt missing earliest year`() { + val senesteMåned = YearMonth.of(2019, 3) + val noInntektThirdPeriod = + Inntekt( + "id", + inntektsListe = + (0..23).toList().map { + KlassifisertInntektMåned( + senesteMåned.minusMonths(it.toLong()), + listOf(KlassifisertInntekt(BigDecimal(1000), InntektKlasse.ARBEIDSINNTEKT)), + ) + }, + sisteAvsluttendeKalenderMåned = senesteMåned, + ) + + val (first, second, third) = noInntektThirdPeriod.splitIntoInntektsPerioder() + + assertEquals(12, first.size) + assertEquals(12, second.size) + assertEquals(12, third.size) + + assertTrue(first.all { it.årMåned in YearMonth.of(2018, 4)..YearMonth.of(2019, 3) }) + assertEquals(YearMonth.of(2019, 3), first.last().årMåned) + assertEquals(YearMonth.of(2018, 4), first.first().årMåned) + + assertTrue(second.all { it.årMåned in YearMonth.of(2017, 4)..YearMonth.of(2018, 3) }) + assertEquals(YearMonth.of(2018, 3), second.last().årMåned) + assertEquals(YearMonth.of(2017, 4), second.first().årMåned) + + assertTrue(third.all { it.årMåned in YearMonth.of(2016, 4)..YearMonth.of(2017, 3) }) + assertEquals(YearMonth.of(2017, 3), third.last().årMåned) + assertEquals(YearMonth.of(2016, 4), third.first().årMåned) + + assertTrue(first.all { it.klassifiserteInntekter.isNotEmpty() }) + assertTrue(second.all { it.klassifiserteInntekter.isNotEmpty() }) + assertTrue(third.all { it.klassifiserteInntekter.isEmpty() }) + } + + @Test + fun `inntektsPerioder correctly splits up noncontinous inntekt`() { + val nonContinous = + Inntekt( + "id", + inntektsListe = + ((0..5).toList() + (10..24).toList()).map { + KlassifisertInntektMåned( + sisteAvsluttendeKalenderMåned.minusMonths(it.toLong()), + listOf(KlassifisertInntekt(BigDecimal(1000), InntektKlasse.ARBEIDSINNTEKT)), + ) + }, + sisteAvsluttendeKalenderMåned = sisteAvsluttendeKalenderMåned, + ) + + val (first, second, third) = nonContinous.splitIntoInntektsPerioder() + + assertEquals(12, first.size) + assertEquals(12, second.size) + assertEquals(12, third.size) + + assertTrue(first.all { it.årMåned in YearMonth.of(2018, 4)..YearMonth.of(2019, 3) }) + assertEquals(YearMonth.of(2019, 3), first.last().årMåned) + assertEquals(YearMonth.of(2018, 4), first.first().årMåned) + + assertTrue(second.all { it.årMåned in YearMonth.of(2017, 4)..YearMonth.of(2018, 3) }) + assertEquals(YearMonth.of(2018, 3), second.last().årMåned) + assertEquals(YearMonth.of(2017, 4), second.first().årMåned) + + assertTrue(third.all { it.årMåned in YearMonth.of(2016, 4)..YearMonth.of(2017, 3) }) + assertEquals(YearMonth.of(2017, 3), third.last().årMåned) + assertEquals(YearMonth.of(2016, 4), third.first().årMåned) + + assertEquals(8, first.filter { it.klassifiserteInntekter.isNotEmpty() }.size) + assertEquals(12, second.filter { it.klassifiserteInntekter.isNotEmpty() }.size) + assertEquals(1, third.filter { it.klassifiserteInntekter.isNotEmpty() }.size) + } +} diff --git "a/dp-inntekt-kontrakter/src/test/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntektM\303\245nedTest.kt" "b/dp-inntekt-kontrakter/src/test/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntektM\303\245nedTest.kt" new file mode 100644 index 00000000..811c9b3a --- /dev/null +++ "b/dp-inntekt-kontrakter/src/test/kotlin/no/nav/dagpenger/inntekt/v1/KlassifisertInntektM\303\245nedTest.kt" @@ -0,0 +1,118 @@ +package no.nav.dagpenger.inntekt.v1 + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.math.BigDecimal +import java.time.YearMonth + +class KlassifisertInntektMånedTest { + val senesteMåned = YearMonth.of(2019, 3) + + val testInntektsListe = + (0..38).toList().map { + KlassifisertInntektMåned( + senesteMåned.minusMonths(it.toLong()), + listOf( + KlassifisertInntekt( + BigDecimal(1000), + InntektKlasse.ARBEIDSINNTEKT, + ), + KlassifisertInntekt( + BigDecimal(2000), + InntektKlasse.DAGPENGER_FANGST_FISKE, + ), + ), + ) + } + + val testInntekt = Inntekt("id", testInntektsListe, sisteAvsluttendeKalenderMåned = senesteMåned) + + @Test + fun `sum with empty list of inntektsklasserToSum returns 0`() { + assertEquals(BigDecimal(0), testInntektsListe.sumInntekt(emptyList())) + } + + @Test + fun `empty inntekt returns 0`() { + assertEquals(BigDecimal(0), emptyList().sumInntekt(InntektKlasse.values().toList())) + } + + @Test + fun ` should sum arbeidsinntekt correctly`() { + assertEquals( + BigDecimal(12000), + testInntekt.splitIntoInntektsPerioder().first.sumInntekt(listOf(InntektKlasse.ARBEIDSINNTEKT)), + ) + + assertEquals( + BigDecimal(36000), + testInntekt.splitIntoInntektsPerioder().all().sumInntekt(listOf(InntektKlasse.ARBEIDSINNTEKT)), + ) + } + + @Test + fun ` should sum dp fangst fiske correctly `() { + assertEquals( + BigDecimal(24000), + testInntekt.splitIntoInntektsPerioder().first.sumInntekt(listOf(InntektKlasse.DAGPENGER_FANGST_FISKE)), + ) + + assertEquals( + BigDecimal(72000), + testInntekt.splitIntoInntektsPerioder().all().sumInntekt(listOf(InntektKlasse.DAGPENGER_FANGST_FISKE)), + ) + } + + @Test + fun ` should sum multiple inntektsklasser`() { + assertEquals( + BigDecimal(36000), + testInntekt.splitIntoInntektsPerioder().first.sumInntekt( + listOf( + InntektKlasse.DAGPENGER_FANGST_FISKE, + InntektKlasse.ARBEIDSINNTEKT, + ), + ), + ) + + assertEquals( + BigDecimal(108000), + testInntekt.splitIntoInntektsPerioder().all().sumInntekt( + listOf( + InntektKlasse.DAGPENGER_FANGST_FISKE, + InntektKlasse.ARBEIDSINNTEKT, + ), + ), + ) + } + + @Test + fun ` should return 0 when no inntekt matches `() { + assertEquals( + BigDecimal(0), + testInntektsListe.sumInntekt(listOf(InntektKlasse.SYKEPENGER)), + ) + } + + @Test + fun `all combines three inntektsperioder correctly`() { + assertEquals( + emptyList(), + Triple( + emptyList(), + emptyList(), + emptyList(), + ).all(), + ) + + val first = (1..5).toList().map { KlassifisertInntektMåned(senesteMåned, emptyList()) } + val second = (1..7).toList().map { KlassifisertInntektMåned(senesteMåned.minusMonths(2), emptyList()) } + val third = listOf(KlassifisertInntektMåned(senesteMåned.plusMonths(1), emptyList())) + val all = Triple(first, second, third).all() + + assertEquals(13, all.size) + assertEquals(5, all.filter { it.årMåned == senesteMåned }.size) + assertEquals(7, all.filter { it.årMåned == senesteMåned.minusMonths(2) }.size) + assertEquals(1, all.filter { it.årMåned == senesteMåned.plusMonths(1) }.size) + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index cbb94fe6..f6a9e90e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,6 @@ +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" +} /* * This file was generated by the Gradle 'init' task. * @@ -8,7 +11,7 @@ */ rootProject.name = "dp-inntekt" -include("dp-inntekt-api") +include("dp-inntekt-api", "dp-inntekt-kontrakter") dependencyResolutionManagement { repositories {