Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Innfører gradering mot tilsyn som eksplisitt reduksjon #427

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett;

import java.math.BigDecimal;

import no.nav.fpsak.tidsserie.LocalDateTimeline;

public class PleiepengerSyktBarnGrunnlag extends YtelsesSpesifiktGrunnlag {

private final LocalDateTimeline<BigDecimal> tilsynsgraderingsprosent;

public PleiepengerSyktBarnGrunnlag(LocalDateTimeline<BigDecimal> tilsynsgraderingsprosent) {
super("PSB");
this.tilsynsgraderingsprosent = tilsynsgraderingsprosent;
}

public LocalDateTimeline<BigDecimal> getTilsynsgraderingsprosent() {
if (tilsynsgraderingsprosent == null) {
return LocalDateTimeline.empty();
}
return tilsynsgraderingsprosent;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPeriode;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPrArbeidsforhold;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPrStatus;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.PleiepengerSyktBarnGrunnlag;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.TilkommetInntekt;
import no.nav.fpsak.nare.doc.RuleDocumentation;
import no.nav.fpsak.nare.evaluation.Evaluation;
import no.nav.fpsak.nare.evaluation.node.SingleEvaluation;
import no.nav.fpsak.nare.specification.LeafSpecification;
import no.nav.fpsak.tidsserie.LocalDateInterval;
import no.nav.fpsak.tidsserie.StandardCombinators;

@RuleDocumentation(FinnGrenseverdi.ID)
public class FinnGrenseverdi extends LeafSpecification<BeregningsgrunnlagPeriode> {
Expand All @@ -38,14 +41,19 @@ public Evaluation evaluate(BeregningsgrunnlagPeriode grunnlag) {
grunnlag.setTotalUtbetalingsgradFraUttak(totalUtbetalingsgradFraUttak);
resultater.put("totalUtbetalingsgradFraUttak", totalUtbetalingsgradFraUttak);

//hvis §8-47a, skaler med fast faktor
var erInaktivTypeA = MidlertidigInaktivType.A.equals(grunnlag.getBeregningsgrunnlag().getMidlertidigInaktivType());
if (erInaktivTypeA) {
BigDecimal reduksjonsfaktor = grunnlag.getBeregningsgrunnlag().getMidlertidigInaktivTypeAReduksjonsfaktor();
grenseverdi = grenseverdi.multiply(reduksjonsfaktor);
resultater.put("grad847a", reduksjonsfaktor);
}
grenseverdi = utførMidlertidigInaktivGradering(grunnlag, resultater, grenseverdi);
grenseverdi = utførYtelsesspesifikkGradering(grunnlag, grenseverdi);
grenseverdi = utførGraderingMotInntekt(grunnlag, resultater, grenseverdi, totalUtbetalingsgradFraUttak);

resultater.put("grenseverdi", grenseverdi);
grunnlag.setGrenseverdi(grenseverdi);
SingleEvaluation resultat = ja();
resultat.setEvaluationProperties(resultater);
return resultat;

}

private BigDecimal utførGraderingMotInntekt(BeregningsgrunnlagPeriode grunnlag, Map<String, Object> resultater, BigDecimal grenseverdi, BigDecimal totalUtbetalingsgradFraUttak) {
//juster ned med tilkommet inntekt hvis det gir lavere utbetaling enn overstående
if (grunnlag.getBeregningsgrunnlag().getToggles().isEnabled("GRADERING_MOT_INNTEKT", false) && !grunnlag.getTilkommetInntektsforholdListe().isEmpty()) {
BigDecimal graderingPåToppenAvUttakgraderingPgaTilkommetInntekt = andelBeholdtEtterGradertMotTilkommetInntekt(grunnlag);
Expand All @@ -60,15 +68,37 @@ public Evaluation evaluate(BeregningsgrunnlagPeriode grunnlag) {
resultater.put("inntektgraderingsprosent", grunnlag.getInntektsgraderingFraBruttoBeregningsgrunnlag());
}
}
resultater.put("grenseverdi", grenseverdi);
grunnlag.setGrenseverdi(grenseverdi);
SingleEvaluation resultat = ja();
resultat.setEvaluationProperties(resultater);
return resultat;
return grenseverdi;
}

private static BigDecimal utførMidlertidigInaktivGradering(BeregningsgrunnlagPeriode grunnlag, Map<String, Object> resultater, BigDecimal grenseverdi) {
//hvis §8-47a, skaler med fast faktor
var erInaktivTypeA = MidlertidigInaktivType.A.equals(grunnlag.getBeregningsgrunnlag().getMidlertidigInaktivType());
if (erInaktivTypeA) {
BigDecimal reduksjonsfaktor = grunnlag.getBeregningsgrunnlag().getMidlertidigInaktivTypeAReduksjonsfaktor();
grenseverdi = grenseverdi.multiply(reduksjonsfaktor);
resultater.put("grad847a", reduksjonsfaktor);
}
return grenseverdi;
}

private static BigDecimal utførYtelsesspesifikkGradering(BeregningsgrunnlagPeriode grunnlag, BigDecimal grenseverdi) {
if (grunnlag.getBeregningsgrunnlag().getYtelsesSpesifiktGrunnlag() != null && grunnlag.getBeregningsgrunnlag().getYtelsesSpesifiktGrunnlag() instanceof PleiepengerSyktBarnGrunnlag psbGrunnlag) {
var tilsynsgraderingsprosent = psbGrunnlag.getTilsynsgraderingsprosent().compress((b1, b2) -> b1.compareTo(b2) == 0, StandardCombinators::leftOnly);
var intersection = tilsynsgraderingsprosent.intersection(new LocalDateInterval(grunnlag.getPeriodeFom(), grunnlag.getPeriodeTom()));
if (intersection.toSegments().size() > 1) {
throw new IllegalStateException("Fant flere tilsynsgrader for samme periode " + grunnlag.getPeriodeFom());
}
if (!intersection.isEmpty()) {
var tilsynsgradering = intersection.toSegments().first().getValue();
grenseverdi = grenseverdi.multiply(tilsynsgradering.divide(BigDecimal.valueOf(100), 10, RoundingMode.HALF_UP));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mulig jeg misforstod, men ender vi opp med å gradere mot tilsyn to ganger her? Det er vel også inkludert i utbetalingsgradene fra uttak som brukes over?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eg trudde vi blei enige om å sende inn 1-aktivitetsgrad som utbetalingsgrad.

}
}
return grenseverdi;
}

static BigDecimal min(BigDecimal a, BigDecimal b){

static BigDecimal min(BigDecimal a, BigDecimal b) {
return a.compareTo(b) > 0 ? b : a;
}

Expand All @@ -91,7 +121,7 @@ private static BigDecimal summerAvkortet(BeregningsgrunnlagPeriode grunnlag) {
for (BeregningsgrunnlagPrStatus bps : grunnlag.getBeregningsgrunnlagPrStatusSomSkalBrukes()) {
if (bps.erArbeidstakerEllerFrilanser()) {
sum = sum.add(bps.getArbeidsforholdSomSkalBrukes().stream()
.map(arb -> arb.getAndelsmessigFørGraderingPrAar())
.map(BeregningsgrunnlagPrArbeidsforhold::getAndelsmessigFørGraderingPrAar)
.reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
} else {
sum = sum.add(bps.getAndelsmessigFørGraderingPrAar());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPeriode;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPrArbeidsforhold;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPrStatus;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.PleiepengerSyktBarnGrunnlag;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.TilkommetInntekt;
import no.nav.fpsak.nare.doc.RuleDocumentation;
import no.nav.fpsak.nare.evaluation.Evaluation;
import no.nav.fpsak.nare.evaluation.node.SingleEvaluation;
import no.nav.fpsak.nare.specification.LeafSpecification;
import no.nav.fpsak.tidsserie.LocalDateInterval;
import no.nav.fpsak.tidsserie.StandardCombinators;

@RuleDocumentation(FinnGrenseverdiUtenFordeling.ID)
public class FinnGrenseverdiUtenFordeling extends LeafSpecification<BeregningsgrunnlagPeriode> {
Expand All @@ -38,14 +41,19 @@ public Evaluation evaluate(BeregningsgrunnlagPeriode grunnlag) {
grunnlag.setTotalUtbetalingsgradFraUttak(totalUtbetalingsgradFraUttak);
resultater.put("totalUtbetalingsgradFraUttak", totalUtbetalingsgradFraUttak);

//hvis §8-47a, skaler med fast faktor
var erInaktivTypeA = MidlertidigInaktivType.A.equals(grunnlag.getBeregningsgrunnlag().getMidlertidigInaktivType());
if (erInaktivTypeA) {
BigDecimal reduksjonsfaktor = grunnlag.getBeregningsgrunnlag().getMidlertidigInaktivTypeAReduksjonsfaktor();
grenseverdi = grenseverdi.multiply(reduksjonsfaktor);
resultater.put("grad847a", reduksjonsfaktor);
}
grenseverdi = utførMidlertidigInaktivGradering(grunnlag, resultater, grenseverdi);
grenseverdi = utførYtelsesspesifikkGradering(grunnlag, grenseverdi);
grenseverdi = utførGraderingMotInntekt(grunnlag, resultater, grenseverdi, totalUtbetalingsgradFraUttak);

resultater.put("grenseverdi", grenseverdi);
grunnlag.setGrenseverdi(grenseverdi);
SingleEvaluation resultat = ja();
resultat.setEvaluationProperties(resultater);
return resultat;

}

private BigDecimal utførGraderingMotInntekt(BeregningsgrunnlagPeriode grunnlag, Map<String, Object> resultater, BigDecimal grenseverdi, BigDecimal totalUtbetalingsgradFraUttak) {
//juster ned med tilkommet inntekt hvis det gir lavere utbetaling enn overstående
if (grunnlag.getBeregningsgrunnlag().getToggles().isEnabled("GRADERING_MOT_INNTEKT", false) && !grunnlag.getTilkommetInntektsforholdListe().isEmpty()) {
BigDecimal graderingPåToppenAvUttakgraderingPgaTilkommetInntekt = andelBeholdtEtterGradertMotTilkommetInntekt(grunnlag);
Expand All @@ -60,15 +68,36 @@ public Evaluation evaluate(BeregningsgrunnlagPeriode grunnlag) {
resultater.put("inntektgraderingsprosent", grunnlag.getInntektsgraderingFraBruttoBeregningsgrunnlag());
}
}
resultater.put("grenseverdi", grenseverdi);
grunnlag.setGrenseverdi(grenseverdi);
SingleEvaluation resultat = ja();
resultat.setEvaluationProperties(resultater);
return resultat;
return grenseverdi;
}

private static BigDecimal utførMidlertidigInaktivGradering(BeregningsgrunnlagPeriode grunnlag, Map<String, Object> resultater, BigDecimal grenseverdi) {
//hvis §8-47a, skaler med fast faktor
var erInaktivTypeA = MidlertidigInaktivType.A.equals(grunnlag.getBeregningsgrunnlag().getMidlertidigInaktivType());
if (erInaktivTypeA) {
BigDecimal reduksjonsfaktor = grunnlag.getBeregningsgrunnlag().getMidlertidigInaktivTypeAReduksjonsfaktor();
grenseverdi = grenseverdi.multiply(reduksjonsfaktor);
resultater.put("grad847a", reduksjonsfaktor);
}
return grenseverdi;
}

private static BigDecimal utførYtelsesspesifikkGradering(BeregningsgrunnlagPeriode grunnlag, BigDecimal grenseverdi) {
if (grunnlag.getBeregningsgrunnlag().getYtelsesSpesifiktGrunnlag() != null && grunnlag.getBeregningsgrunnlag().getYtelsesSpesifiktGrunnlag() instanceof PleiepengerSyktBarnGrunnlag psbGrunnlag) {
var tilsynsgraderingsprosent = psbGrunnlag.getTilsynsgraderingsprosent().compress((b1, b2) -> b1.compareTo(b2) == 0, StandardCombinators::leftOnly);
var intersection = tilsynsgraderingsprosent.intersection(new LocalDateInterval(grunnlag.getPeriodeFom(), grunnlag.getPeriodeTom()));
if (intersection.toSegments().size() > 1) {
throw new IllegalStateException("Fant flere tilsynsgrader for samme periode " + grunnlag.getPeriodeFom());
}
if (!intersection.isEmpty()) {
var tilsynsgradering = intersection.toSegments().first().getValue();
grenseverdi = grenseverdi.multiply(tilsynsgradering.divide(BigDecimal.valueOf(100), 10, RoundingMode.HALF_UP));
}
}
return grenseverdi;
}

static BigDecimal min(BigDecimal a, BigDecimal b){
static BigDecimal min(BigDecimal a, BigDecimal b) {
return a.compareTo(b) > 0 ? b : a;
}

Expand All @@ -91,7 +120,7 @@ private static BigDecimal summerAvkortet(BeregningsgrunnlagPeriode grunnlag) {
for (BeregningsgrunnlagPrStatus bps : grunnlag.getBeregningsgrunnlagPrStatusSomSkalBrukes()) {
if (bps.erArbeidstakerEllerFrilanser()) {
sum = sum.add(bps.getArbeidsforholdSomSkalBrukes().stream()
.map(arb -> arb.getAndelsmessigFørGraderingPrAar())
.map(BeregningsgrunnlagPrArbeidsforhold::getAndelsmessigFørGraderingPrAar)
.reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
} else {
sum = sum.add(bps.getAndelsmessigFørGraderingPrAar());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPeriode;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPrArbeidsforhold;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPrStatus;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.PleiepengerSyktBarnGrunnlag;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.TilkommetInntekt;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.grunnlag.inntekt.Arbeidsforhold;
import no.nav.fpsak.tidsserie.LocalDateTimeline;

class RegelFinnGrenseverdiTest {

Expand Down Expand Up @@ -118,6 +120,31 @@ void ett_arbeidsforhold_over_6G() {
assertThat(periode.getGrenseverdi()).isEqualByComparingTo(BigDecimal.valueOf(600_000));
}

@Test
void ett_arbeidsforhold_over_6G_og_gradering_mot_tilsyn() {
//Arrange
double beregnetPrÅr = 800_000;

BeregningsgrunnlagPeriode periode = BeregningsgrunnlagPeriode.builder()
.medPeriode(Periode.of(LocalDate.now(), TIDENES_ENDE))
.build();

Beregningsgrunnlag.builder()
.medBeregningsgrunnlagPeriode(periode)
.medGrunnbeløp(BigDecimal.valueOf(100_000))
.medYtelsesSpesifiktGrunnlag(new PleiepengerSyktBarnGrunnlag(new LocalDateTimeline<>(
periode.getPeriodeFom(), periode.getPeriodeTom(), BigDecimal.valueOf(50)
)));

leggTilArbeidsforhold(periode, AF_1, beregnetPrÅr, null, 100D, 0D);

//Act
kjørRegel(periode);

assertThat(periode.getGrenseverdi()).isEqualByComparingTo(BigDecimal.valueOf(300_000));
}


@Test
void to_arbeidsforhold_under_6G() {
//Arrange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@
import org.junit.jupiter.api.Test;

import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.AktivitetStatus;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.AktivitetStatusMedHjemmel;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.BeregningsgrunnlagHjemmel;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.MidlertidigInaktivType;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.Periode;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.RegelResultat;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.Beregningsgrunnlag;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPeriode;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPrArbeidsforhold;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.BeregningsgrunnlagPrStatus;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.PleiepengerSyktBarnGrunnlag;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.fastsett.TilkommetInntekt;
import no.nav.folketrygdloven.beregningsgrunnlag.regelmodell.grunnlag.inntekt.Arbeidsforhold;
import no.nav.fpsak.tidsserie.LocalDateTimeline;

class RegelFinnGrenseverdiUtenFordelingTest {

Expand Down Expand Up @@ -118,6 +122,31 @@ void ett_arbeidsforhold_over_6G() {
assertThat(periode.getGrenseverdi()).isEqualByComparingTo(BigDecimal.valueOf(600_000));
}

@Test
void ett_arbeidsforhold_over_6G_og_gradering_mot_tilsyn() {
//Arrange
double beregnetPrÅr = 800_000;

BeregningsgrunnlagPeriode periode = BeregningsgrunnlagPeriode.builder()
.medPeriode(Periode.of(LocalDate.now(), TIDENES_ENDE))
.build();

Beregningsgrunnlag.builder()
.medBeregningsgrunnlagPeriode(periode)
.medGrunnbeløp(BigDecimal.valueOf(100_000))
.medYtelsesSpesifiktGrunnlag(new PleiepengerSyktBarnGrunnlag(new LocalDateTimeline<>(
periode.getPeriodeFom(), periode.getPeriodeTom(), BigDecimal.valueOf(50)
)));

leggTilArbeidsforhold(periode, AF_1, beregnetPrÅr, null, 100D, 0D);

//Act
kjørRegel(periode);

assertThat(periode.getGrenseverdi()).isEqualByComparingTo(BigDecimal.valueOf(300_000));
}


@Test
void to_arbeidsforhold_under_6G() {
//Arrange
Expand Down