Skip to content

Commit bbc6c5f

Browse files
authored
Lager mapping for lønnsinntektbeskrivelse (#2345)
* Lager mapping for lønnsinntektbeskrivelse * Fikser etter QA * Refaktorering av mapping av lønnsinntekter * Legger til test for flere beskrivelser
1 parent 993b05c commit bbc6c5f

File tree

11 files changed

+629
-94
lines changed

11 files changed

+629
-94
lines changed

domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/domene/iay/Inntektspost.java

+17
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import no.nav.abakus.iaygrunnlag.kodeverk.IndexKey;
2121
import no.nav.abakus.iaygrunnlag.kodeverk.InntektspostType;
22+
import no.nav.abakus.iaygrunnlag.kodeverk.LønnsinntektBeskrivelse;
2223
import no.nav.abakus.iaygrunnlag.kodeverk.SkatteOgAvgiftsregelType;
2324
import no.nav.abakus.iaygrunnlag.kodeverk.UtbetaltYtelseFraOffentligeType;
2425
import no.nav.abakus.iaygrunnlag.kodeverk.UtbetaltYtelseType;
@@ -27,6 +28,7 @@
2728
import no.nav.foreldrepenger.abakus.felles.jpa.BaseEntitet;
2829
import no.nav.foreldrepenger.abakus.felles.jpa.IntervallEntitet;
2930
import no.nav.foreldrepenger.abakus.iay.jpa.InntektspostTypeKodeverdiConverter;
31+
import no.nav.foreldrepenger.abakus.iay.jpa.LønnsbeskrivelseKodeverdiConverter;
3032
import no.nav.foreldrepenger.abakus.iay.jpa.SkatteOgAvgiftsregelTypeKodeverdiConverter;
3133
import no.nav.foreldrepenger.abakus.typer.Beløp;
3234

@@ -46,6 +48,12 @@ public class Inntektspost extends BaseEntitet implements IndexKey {
4648
@Column(name = "skatte_og_avgiftsregel_type", nullable = false, updatable = false)
4749
private SkatteOgAvgiftsregelType skatteOgAvgiftsregelType = SkatteOgAvgiftsregelType.UDEFINERT;
4850

51+
/**
52+
* Beskriver hva inntekten gjelder dersom den er av typen LØNN
53+
*/
54+
@Convert(converter = LønnsbeskrivelseKodeverdiConverter.class)
55+
@Column(name = "lonnsinntekt_beskrivelse", nullable = false, updatable = false)
56+
private LønnsinntektBeskrivelse lønnsinntektBeskrivelse = LønnsinntektBeskrivelse.UDEFINERT;
4957
@ManyToOne(optional = false)
5058
@JoinColumn(name = "inntekt_id", nullable = false, updatable = false, unique = true)
5159
private Inntekt inntekt;
@@ -82,6 +90,7 @@ public Inntektspost() {
8290
Inntektspost(Inntektspost inntektspost) {
8391
this.inntektspostType = inntektspost.getInntektspostType();
8492
this.skatteOgAvgiftsregelType = inntektspost.getSkatteOgAvgiftsregelType();
93+
this.lønnsinntektBeskrivelse = inntektspost.getLønnsinntektBeskrivelse();
8594
this.periode = inntektspost.getPeriode();
8695
this.beløp = inntektspost.getBeløp();
8796
this.ytelse = inntektspost.getYtelseType().getKode();
@@ -128,6 +137,14 @@ void setSkatteOgAvgiftsregelType(SkatteOgAvgiftsregelType skatteOgAvgiftsregelTy
128137
this.skatteOgAvgiftsregelType = skatteOgAvgiftsregelType;
129138
}
130139

140+
public LønnsinntektBeskrivelse getLønnsinntektBeskrivelse() {
141+
return lønnsinntektBeskrivelse;
142+
}
143+
144+
public void setLønnsinntektBeskrivelse(LønnsinntektBeskrivelse lønnsinntektBeskrivelse) {
145+
this.lønnsinntektBeskrivelse = lønnsinntektBeskrivelse;
146+
}
147+
131148
public void setPeriode(LocalDate fom, LocalDate tom) {
132149
this.periode = IntervallEntitet.fraOgMedTilOgMed(fom, tom);
133150
}

domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/domene/iay/InntektspostBuilder.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.time.LocalDate;
55

66
import no.nav.abakus.iaygrunnlag.kodeverk.InntektspostType;
7+
import no.nav.abakus.iaygrunnlag.kodeverk.LønnsinntektBeskrivelse;
78
import no.nav.abakus.iaygrunnlag.kodeverk.SkatteOgAvgiftsregelType;
89
import no.nav.abakus.iaygrunnlag.kodeverk.UtbetaltYtelseType;
910
import no.nav.foreldrepenger.abakus.typer.Beløp;
@@ -29,6 +30,11 @@ public InntektspostBuilder medSkatteOgAvgiftsregelType(SkatteOgAvgiftsregelType
2930
return this;
3031
}
3132

33+
public InntektspostBuilder medLønnsinntektBeskrivelse(LønnsinntektBeskrivelse lønnsinntektBeskrivelse) {
34+
this.inntektspost.setLønnsinntektBeskrivelse(lønnsinntektBeskrivelse);
35+
return this;
36+
}
37+
3238
public InntektspostBuilder medPeriode(LocalDate fraOgMed, LocalDate tilOgMed) {
3339
this.inntektspost.setPeriode(fraOgMed, tilOgMed);
3440
return this;
@@ -51,4 +57,4 @@ public Inntektspost build() {
5157
throw new IllegalStateException();
5258
}
5359

54-
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package no.nav.foreldrepenger.abakus.iay.jpa;
2+
3+
import javax.persistence.AttributeConverter;
4+
import javax.persistence.Converter;
5+
6+
import no.nav.abakus.iaygrunnlag.kodeverk.LønnsinntektBeskrivelse;
7+
8+
9+
@Converter(autoApply = true)
10+
public class LønnsbeskrivelseKodeverdiConverter implements AttributeConverter<LønnsinntektBeskrivelse, String> {
11+
@Override
12+
public String convertToDatabaseColumn(LønnsinntektBeskrivelse attribute) {
13+
return attribute == null ? null : attribute.getKode();
14+
}
15+
16+
@Override
17+
public LønnsinntektBeskrivelse convertToEntityAttribute(String dbData) {
18+
return dbData == null ? null : LønnsinntektBeskrivelse.fraKode(dbData);
19+
}
20+
}

domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/iay/tjeneste/dto/iay/MapAktørInntekt.java

+2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ private InntektspostBuilder mapInntektspost(UtbetalingsPostDto post) {
7373
.medInntektspostType(post.getInntektspostType())
7474
.medPeriode(post.getPeriode().getFom(), post.getPeriode().getTom())
7575
.medSkatteOgAvgiftsregelType(post.getSkattAvgiftType())
76+
.medLønnsinntektBeskrivelse(post.getLønnsinntektBeskrivelse())
7677
.medYtelse(post.getYtelseType());
7778
}
7879

@@ -138,6 +139,7 @@ private UtbetalingsPostDto tilPost(Inntektspost inntektspost) {
138139

139140
UtbetalingsPostDto dto = new UtbetalingsPostDto(periode, inntektspostType).medUtbetaltYtelseType(ytelseType)
140141
.medSkattAvgiftType(skattOgAvgiftType)
142+
.medLønnsinntektbeskrivelse(inntektspost.getLønnsinntektBeskrivelse())
141143
.medBeløp(inntektspost.getBeløp().getVerdi());
142144

143145
return dto;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package no.nav.foreldrepenger.abakus.registerdata;
2+
3+
import java.math.BigDecimal;
4+
import java.time.YearMonth;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.Objects;
8+
import java.util.Optional;
9+
import java.util.Set;
10+
import java.util.stream.Collectors;
11+
12+
import no.nav.abakus.iaygrunnlag.kodeverk.InntektskildeType;
13+
import no.nav.abakus.iaygrunnlag.kodeverk.InntektspostType;
14+
import no.nav.abakus.iaygrunnlag.kodeverk.LønnsinntektBeskrivelse;
15+
import no.nav.abakus.iaygrunnlag.kodeverk.SkatteOgAvgiftsregelType;
16+
import no.nav.foreldrepenger.abakus.domene.iay.Arbeidsgiver;
17+
import no.nav.foreldrepenger.abakus.domene.iay.InntektArbeidYtelseAggregatBuilder;
18+
import no.nav.foreldrepenger.abakus.domene.iay.InntektBuilder;
19+
import no.nav.foreldrepenger.abakus.domene.iay.InntektspostBuilder;
20+
import no.nav.foreldrepenger.abakus.domene.iay.Opptjeningsnøkkel;
21+
import no.nav.foreldrepenger.abakus.registerdata.inntekt.komponenten.InntektsInformasjon;
22+
23+
/**
24+
* Lager Inntekt for lønnsinnntekter
25+
*/
26+
class ByggLønnsinntektInntektTjeneste {
27+
28+
29+
static void mapLønnsinntekter(InntektsInformasjon inntektsInformasjon,
30+
InntektArbeidYtelseAggregatBuilder.AktørInntektBuilder aktørInntektBuilder,
31+
Map<String, Arbeidsgiver> arbeidsgivereLookup) {
32+
mapTilArbeidsgiver(inntektsInformasjon, arbeidsgivereLookup).entrySet()
33+
.stream()
34+
.map(e -> byggInntekt(e.getValue(), e.getKey(), aktørInntektBuilder, inntektsInformasjon.getKilde()))
35+
.forEach(aktørInntektBuilder::leggTilInntekt);
36+
}
37+
38+
private static Map<Arbeidsgiver, Map<YearMonth, List<MånedsbeløpOgSkatteOgAvgiftsregel>>> mapTilArbeidsgiver(InntektsInformasjon inntektsInformasjon,
39+
Map<String, Arbeidsgiver> arbeidsgivereLookup) {
40+
41+
return inntektsInformasjon.getMånedsinntekterUtenomYtelser()
42+
.stream()
43+
.filter(mi -> arbeidsgivereLookup.get(mi.getArbeidsgiver()) != null)
44+
.map(mi -> new MånedsbeløpOgSkatteOgAvgiftsregel(arbeidsgivereLookup.get(mi.getArbeidsgiver()), mi.getMåned(), mi.getBeløp(),
45+
mi.getSkatteOgAvgiftsregelType(), mi.getLønnsbeskrivelseKode()))
46+
.collect(Collectors.groupingBy(MånedsbeløpOgSkatteOgAvgiftsregel::getArbeidsgiver,
47+
Collectors.groupingBy(MånedsbeløpOgSkatteOgAvgiftsregel::getMåned)));
48+
}
49+
50+
private static InntektBuilder byggInntekt(Map<YearMonth, List<MånedsbeløpOgSkatteOgAvgiftsregel>> inntekter,
51+
Arbeidsgiver arbeidsgiver,
52+
InntektArbeidYtelseAggregatBuilder.AktørInntektBuilder aktørInntektBuilder,
53+
InntektskildeType inntektOpptjening) {
54+
55+
InntektBuilder inntektBuilder = aktørInntektBuilder.getInntektBuilder(inntektOpptjening, new Opptjeningsnøkkel(arbeidsgiver));
56+
57+
for (var måned : inntekter.keySet()) {
58+
var månedsinnteker = inntekter.get(måned);
59+
BigDecimal beløpSum = månedsinnteker.stream().map(MånedsbeløpOgSkatteOgAvgiftsregel::getBeløp).reduce(BigDecimal.ZERO, BigDecimal::add);
60+
61+
Optional<String> valgtSkatteOgAvgiftsregel = finnSkatteOgAvgiftsregel(månedsinnteker);
62+
63+
var lønnsinntektBeskrivelseKode = finnLønnsbeskrivelseType(månedsinnteker);
64+
lagInntektsposter(måned, beløpSum, valgtSkatteOgAvgiftsregel, lønnsinntektBeskrivelseKode, inntektBuilder);
65+
}
66+
67+
return inntektBuilder.medArbeidsgiver(arbeidsgiver);
68+
}
69+
70+
private static Optional<String> finnSkatteOgAvgiftsregel(List<MånedsbeløpOgSkatteOgAvgiftsregel> månedsinnteker) {
71+
Map<String, Integer> antalInntekterForAvgiftsregel = månedsinnteker.stream()
72+
.filter(e -> e.getSkatteOgAvgiftsregelType() != null)
73+
.collect(Collectors.groupingBy(MånedsbeløpOgSkatteOgAvgiftsregel::getSkatteOgAvgiftsregelType,
74+
Collectors.collectingAndThen(Collectors.mapping(MånedsbeløpOgSkatteOgAvgiftsregel::getBeløp, Collectors.toSet()), Set::size)));
75+
Optional<String> valgtSkatteOgAvgiftsregel = Optional.empty();
76+
if (antalInntekterForAvgiftsregel.keySet().size() > 1) {
77+
valgtSkatteOgAvgiftsregel = Optional.ofNullable(velgSkatteOgAvgiftsRegel(antalInntekterForAvgiftsregel.keySet()));
78+
} else if (antalInntekterForAvgiftsregel.keySet().size() == 1) {
79+
valgtSkatteOgAvgiftsregel = Optional.of(antalInntekterForAvgiftsregel.keySet().iterator().next());
80+
}
81+
return valgtSkatteOgAvgiftsregel;
82+
}
83+
84+
private static Optional<String> finnLønnsbeskrivelseType(List<MånedsbeløpOgSkatteOgAvgiftsregel> månedsinnteker) {
85+
Set<String> lønnsinntektBeskrivelse = månedsinnteker.stream()
86+
.map(MånedsbeløpOgSkatteOgAvgiftsregel::getLønnsinntektBeskrivelseKode)
87+
.filter(Objects::nonNull)
88+
.collect(Collectors.toSet());
89+
Optional<String> valgtLønnsbesrivelseType = Optional.empty();
90+
if (lønnsinntektBeskrivelse.size() > 1) {
91+
if (lønnsinntektBeskrivelse.contains(LønnsinntektBeskrivelse.KOMMUNAL_OMSORGSLOENN_OG_FOSTERHJEMSGODTGJOERELSE.getOffisiellKode())) {
92+
return Optional.of(LønnsinntektBeskrivelse.KOMMUNAL_OMSORGSLOENN_OG_FOSTERHJEMSGODTGJOERELSE.getOffisiellKode());
93+
} else {
94+
return Optional.of(lønnsinntektBeskrivelse.iterator().next());
95+
}
96+
} else if (lønnsinntektBeskrivelse.size() == 1) {
97+
return Optional.of(lønnsinntektBeskrivelse.iterator().next());
98+
}
99+
return valgtLønnsbesrivelseType;
100+
}
101+
102+
103+
private static void lagInntektsposter(YearMonth måned,
104+
BigDecimal sumInntektsbeløp,
105+
Optional<String> valgtSkatteOgAvgiftsregel,
106+
Optional<String> lønnsinntektBeskrivelseKode,
107+
InntektBuilder inntektBuilder) {
108+
InntektspostBuilder inntektspostBuilder = inntektBuilder.getInntektspostBuilder();
109+
inntektspostBuilder.medBeløp(sumInntektsbeløp).medPeriode(måned.atDay(1), måned.atEndOfMonth()).medInntektspostType(InntektspostType.LØNN);
110+
valgtSkatteOgAvgiftsregel.map(SkatteOgAvgiftsregelType::finnForKodeverkEiersKode).ifPresent(inntektspostBuilder::medSkatteOgAvgiftsregelType);
111+
lønnsinntektBeskrivelseKode.map(LønnsinntektBeskrivelse::finnForKodeverkEiersKode).ifPresent(inntektspostBuilder::medLønnsinntektBeskrivelse);
112+
inntektBuilder.leggTilInntektspost(inntektspostBuilder);
113+
}
114+
115+
private static String velgSkatteOgAvgiftsRegel(Set<String> alternativ) {
116+
if (alternativ.contains(SkatteOgAvgiftsregelType.SÆRSKILT_FRADRAG_FOR_SJØFOLK.getOffisiellKode())) {
117+
return SkatteOgAvgiftsregelType.SÆRSKILT_FRADRAG_FOR_SJØFOLK.getOffisiellKode();
118+
} else if (alternativ.contains(SkatteOgAvgiftsregelType.NETTOLØNN_FOR_SJØFOLK.getOffisiellKode())) {
119+
return SkatteOgAvgiftsregelType.NETTOLØNN_FOR_SJØFOLK.getOffisiellKode();
120+
} else {
121+
return alternativ.stream().findFirst().orElse(null);
122+
}
123+
}
124+
125+
public static final class MånedsbeløpOgSkatteOgAvgiftsregel {
126+
private Arbeidsgiver arbeidsgiver;
127+
private YearMonth måned;
128+
private BigDecimal beløp;
129+
private String skatteOgAvgiftsregelType;
130+
131+
private String lønnsinntektBeskrivelseKode;
132+
133+
public MånedsbeløpOgSkatteOgAvgiftsregel(Arbeidsgiver arbeidsgiver,
134+
YearMonth måned,
135+
BigDecimal beløp,
136+
String skatteOgAvgiftsregelType,
137+
String lønnsinntektBeskrivelseKode) {
138+
this.arbeidsgiver = arbeidsgiver;
139+
this.måned = måned;
140+
this.beløp = beløp;
141+
this.skatteOgAvgiftsregelType = skatteOgAvgiftsregelType;
142+
this.lønnsinntektBeskrivelseKode = lønnsinntektBeskrivelseKode;
143+
}
144+
145+
public Arbeidsgiver getArbeidsgiver() {
146+
return arbeidsgiver;
147+
}
148+
149+
public YearMonth getMåned() {
150+
return måned;
151+
}
152+
153+
public BigDecimal getBeløp() {
154+
return beløp;
155+
}
156+
157+
public String getSkatteOgAvgiftsregelType() {
158+
return skatteOgAvgiftsregelType;
159+
}
160+
161+
public String getLønnsinntektBeskrivelseKode() {
162+
return lønnsinntektBeskrivelseKode;
163+
}
164+
}
165+
166+
}

0 commit comments

Comments
 (0)