Skip to content

Commit

Permalink
Støtte tilbakekreving av OMP i helg (#2810)
Browse files Browse the repository at this point in the history
* Støtte tilbakekreving av OMP i helg

* Støtte tilbakekreving av OMP i helg
  • Loading branch information
tendestad committed May 8, 2024
1 parent 780e772 commit a979c96
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 32 deletions.
Expand Up @@ -2,47 +2,49 @@

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import java.util.function.Function;

import no.nav.foreldrepenger.tilbakekreving.behandlingslager.fagsak.FagOmrådeKode;
import no.nav.foreldrepenger.tilbakekreving.felles.Periode;
import no.nav.foreldrepenger.tilbakekreving.felles.Ukedager;

public class BeregnBeløpUtil {

private boolean forEngangsstønad;
private Function<Periode, Integer> periodeTilDager;

public static BeregnBeløpUtil forFagområde(FagOmrådeKode fagOmrådeKode) {
return new BeregnBeløpUtil(fagOmrådeKode == FagOmrådeKode.ENGANGSSTØNAD);
return new BeregnBeløpUtil(fagOmrådeKode);
}

public BeregnBeløpUtil(boolean forEngangsstønad) {
this.forEngangsstønad = forEngangsstønad;
private BeregnBeløpUtil(FagOmrådeKode fagOmrådeKode) {
this(fagOmrådeKode == FagOmrådeKode.ENGANGSSTØNAD || fagOmrådeKode == FagOmrådeKode.OMSORGSPENGER);
}

public BigDecimal beregnBeløpPrVirkedag(BigDecimal beløp, Periode periode) {
int antallVirkedager = Ukedager.beregnAntallVirkedager(periode);
if (forEngangsstønad && antallVirkedager == 0) { //Gjelder kun ved Engangsstønad (REFUTG) som treffer en ikke vanlig virkedag.
return beløp;
}
return beløp.divide(BigDecimal.valueOf(antallVirkedager), 2, RoundingMode.HALF_UP);
private BeregnBeløpUtil(boolean utbetalingMuligAlleDager) {
periodeTilDager = utbetalingMuligAlleDager
? (Periode p) -> (int) ChronoUnit.DAYS.between(p.getFom(), p.getTom()) + 1
: Ukedager::beregnAntallVirkedager;
}

public BigDecimal beregnBeløpPrDag(BigDecimal beløp, Periode periode) {
int antallDager = periodeTilDager.apply(periode);
return beløp.divide(BigDecimal.valueOf(antallDager), 2, RoundingMode.HALF_UP);
}

public BigDecimal beregnBeløp(Periode foreldetPeriode, Periode grunnlagPeriode, BigDecimal beløpPrVirkedag) {
Optional<Periode> overlap = grunnlagPeriode.overlap(foreldetPeriode);
if (overlap.isPresent()) {
Periode overlapInterval = overlap.get();
int antallVirkedager = Ukedager.beregnAntallVirkedager(overlapInterval);
if (forEngangsstønad && antallVirkedager == 0) { //Gjelder kun ved Engangsstønad (REFUTG) som treffer en ikke vanlig virkedag.
return beløpPrVirkedag;
}
return beløpPrVirkedag.multiply(BigDecimal.valueOf(antallVirkedager));
int antallDager = periodeTilDager.apply(overlapInterval);
return beløpPrVirkedag.multiply(BigDecimal.valueOf(antallDager));
}
return BigDecimal.ZERO;
}

public BigDecimal beregnBeløpForPeriode(BigDecimal tilbakekrevesBeløp, Periode feilutbetalingPeriode, Periode periode) {
BigDecimal grunnlagBelopPerUkeDager = beregnBeløpPrVirkedag(tilbakekrevesBeløp, periode);
BigDecimal grunnlagBelopPerUkeDager = beregnBeløpPrDag(tilbakekrevesBeløp, periode);
BigDecimal ytelseBeløp = beregnBeløp(feilutbetalingPeriode, periode, grunnlagBelopPerUkeDager);
return ytelseBeløp.setScale(0, RoundingMode.HALF_UP);
}
Expand Down
Expand Up @@ -108,8 +108,8 @@ public static boolean samletFeilutbetaltKanAutomatiskBehandles(Kravgrunnlag431 k
for (KravgrunnlagPeriode432 kgPeriode : kgPerioder) {
BigDecimal beløp = beløpUtleder.apply(kgPeriode);
if (isNotZero(beløp)) {
BigDecimal feilutbetaltBeløpPrVirkedag = beregnBeløpUtil.beregnBeløpPrVirkedag(beløp, kgPeriode.getPeriode());
sum = sum.add(beregnBeløpUtil.beregnBeløp(periode, kgPeriode.getPeriode(), feilutbetaltBeløpPrVirkedag));
BigDecimal feilutbetaltBeløpPrDag = beregnBeløpUtil.beregnBeløpPrDag(beløp, kgPeriode.getPeriode());
sum = sum.add(beregnBeløpUtil.beregnBeløp(periode, kgPeriode.getPeriode(), feilutbetaltBeløpPrDag));
}
}

Expand Down
Expand Up @@ -10,13 +10,14 @@
import java.util.SortedMap;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import no.nav.foreldrepenger.tilbakekreving.behandling.modell.LogiskPeriode;
import no.nav.foreldrepenger.tilbakekreving.behandlingskontroll.impl.BehandlingskontrollTjeneste;
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.behandling.Behandling;
Expand All @@ -25,6 +26,7 @@
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.behandling.aksjonspunkt.Venteårsak;
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.behandling.repository.BehandlingRepository;
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.behandling.repository.BehandlingRepositoryProvider;
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.fagsak.FagsakYtelseType;
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.historikk.HistorikkAktør;
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.historikk.HistorikkInnslagTekstBuilder;
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.historikk.HistorikkRepository;
Expand Down Expand Up @@ -77,7 +79,9 @@ public KravgrunnlagTjeneste(BehandlingRepositoryProvider repositoryProvider,


public List<LogiskPeriode> utledLogiskPeriode(Long behandlingId) {
return LogiskPeriodeTjeneste.utledLogiskPeriode(finnFeilutbetalingPrPeriode(behandlingId));
Behandling behandling = behandlingRepository.hentBehandling(behandlingId);
FagsakYtelseType fagsakYtelseType = behandling.getFagsak().getFagsakYtelseType();
return new LogiskPeriodeTjeneste(fagsakYtelseType).utledLogiskPeriode(finnFeilutbetalingPrPeriode(behandlingId));
}

private SortedMap<Periode, BigDecimal> finnFeilutbetalingPrPeriode(Long behandlingId) {
Expand Down
Expand Up @@ -9,11 +9,22 @@
import java.util.SortedMap;

import no.nav.foreldrepenger.tilbakekreving.behandling.modell.LogiskPeriode;
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.fagsak.FagsakYtelseType;
import no.nav.foreldrepenger.tilbakekreving.felles.Periode;

public class LogiskPeriodeTjeneste {

public static List<LogiskPeriode> utledLogiskPeriode(SortedMap<Periode, BigDecimal> feilutbetalingPrPeriode) {
private final boolean utbetalingMuligAlleDager;

LogiskPeriodeTjeneste(boolean utbetalingMuligAlleDager){
this.utbetalingMuligAlleDager = utbetalingMuligAlleDager;
}

public LogiskPeriodeTjeneste(FagsakYtelseType fagsakYtelseType) {
this(fagsakYtelseType == FagsakYtelseType.ENGANGSTØNAD || fagsakYtelseType == FagsakYtelseType.OMSORGSPENGER);
}

public List<LogiskPeriode> utledLogiskPeriode(SortedMap<Periode, BigDecimal> feilutbetalingPrPeriode) {
LocalDate førsteDag = null;
LocalDate sisteDag = null;
BigDecimal logiskPeriodeBeløp = BigDecimal.ZERO;
Expand All @@ -25,7 +36,7 @@ public static List<LogiskPeriode> utledLogiskPeriode(SortedMap<Periode, BigDecim
førsteDag = periode.getFom();
sisteDag = periode.getTom();
} else {
if (harUkedagerMellom(sisteDag, periode.getFom())) {
if (harUtbetalingsdagerMellom(sisteDag, periode.getFom())) {
resultat.add(LogiskPeriode.lagPeriode(førsteDag, sisteDag, logiskPeriodeBeløp));
førsteDag = periode.getFom();
logiskPeriodeBeløp = BigDecimal.ZERO;
Expand All @@ -40,13 +51,17 @@ public static List<LogiskPeriode> utledLogiskPeriode(SortedMap<Periode, BigDecim
return resultat;
}

private static boolean harUkedagerMellom(LocalDate dag1, LocalDate dag2) {
private boolean harUtbetalingsdagerMellom(LocalDate dag1, LocalDate dag2) {
if (!dag2.isAfter(dag1)) {
throw new IllegalArgumentException("dag2 må være etter dag1");
}
if (dag1.plusDays(1).equals(dag2)) {
return false;
}
if (utbetalingMuligAlleDager){
return true;
}

if (dag1.plusDays(2).equals(dag2) && (dag1.getDayOfWeek() == DayOfWeek.FRIDAY || dag1.getDayOfWeek() == DayOfWeek.SATURDAY)) {
return false;
}
Expand Down
Expand Up @@ -10,6 +10,7 @@
import org.junit.jupiter.api.Test;

import no.nav.foreldrepenger.tilbakekreving.behandling.modell.LogiskPeriode;
import no.nav.foreldrepenger.tilbakekreving.behandlingslager.fagsak.FagsakYtelseType;
import no.nav.foreldrepenger.tilbakekreving.felles.Periode;

class LogiskPeriodeTjenesteTest {
Expand All @@ -23,15 +24,15 @@ class LogiskPeriodeTjenesteTest {

@Test
void tom_input_skal_gi_tom_output() {
List<LogiskPeriode> resultat = LogiskPeriodeTjeneste.utledLogiskPeriode(InputBuilder.builder().build());
List<LogiskPeriode> resultat = new LogiskPeriodeTjeneste(FagsakYtelseType.FORELDREPENGER).utledLogiskPeriode(InputBuilder.builder().build());
Assertions.assertThat(resultat).isEmpty();
}

@Test
void en_periode_skal_fortsette_som_samme_periode() {
Periode periode1 = Periode.of(uke_1_onsdag, uke_1_lørdag);
SortedMap<Periode, BigDecimal> input = InputBuilder.builder().leggTil(periode1, BigDecimal.ONE).build();
List<LogiskPeriode> resultat = LogiskPeriodeTjeneste.utledLogiskPeriode(input);
List<LogiskPeriode> resultat = new LogiskPeriodeTjeneste(FagsakYtelseType.FORELDREPENGER).utledLogiskPeriode(input);
Assertions.assertThat(resultat).hasSize(1);
assertSamme(resultat.get(0), periode1, BigDecimal.ONE);
}
Expand All @@ -46,7 +47,7 @@ void en_periode_skal_fortsette_som_samme_periode() {
.leggTil(periode2, BigDecimal.ONE)
.leggTil(periode3, BigDecimal.ONE)
.build();
List<LogiskPeriode> resultat = LogiskPeriodeTjeneste.utledLogiskPeriode(input);
List<LogiskPeriode> resultat = new LogiskPeriodeTjeneste(FagsakYtelseType.FORELDREPENGER).utledLogiskPeriode(input);
Assertions.assertThat(resultat).hasSize(1);
assertSamme(resultat.get(0), Periode.of(periode1.getFom(), periode3.getTom()), BigDecimal.valueOf(3));
}
Expand All @@ -59,7 +60,7 @@ void en_periode_skal_fortsette_som_samme_periode() {
.leggTil(periode1, BigDecimal.ONE)
.leggTil(periode2, BigDecimal.ONE)
.build();
List<LogiskPeriode> resultat = LogiskPeriodeTjeneste.utledLogiskPeriode(input);
List<LogiskPeriode> resultat = new LogiskPeriodeTjeneste(FagsakYtelseType.FORELDREPENGER).utledLogiskPeriode(input);
Assertions.assertThat(resultat).hasSize(2);
assertSamme(resultat.get(0), periode1, BigDecimal.ONE);
assertSamme(resultat.get(1), periode2, BigDecimal.ONE);
Expand All @@ -73,7 +74,7 @@ void en_periode_skal_fortsette_som_samme_periode() {
.leggTil(periode1, BigDecimal.ONE)
.leggTil(periode2, BigDecimal.ONE)
.build();
List<LogiskPeriode> resultat = LogiskPeriodeTjeneste.utledLogiskPeriode(input);
List<LogiskPeriode> resultat = new LogiskPeriodeTjeneste(FagsakYtelseType.FORELDREPENGER).utledLogiskPeriode(input);
Assertions.assertThat(resultat).hasSize(1);
assertSamme(resultat.get(0), Periode.of(uke_1_onsdag, uke_2_mandag), BigDecimal.valueOf(2));
}
Expand All @@ -86,7 +87,7 @@ void en_periode_skal_fortsette_som_samme_periode() {
.leggTil(periode1, BigDecimal.ONE)
.leggTil(periode2, BigDecimal.ONE)
.build();
List<LogiskPeriode> resultat = LogiskPeriodeTjeneste.utledLogiskPeriode(input);
List<LogiskPeriode> resultat = new LogiskPeriodeTjeneste(FagsakYtelseType.FORELDREPENGER).utledLogiskPeriode(input);
Assertions.assertThat(resultat).hasSize(1);
assertSamme(resultat.get(0), Periode.of(uke_1_onsdag, uke_2_mandag), BigDecimal.valueOf(2));
}
Expand All @@ -99,11 +100,38 @@ void en_periode_skal_fortsette_som_samme_periode() {
.leggTil(periode1, BigDecimal.ONE)
.leggTil(periode2, BigDecimal.ONE)
.build();
List<LogiskPeriode> resultat = LogiskPeriodeTjeneste.utledLogiskPeriode(input);
List<LogiskPeriode> resultat = new LogiskPeriodeTjeneste(FagsakYtelseType.FORELDREPENGER).utledLogiskPeriode(input);
Assertions.assertThat(resultat).hasSize(1);
assertSamme(resultat.get(0), Periode.of(uke_1_onsdag, uke_2_mandag), BigDecimal.valueOf(2));
}

@Test
void perioder_som_er_skilt_med_en_lørdag_skal_ikke_slås_sammen_for_OMP() {
Periode periode1 = Periode.of(uke_1_onsdag, uke_1_fredag);
Periode periode2 = Periode.of(uke_1_søndag, uke_2_mandag);
SortedMap<Periode, BigDecimal> input = InputBuilder.builder()
.leggTil(periode1, BigDecimal.ONE)
.leggTil(periode2, BigDecimal.ONE)
.build();
List<LogiskPeriode> resultat = new LogiskPeriodeTjeneste(FagsakYtelseType.OMSORGSPENGER).utledLogiskPeriode(input);
Assertions.assertThat(resultat).hasSize(2);
assertSamme(resultat.get(0), periode1, BigDecimal.valueOf(1));
assertSamme(resultat.get(1), periode2, BigDecimal.valueOf(1));
}

@Test
void perioder_som_er_skilt_med_en_søndag_skal_ikke_slås_sammen_for_OMP() {
Periode periode1 = Periode.of(uke_1_onsdag, uke_1_lørdag);
Periode periode2 = Periode.of(uke_2_mandag, uke_2_mandag);
SortedMap<Periode, BigDecimal> input = InputBuilder.builder()
.leggTil(periode1, BigDecimal.ONE)
.leggTil(periode2, BigDecimal.ONE)
.build();
List<LogiskPeriode> resultat = new LogiskPeriodeTjeneste(FagsakYtelseType.OMSORGSPENGER).utledLogiskPeriode(input);
Assertions.assertThat(resultat).hasSize(2);
assertSamme(resultat.get(0), periode1, BigDecimal.valueOf(1));
assertSamme(resultat.get(1), periode2, BigDecimal.valueOf(1));
}

static void assertSamme(LogiskPeriode ub, Periode periode, BigDecimal verdi) {
Assertions.assertThat(Periode.of(ub.getFom(), ub.getTom())).isEqualTo(periode);
Expand Down

0 comments on commit a979c96

Please sign in to comment.