Skip to content

Commit bd69c67

Browse files
vskjefstJMLindseth
andcommitted
Lagre inntekt (WiP, squash før merge)
Co-authored-by: John Martin Lindseth <[email protected]>
1 parent f70eae5 commit bd69c67

File tree

5 files changed

+290
-91
lines changed

5 files changed

+290
-91
lines changed

dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/mapping/MapToInntektFrontend.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import java.time.YearMonth
1313

1414
fun InntektkomponentResponse.mapToFrontend(
1515
person: Inntektsmottaker,
16-
organisasjonsInfoListe: MutableList<OrganisasjonNavnOgIdMapping>,
16+
organisasjonsInfoListe: List<OrganisasjonNavnOgIdMapping>,
1717
): InntekterDto {
1818
val inntekt = arbeidsInntektMaaned
1919
val virksomheter: MutableList<Virksomhet> = mutableListOf()

dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/v1/UklassifisertInntektRoute.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import no.nav.dagpenger.inntekt.opptjeningsperiode.Opptjeningsperiode
4343
import no.nav.dagpenger.inntekt.v1.models.InntekterDto
4444
import no.nav.dagpenger.inntekt.v1.models.mapToStoredInntekt
4545
import java.time.LocalDate
46+
import kotlin.coroutines.CoroutineContext
4647

4748
private val logger = KotlinLogging.logger {}
4849
const val INNTEKT_KORRIGERING = "inntekt_korrigering"
@@ -72,11 +73,12 @@ fun Route.uklassifisertInntekt(
7273
inntektStore: InntektStore,
7374
personOppslag: PersonOppslag,
7475
enhetsregisterClient: EnhetsregisterClient,
76+
coroutineContext: CoroutineContext = Dispatchers.IO,
7577
) {
7678
authenticate("azure") {
7779
route("/uklassifisert/{aktørId}/{kontekstType}/{kontekstId}/{beregningsDato}") {
7880
get {
79-
withContext(Dispatchers.IO) {
81+
withContext(coroutineContext) {
8082
call.withInntektRequest("GET /uklassifisert/") {
8183
val person = personOppslag.hentPerson(this.aktørId)
8284
inntektStore
@@ -99,7 +101,7 @@ fun Route.uklassifisertInntekt(
99101
}
100102
}
101103
post {
102-
withContext(Dispatchers.IO) {
104+
withContext(coroutineContext) {
103105
call.withInntektRequest("POST /uklassifisert/") {
104106
val person = personOppslag.hentPerson(this.aktørId)
105107
val guiInntekt = call.receive<GUIInntekt>()
@@ -141,7 +143,7 @@ fun Route.uklassifisertInntekt(
141143

142144
route("/uklassifisert/{inntektId}") {
143145
get {
144-
withContext(Dispatchers.IO) {
146+
withContext(coroutineContext) {
145147
val inntektId = InntektId(call.parameters["inntektId"]!!)
146148
inntektStore
147149
.getInntektMedPersonFnr(inntektId)
@@ -167,7 +169,7 @@ fun Route.uklassifisertInntekt(
167169
}
168170
}
169171
post {
170-
withContext(Dispatchers.IO) {
172+
withContext(coroutineContext) {
171173
val inntektId = call.parameters["inntektId"]!!
172174
call
173175
.receive<InntekterDto>()
@@ -208,7 +210,7 @@ fun Route.uklassifisertInntekt(
208210
route("/uklassifisert/uncached/{aktørId}/{kontekstType}/{kontekstId}/{beregningsDato}") {
209211
get {
210212
val callId = call.callId
211-
withContext(Dispatchers.IO) {
213+
withContext(coroutineContext) {
212214
call.withInntektRequest("GET /uklassifisert/uncached/") {
213215
val person = personOppslag.hentPerson(this.aktørId)
214216
val opptjeningsperiode = Opptjeningsperiode(this.beregningsDato)
@@ -231,7 +233,7 @@ fun Route.uklassifisertInntekt(
231233
}
232234

233235
post {
234-
withContext(Dispatchers.IO) {
236+
withContext(coroutineContext) {
235237
call.withInntektRequest("POST /uklassifisert/uncached/") {
236238
val guiInntekt = call.receive<GUIInntekt>()
237239
val person = personOppslag.hentPerson(this.aktørId)
@@ -273,9 +275,7 @@ fun Route.uklassifisertInntekt(
273275
}
274276
route("/verdikoder") {
275277
get {
276-
withContext(Dispatchers.IO) {
277-
call.respond(HttpStatusCode.OK, dataGrunnlagKlassifiseringToVerdikode.values)
278-
}
278+
call.respond(HttpStatusCode.OK, dataGrunnlagKlassifiseringToVerdikode.values)
279279
}
280280
}
281281
}

dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/v1/models/InntekterDto.kt

Lines changed: 39 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ package no.nav.dagpenger.inntekt.v1.models
33
import no.nav.dagpenger.inntekt.db.InntektId
44
import no.nav.dagpenger.inntekt.db.StoredInntekt
55
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Aktoer
6-
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.AktoerType
6+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.AktoerType.NATURLIG_IDENT
77
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.ArbeidsInntektInformasjon
88
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.ArbeidsInntektMaaned
99
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Inntekt
1010
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektkomponentResponse
1111
import no.nav.dagpenger.inntekt.mapping.Inntektsmottaker
1212
import no.nav.dagpenger.inntekt.mapping.Virksomhet
1313
import java.time.LocalDateTime.now
14+
import java.time.YearMonth
1415

1516
data class InntekterDto(
1617
val virksomheter: List<Virksomhet>,
@@ -26,69 +27,46 @@ fun InntekterDto.mapToStoredInntekt(inntektId: String): StoredInntekt =
2627
)
2728

2829
private fun mapToInntektkomponentResponse(inntekterDto: InntekterDto): InntektkomponentResponse {
29-
val arbeidsInntektMaaneder: MutableList<ArbeidsInntektMaaned> = mutableListOf()
30-
31-
/*
32-
Dette må mappes om fra gruppering på virksomhet, til gruppering på aarMaaned (dvs hvert aarMaaned inneholder
33-
inntekt for alle virksomhetene som har utbetalt inntekt for gitt aarMaaned). Strukturen som kommer fra frontend er
34-
gruppert på virksomhet, og alle utbetalte inntekter for alle aarMaaned ligger inne i hver virksomhet.
35-
36-
Vi mistenker også at Avvik i datastrukturen som sendes til frontend (og som frontend da sender tilbake til backend),
37-
ikke inneholder all informasjon og/eller ligger på feil sted i strukturen.
38-
39-
Løsningsforslag:
40-
41-
Lag en Map<YearMonth, List<Inntekt>>(), og map InntektMaaned-objekter til Inntekt-objekter, og legg i riktig
42-
"bucket" i mappen -> opprett et ArbeidsInntektMaaned-objekt per key i map (key == maanedAar,
43-
liste i value == arbeidsInntektInformasjon.
44-
45-
Hvis vi blir skikkelig tøffe: https://kotlinlang.org/docs/collection-grouping.html
46-
47-
I tillegg må vi se på mapping av avvik når vi har fått det på riktig plass i InntektDto.
48-
*/
49-
30+
val inntektPerÅrOgMåned = mutableMapOf<YearMonth, MutableList<Inntekt>>()
5031
inntekterDto.virksomheter.forEach { virksomhet ->
51-
arbeidsInntektMaaneder.addAll(
52-
virksomhet.inntekter?.map {
53-
ArbeidsInntektMaaned(
54-
it.aarMaaned,
55-
virksomhet.avvikListe,
56-
ArbeidsInntektInformasjon(
57-
virksomhet.inntekter.map { inntektMaaned ->
58-
Inntekt(
59-
inntektMaaned.belop,
60-
inntektMaaned.inntektskilde,
61-
inntektMaaned.beskrivelse,
62-
inntektMaaned.inntektskilde,
63-
inntektMaaned.inntektsstatus,
64-
inntektMaaned.inntektsperiodetype ?: "Maaned",
65-
inntektMaaned.leveringstidspunkt,
66-
inntektMaaned.opptjeningsland,
67-
inntektMaaned.opptjeningsperiode,
68-
inntektMaaned.skattemessigBosattLand,
69-
inntektMaaned.utbetaltIMaaned,
70-
inntektMaaned.opplysningspliktig,
71-
inntektMaaned.inntektsinnsender,
72-
inntektMaaned.virksomhet,
73-
inntektMaaned.inntektsmottaker,
74-
inntektMaaned.inngaarIGrunnlagForTrekk,
75-
inntektMaaned.utloeserArbeidsgiveravgift,
76-
inntektMaaned.informasjonsstatus,
77-
inntektMaaned.inntektType,
78-
inntektMaaned.tilleggsinformasjon,
79-
)
80-
},
81-
),
82-
)
83-
} ?: listOf(),
84-
)
32+
virksomhet.inntekter?.map { inntektMaaned ->
33+
val inntekter = inntektPerÅrOgMåned[inntektMaaned.aarMaaned] ?: mutableListOf()
34+
inntekter.add(
35+
Inntekt(
36+
inntektMaaned.belop,
37+
inntektMaaned.fordel,
38+
inntektMaaned.beskrivelse,
39+
inntektMaaned.inntektskilde,
40+
inntektMaaned.inntektsstatus,
41+
inntektMaaned.inntektsperiodetype ?: "Maaned",
42+
inntektMaaned.leveringstidspunkt,
43+
inntektMaaned.opptjeningsland,
44+
inntektMaaned.opptjeningsperiode,
45+
inntektMaaned.skattemessigBosattLand,
46+
inntektMaaned.utbetaltIMaaned,
47+
inntektMaaned.opplysningspliktig,
48+
inntektMaaned.inntektsinnsender,
49+
inntektMaaned.virksomhet,
50+
inntektMaaned.inntektsmottaker,
51+
inntektMaaned.inngaarIGrunnlagForTrekk,
52+
inntektMaaned.utloeserArbeidsgiveravgift,
53+
inntektMaaned.informasjonsstatus,
54+
inntektMaaned.inntektType,
55+
inntektMaaned.tilleggsinformasjon,
56+
),
57+
)
58+
inntektPerÅrOgMåned.put(inntektMaaned.aarMaaned, inntekter)
59+
}
8560
}
8661

8762
return InntektkomponentResponse(
88-
arbeidsInntektMaaneder,
89-
mapToAktoerNaturligIdent(inntekterDto.mottaker.pnr),
63+
inntektPerÅrOgMåned.map { (yearMonth, inntekter) ->
64+
ArbeidsInntektMaaned(
65+
yearMonth,
66+
listOf(),
67+
ArbeidsInntektInformasjon(inntekter),
68+
)
69+
},
70+
Aktoer(NATURLIG_IDENT, inntekterDto.mottaker.pnr ?: throw IllegalArgumentException("Fødselsenummer mangler")),
9071
)
9172
}
92-
93-
private fun mapToAktoerNaturligIdent(fnr: String?): Aktoer =
94-
Aktoer(AktoerType.NATURLIG_IDENT, fnr ?: throw IllegalArgumentException("Fødselsenummer mangler"))

dp-inntekt-api/src/test/kotlin/no/nav/dagpenger/inntekt/v1/models/InntekterDtoTest.kt

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,25 @@ package no.nav.dagpenger.inntekt.v1.models
33
import com.fasterxml.jackson.module.kotlin.readValue
44
import de.huxhorn.sulky.ulid.ULID
55
import io.kotest.matchers.collections.shouldBeEmpty
6+
import io.kotest.matchers.collections.shouldContain
67
import io.kotest.matchers.collections.shouldHaveSize
78
import io.kotest.matchers.nulls.shouldNotBeNull
89
import io.kotest.matchers.shouldBe
10+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Aktoer
11+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.AktoerType.AKTOER_ID
912
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.AktoerType.NATURLIG_IDENT
13+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.AktoerType.ORGANISASJON
14+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Inntekt
15+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektBeskrivelse.BIL
16+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektType.LOENNSINNTEKT
17+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Periode
18+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.SpesielleInntjeningsforhold.LOENN_VED_KONKURS_ELLER_STATSGARANTI_OSV
19+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.TilleggInformasjon
20+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.TilleggInformasjonsDetaljer
1021
import no.nav.dagpenger.inntekt.serder.jacksonObjectMapper
1122
import org.junit.jupiter.api.Test
23+
import java.math.BigDecimal
24+
import java.time.LocalDate
1225
import java.time.YearMonth
1326

1427
class InntekterDtoTest {
@@ -20,25 +33,68 @@ class InntekterDtoTest {
2033
this::class.java.getResource("/test-data/expected-uklassifisert-post-body.json")?.readText()!!,
2134
)
2235

23-
val storedInntekt =
24-
inntekterDto.mapToStoredInntekt(
25-
inntektId = inntektId,
26-
)
36+
val storedInntekt = inntekterDto.mapToStoredInntekt(inntektId = inntektId)
2737

2838
storedInntekt.manueltRedigert shouldBe true
2939
storedInntekt.timestamp.shouldNotBeNull()
3040
storedInntekt.inntektId.id shouldBe inntektId
3141
storedInntekt.inntekt.ident.aktoerType shouldBe NATURLIG_IDENT
3242
storedInntekt.inntekt.ident.identifikator shouldBe inntekterDto.mottaker.pnr
33-
storedInntekt.inntekt.arbeidsInntektMaaned?.shouldHaveSize(2)
43+
storedInntekt.inntekt.arbeidsInntektMaaned?.shouldHaveSize(4)
3444
storedInntekt.inntekt.arbeidsInntektMaaned?.first().let {
3545
it?.aarMaaned shouldBe YearMonth.of(2023, 1)
3646
it?.avvikListe.shouldBeEmpty()
37-
it?.arbeidsInntektInformasjon?.inntektListe?.shouldHaveSize(2)
47+
it?.arbeidsInntektInformasjon?.inntektListe?.shouldHaveSize(1)
48+
it?.arbeidsInntektInformasjon?.inntektListe?.shouldContain(
49+
Inntekt(
50+
beloep = BigDecimal("50000.00"),
51+
fordel = "kontantytelse",
52+
beskrivelse = BIL,
53+
inntektskilde = "A-ordningen",
54+
inntektsstatus = "LoependeInnrapportert",
55+
inntektsperiodetype = "Maaned",
56+
leveringstidspunkt = YearMonth.of(2023, 1),
57+
opptjeningsland = "NO",
58+
opptjeningsperiode = Periode(LocalDate.of(2023, 1, 4), LocalDate.of(2023, 1, 25)),
59+
skattemessigBosattLand = "NO",
60+
utbetaltIMaaned = YearMonth.of(2023, 2),
61+
opplysningspliktig = Aktoer(NATURLIG_IDENT, "06221841830"),
62+
inntektsinnsender = Aktoer(ORGANISASJON, "561235623"),
63+
virksomhet = Aktoer(ORGANISASJON, "123456789"),
64+
inntektsmottaker = Aktoer(AKTOER_ID, "287631"),
65+
inngaarIGrunnlagForTrekk = true,
66+
utloeserArbeidsgiveravgift = false,
67+
informasjonsstatus = "InngaarAlltid",
68+
inntektType = LOENNSINNTEKT,
69+
tilleggsinformasjon =
70+
TilleggInformasjon(
71+
kategori = "enKategori",
72+
tilleggsinformasjonDetaljer =
73+
TilleggInformasjonsDetaljer(
74+
detaljerType = "enDetaljerType",
75+
spesielleInntjeningsforhold = LOENN_VED_KONKURS_ELLER_STATSGARANTI_OSV,
76+
),
77+
),
78+
),
79+
)
3880
}
3981
storedInntekt.inntekt.arbeidsInntektMaaned?.get(1).let {
4082
it?.aarMaaned shouldBe YearMonth.of(2024, 1)
4183
it?.avvikListe.shouldBeEmpty()
84+
it?.arbeidsInntektInformasjon?.inntektListe?.shouldHaveSize(2)
85+
}
86+
storedInntekt.inntekt.arbeidsInntektMaaned?.get(2).let {
87+
it?.aarMaaned shouldBe YearMonth.of(2025, 2)
88+
it?.avvikListe.shouldBeEmpty()
89+
it?.arbeidsInntektInformasjon?.inntektListe?.shouldHaveSize(1)
90+
it?.arbeidsInntektInformasjon?.inntektListe?.first().let { inntekt ->
91+
inntekt?.tilleggsinformasjon shouldBe null
92+
}
93+
}
94+
storedInntekt.inntekt.arbeidsInntektMaaned?.get(3).let {
95+
it?.aarMaaned shouldBe YearMonth.of(2025, 3)
96+
it?.avvikListe.shouldBeEmpty()
97+
it?.arbeidsInntektInformasjon?.inntektListe?.shouldHaveSize(1)
4298
}
4399
}
44100
}

0 commit comments

Comments
 (0)