Skip to content

Commit 8df1321

Browse files
ArselanSultanivskjefstnattaphongklinjanJMLindseth
committed
Legg til nytt endepunkt for å hente inntektdata med inntektId
Dette endepunktet skal brukes av den nye frontenden som lages. Map om til et dto-objekt basert på liste av virksomheter, siden det passer bedre med sånn det skal se ut for saksbehandler. Co-authored-by: Arselan.Sultani <[email protected]> Co-authored-by: Vegard Skjefstad <[email protected]> Co-authored-by: Nattaphong Klinjan <[email protected]> Co-authored-by: John Martin Lindseth <[email protected]>
1 parent 761f189 commit 8df1321

File tree

13 files changed

+1016
-149
lines changed

13 files changed

+1016
-149
lines changed

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

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,28 @@ class BehandlingsInntektsGetter(
2222
suspend fun getKlassifisertInntekt(
2323
inntektparametre: Inntektparametre,
2424
callId: String? = null,
25-
): Inntekt {
26-
return klassifiserOgMapInntekt(getSpesifisertInntekt(inntektparametre, callId))
27-
}
25+
): Inntekt = klassifiserOgMapInntekt(getSpesifisertInntekt(inntektparametre, callId))
2826

29-
fun getKlassifisertInntekt(inntektId: InntektId): Inntekt {
30-
return klassifiserOgMapInntekt(inntektStore.getSpesifisertInntekt(inntektId))
31-
}
27+
fun getKlassifisertInntekt(inntektId: InntektId): Inntekt = klassifiserOgMapInntekt(inntektStore.getSpesifisertInntekt(inntektId))
3228

3329
suspend fun getSpesifisertInntekt(
3430
inntektparametre: Inntektparametre,
3531
callId: String? = null,
36-
): SpesifisertInntekt {
37-
return mapToSpesifisertInntekt(
32+
): SpesifisertInntekt =
33+
mapToSpesifisertInntekt(
3834
getBehandlingsInntekt(inntektparametre, callId),
3935
inntektparametre.opptjeningsperiode.sisteAvsluttendeKalenderMåned,
4036
)
41-
}
4237

4338
internal suspend fun getBehandlingsInntekt(
4439
inntektparametre: Inntektparametre,
4540
callId: String? = null,
46-
): StoredInntekt {
47-
return isInntektStored(inntektparametre)?.let {
41+
): StoredInntekt =
42+
isInntektStored(inntektparametre)?.let {
4843
LOGGER.info { "Henter stored inntekt: ${inntektparametre.toDebugString()}" }
4944
inntektStore.getInntekt(it)
5045
}
5146
?: fetchAndStoreInntekt(inntektparametre, callId)
52-
}
5347

5448
private suspend fun fetchAndStoreInntekt(
5549
inntektparametre: Inntektparametre,

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ internal fun Application.inntektApi(
107107
}
108108
exception<InntektskomponentenHttpClientException> { call, cause ->
109109
val statusCode =
110-
if (HttpStatusCode.fromValue(cause.status)
110+
if (HttpStatusCode
111+
.fromValue(cause.status)
111112
.isSuccess()
112113
) {
113114
HttpStatusCode.InternalServerError
@@ -218,7 +219,7 @@ internal fun Application.inntektApi(
218219
routing {
219220
route("/v1") {
220221
route("/inntekt") {
221-
uklassifisertInntekt(inntektskomponentHttpClient, inntektStore, personOppslag)
222+
uklassifisertInntekt(inntektskomponentHttpClient, inntektStore, personOppslag, enhetsregisterClient)
222223
}
223224
opptjeningsperiodeApi(inntektStore)
224225
enhetsregisteret(enhetsregisterClient)

dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/InntektStore.kt

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ interface InntektStore {
2626
fun getManueltRedigert(inntektId: InntektId): ManueltRedigert?
2727

2828
fun markerInntektBrukt(inntektId: InntektId): Int
29+
30+
fun getInntektMedPersonFnr(inntektId: InntektId): StoredInntektMedFnr
2931
}
3032

3133
data class Inntektparametre(
@@ -36,20 +38,23 @@ data class Inntektparametre(
3638
) {
3739
val opptjeningsperiode: Opptjeningsperiode = Opptjeningsperiode(beregningsdato)
3840

39-
fun toDebugString(): String {
40-
return "Inntektparametre(aktørId='$aktørId', beregningsdato=$beregningsdato, regelkontekst=$regelkontekst)"
41-
}
41+
fun toDebugString(): String = "Inntektparametre(aktørId='$aktørId', beregningsdato=$beregningsdato, regelkontekst=$regelkontekst)"
4242
}
4343

44-
data class RegelKontekst(val id: String, val type: String)
44+
data class RegelKontekst(
45+
val id: String,
46+
val type: String,
47+
)
4548

4649
data class StoreInntektCommand(
4750
val inntektparametre: Inntektparametre,
4851
val inntekt: InntektkomponentResponse,
4952
val manueltRedigert: ManueltRedigert? = null,
5053
)
5154

52-
data class ManueltRedigert(val redigertAv: String) {
55+
data class ManueltRedigert(
56+
val redigertAv: String,
57+
) {
5358
companion object {
5459
fun from(
5560
bool: Boolean,
@@ -68,9 +73,14 @@ data class StoredInntekt(
6873
val timestamp: LocalDateTime? = null,
6974
)
7075

71-
data class DetachedInntekt(val inntekt: InntektkomponentResponse, val manueltRedigert: Boolean)
76+
data class DetachedInntekt(
77+
val inntekt: InntektkomponentResponse,
78+
val manueltRedigert: Boolean,
79+
)
7280

73-
data class InntektId(val id: String) {
81+
data class InntektId(
82+
val id: String,
83+
) {
7484
init {
7585
try {
7686
ULID.parseULID(id)
@@ -80,9 +90,23 @@ data class InntektId(val id: String) {
8090
}
8191
}
8292

83-
class InntektNotFoundException(override val message: String) : RuntimeException(message)
93+
data class StoredInntektMedFnr(
94+
val inntektId: InntektId,
95+
val inntekt: InntektkomponentResponse,
96+
val manueltRedigert: Boolean,
97+
val timestamp: LocalDateTime? = null,
98+
valdselsnummer: String,
99+
)
100+
101+
class InntektNotFoundException(
102+
override val message: String,
103+
) : RuntimeException(message)
84104

85-
class StoreException(override val message: String) : RuntimeException(message)
105+
class StoreException(
106+
override val message: String,
107+
) : RuntimeException(message)
86108

87-
class IllegalInntektIdException(override val message: String, override val cause: Throwable?) :
88-
java.lang.RuntimeException(message, cause)
109+
class IllegalInntektIdException(
110+
override val message: String,
111+
override val cause: Throwable?,
112+
) : java.lang.RuntimeException(message, cause)

dp-inntekt-api/src/main/kotlin/no/nav/dagpenger/inntekt/db/PostgresInntektStore.kt

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@ import java.time.ZonedDateTime
2222
import javax.sql.DataSource
2323

2424
@Suppress("ktlint:standard:max-line-length")
25-
internal class PostgresInntektStore(private val dataSource: DataSource) : InntektStore, HealthCheck {
25+
internal class PostgresInntektStore(
26+
private val dataSource: DataSource,
27+
) : InntektStore,
28+
HealthCheck {
2629
companion object {
2730
private val ulidGenerator = ULID()
2831
private val LOGGER = KotlinLogging.logger {}
2932
private val markerInntektTimer =
30-
Summary.builder()
33+
Summary
34+
.builder()
3135
.name("marker_inntekt_brukt")
3236
.help("Hvor lang tid det tar å markere en inntekt brukt (i sekunder")
3337
.register()
@@ -110,8 +114,8 @@ internal class PostgresInntektStore(private val dataSource: DataSource) : Inntek
110114
}
111115
}
112116

113-
override fun getInntekt(inntektId: InntektId): StoredInntekt {
114-
return using(sessionOf(dataSource)) { session ->
117+
override fun getInntekt(inntektId: InntektId): StoredInntekt =
118+
using(sessionOf(dataSource)) { session ->
115119
session.run(
116120
queryOf(
117121
""" SELECT id, inntekt, manuelt_redigert, timestamp from inntekt_V1 where id = ?""",
@@ -123,12 +127,10 @@ internal class PostgresInntektStore(private val dataSource: DataSource) : Inntek
123127
manueltRedigert = row.boolean("manuelt_redigert"),
124128
timestamp = row.zonedDateTime("timestamp").toLocalDateTime(),
125129
)
126-
}
127-
.asSingle,
130+
}.asSingle,
128131
)
129132
?: throw InntektNotFoundException("Inntekt with id $inntektId not found.")
130133
}
131-
}
132134

133135
override fun getSpesifisertInntekt(inntektId: InntektId): SpesifisertInntekt {
134136
@Language("sql")
@@ -137,8 +139,9 @@ internal class PostgresInntektStore(private val dataSource: DataSource) : Inntek
137139
SELECT inntekt.id, inntekt.inntekt, inntekt.manuelt_redigert, inntekt.timestamp, mapping.beregningsdato
138140
from inntekt_V1 inntekt
139141
inner join inntekt_V1_person_mapping mapping on inntekt.id = mapping.inntektid
140-
where inntekt.id = ?"""
141-
.trimIndent()
142+
where inntekt.id = ?
143+
144+
""".trimIndent()
142145

143146
val stored =
144147
using(sessionOf(dataSource)) { session ->
@@ -153,14 +156,40 @@ internal class PostgresInntektStore(private val dataSource: DataSource) : Inntek
153156
manueltRedigert = row.boolean("manuelt_redigert"),
154157
timestamp = row.zonedDateTime("timestamp").toLocalDateTime(),
155158
) to row.localDate("beregningsdato")
156-
}
157-
.asSingle,
159+
}.asSingle,
158160
)
159161
?: throw InntektNotFoundException("Inntekt with id $inntektId not found.")
160162
}
161163
return mapToSpesifisertInntekt(stored.first, Opptjeningsperiode(stored.second).sisteAvsluttendeKalenderMåned)
162164
}
163165

166+
override fun getInntektMedPersonFnr(inntektId: InntektId): StoredInntektMedFnr {
167+
@Language("sql")
168+
val statement =
169+
"""
170+
SELECT inntekt.id, inntekt.inntekt, inntekt.manuelt_redigert, inntekt.timestamp, mapping.fnr
171+
from inntekt_V1 inntekt
172+
inner join inntekt_V1_person_mapping mapping on inntekt.id = mapping.inntektid
173+
where inntekt.id = ?
174+
175+
""".trimIndent()
176+
177+
return using(sessionOf(dataSource)) { session ->
178+
session.run(
179+
queryOf(statement, inntektId.id)
180+
.map {
181+
StoredInntektMedFnr(
182+
inntektId = InntektId(it.string("id")),
183+
inntekt = it.binaryStream("inntekt").use { jacksonObjectMapper.readValue<InntektkomponentResponse>(it) },
184+
manueltRedigert = it.boolean("manuelt_redigert"),
185+
timestamp = it.zonedDateTime("timestamp").toLocalDateTime(),
186+
fødselsnummer = it.string("fnr"),
187+
)
188+
}.asSingle,
189+
) ?: throw InntektNotFoundException("Inntekt with id $inntektId not found.")
190+
}
191+
}
192+
164193
override fun storeInntekt(
165194
command: StoreInntektCommand,
166195
created: ZonedDateTime,

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ data class GUIInntekt(
2020
val inntektsmottaker: Inntektsmottaker? = null,
2121
)
2222

23-
data class Inntektsmottaker(val pnr: String?, val navn: String?)
23+
data class Inntektsmottaker(
24+
val pnr: String?,
25+
val navn: String?,
26+
)
2427

2528
data class GUIInntektsKomponentResponse(
2629
val fraDato: YearMonth?,
@@ -62,3 +65,8 @@ data class InntektMedVerdikode(
6265
val tilleggsinformasjon: TilleggInformasjon? = null,
6366
val verdikode: String,
6467
)
68+
69+
data class OrganisasjonNavnOgIdMapping(
70+
val organisasjonsnummer: String,
71+
val organisasjonNavn: String,
72+
)
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package no.nav.dagpenger.inntekt.mapping
2+
3+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Aktoer
4+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.Avvik
5+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektBeskrivelse
6+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektType
7+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.InntektkomponentResponse
8+
import no.nav.dagpenger.inntekt.inntektskomponenten.v1.TilleggInformasjon
9+
import java.math.BigDecimal
10+
import java.time.YearMonth
11+
12+
fun InntektkomponentResponse.mapToFrontend(
13+
person: Inntektsmottaker,
14+
organisasjonsInfoListe: MutableList<OrganisasjonNavnOgIdMapping>,
15+
): InntekterResponse {
16+
val inntekt = arbeidsInntektMaaned
17+
val virksomhetListe: MutableList<Virksomhet> = mutableListOf()
18+
19+
inntekt?.forEach { arbeidsInntektMaaned ->
20+
val inntektsInformasjon = arbeidsInntektMaaned.arbeidsInntektInformasjon
21+
inntektsInformasjon?.inntektListe?.forEach { inntekt ->
22+
val virksomhet = inntekt.virksomhet
23+
val virksomhetNavn =
24+
organisasjonsInfoListe.find { it.organisasjonsnummer == virksomhet?.identifikator }?.organisasjonNavn
25+
?: ""
26+
val inntekter = mutableListOf<InntektMaaned>()
27+
inntekter.add(
28+
InntektMaaned(
29+
belop = inntekt.beloep,
30+
inntektskilde = inntekt.inntektskilde,
31+
redigert = false,
32+
begrunnelse = inntekt.beskrivelse.name,
33+
aarMaaned = arbeidsInntektMaaned.aarMaaned,
34+
fordel = inntekt.fordel,
35+
beskrivelse = inntekt.beskrivelse,
36+
inntektsstatus = inntekt.inntektsstatus,
37+
utbetaltIMaaned = inntekt.utbetaltIMaaned,
38+
inntektType = inntekt.inntektType,
39+
leveringstidspunkt = inntekt.leveringstidspunkt,
40+
opptjeningsland = inntekt.opptjeningsland,
41+
skattemessigBosattLand = inntekt.skattemessigBosattLand,
42+
inntektsinnsender = inntekt.inntektsinnsender,
43+
virksomhet = inntekt.virksomhet,
44+
inntektsmottaker = inntekt.inntektsmottaker,
45+
inngaarIGrunnlagForTrekk = inntekt.inngaarIGrunnlagForTrekk,
46+
utloeserArbeidsgiveravgift = inntekt.utloeserArbeidsgiveravgift,
47+
informasjonsstatus = inntekt.informasjonsstatus,
48+
tilleggsinformasjon = inntekt.tilleggsinformasjon,
49+
),
50+
)
51+
52+
val eksisterendeVirksomhet =
53+
virksomhetListe.find { it.virksomhetsnummer == virksomhet?.identifikator }
54+
if (eksisterendeVirksomhet != null) {
55+
eksisterendeVirksomhet.inntekter?.addAll(inntekter)
56+
eksisterendeVirksomhet.periode =
57+
InntektPeriode(
58+
fra = eksisterendeVirksomhet.inntekter!!.minOf { it.aarMaaned },
59+
til = eksisterendeVirksomhet.inntekter.maxOf { it.aarMaaned },
60+
)
61+
eksisterendeVirksomhet.totalBeløp = eksisterendeVirksomhet.inntekter.sumOf { it.belop }
62+
} else {
63+
virksomhetListe.add(
64+
Virksomhet(
65+
virksomhetsnummer = virksomhet?.identifikator ?: "",
66+
virksomhetsnavn = virksomhetNavn,
67+
periode =
68+
InntektPeriode(
69+
fra = arbeidsInntektMaaned.aarMaaned,
70+
til = arbeidsInntektMaaned.aarMaaned,
71+
),
72+
inntekter = inntekter,
73+
avvikListe =
74+
arbeidsInntektMaaned.avvikListe?.filter { it.virksomhet?.identifikator == virksomhet?.identifikator }
75+
?: emptyList(),
76+
),
77+
)
78+
}
79+
}
80+
}
81+
82+
return InntekterResponse(
83+
virksomhetsinntekt = virksomhetListe,
84+
mottaker = person,
85+
)
86+
}
87+
88+
data class InntekterResponse(
89+
val virksomhetsinntekt: List<Virksomhet>,
90+
val mottaker: Inntektsmottaker,
91+
)
92+
93+
data class Virksomhet(
94+
val virksomhetsnummer: String,
95+
val virksomhetsnavn: String,
96+
var periode: InntektPeriode?,
97+
val inntekter: MutableList<InntektMaaned>?,
98+
var totalBeløp: BigDecimal? = inntekter?.sumOf { it.belop } ?: BigDecimal.ZERO,
99+
val avvikListe: List<Avvik>,
100+
)
101+
102+
data class InntektPeriode(
103+
val fra: YearMonth,
104+
val til: YearMonth,
105+
)
106+
107+
data class InntektMaaned(
108+
val belop: BigDecimal,
109+
val fordel: String,
110+
val beskrivelse: InntektBeskrivelse,
111+
val inntektskilde: String,
112+
val inntektsstatus: String,
113+
val leveringstidspunkt: YearMonth? = null,
114+
val opptjeningsland: String? = null,
115+
val skattemessigBosattLand: String? = null,
116+
val utbetaltIMaaned: YearMonth,
117+
val inntektsinnsender: Aktoer? = null,
118+
val virksomhet: Aktoer? = null,
119+
val inntektsmottaker: Aktoer? = null,
120+
val inngaarIGrunnlagForTrekk: Boolean? = null,
121+
val utloeserArbeidsgiveravgift: Boolean? = null,
122+
val informasjonsstatus: String? = null,
123+
val inntektType: InntektType,
124+
val tilleggsinformasjon: TilleggInformasjon? = null,
125+
val redigert: Boolean,
126+
val begrunnelse: String,
127+
val aarMaaned: YearMonth,
128+
)

0 commit comments

Comments
 (0)