diff --git a/behandlingslager/domene/src/main/java/no/nav/foreldrepenger/tilbakekreving/grunnlag/KravgrunnlagValidator.java b/behandlingslager/domene/src/main/java/no/nav/foreldrepenger/tilbakekreving/grunnlag/KravgrunnlagValidator.java index 2af6c6a38..569b5a618 100644 --- a/behandlingslager/domene/src/main/java/no/nav/foreldrepenger/tilbakekreving/grunnlag/KravgrunnlagValidator.java +++ b/behandlingslager/domene/src/main/java/no/nav/foreldrepenger/tilbakekreving/grunnlag/KravgrunnlagValidator.java @@ -10,8 +10,10 @@ import java.util.function.Consumer; import java.util.stream.Collectors; +import no.nav.foreldrepenger.tilbakekreving.behandlingslager.fagsak.FagOmrådeKode; import no.nav.foreldrepenger.tilbakekreving.domene.typer.Henvisning; import no.nav.foreldrepenger.tilbakekreving.felles.Periode; +import no.nav.foreldrepenger.tilbakekreving.felles.Ukedager; import no.nav.foreldrepenger.tilbakekreving.grunnlag.kodeverk.KlasseType; import no.nav.vedtak.exception.VLException; @@ -21,15 +23,16 @@ private KravgrunnlagValidator() { } private static final List> VALIDATORER = List.of( - KravgrunnlagValidator::validerPeriodeInnenforMåned, - KravgrunnlagValidator::validerOverlappendePerioder, - KravgrunnlagValidator::validerSkatt, - KravgrunnlagValidator::validerPerioderHarFeilutbetalingPostering, - KravgrunnlagValidator::validerPerioderHarYtelPostering, - KravgrunnlagValidator::validerPerioderHarFeilPosteringMedNegativFeilutbetaltBeløp, - KravgrunnlagValidator::validerYtelseMotFeilutbetaling, - KravgrunnlagValidator::validerYtelPosteringTilbakekrevesMotNyttOgOpprinneligUtbetalt, - KravgrunnlagValidator::validerReferanse + KravgrunnlagValidator::validerPeriodeInnenforMåned, + KravgrunnlagValidator::validerOverlappendePerioder, + KravgrunnlagValidator::validerSkatt, + KravgrunnlagValidator::validerPerioderHarFeilutbetalingPostering, + KravgrunnlagValidator::validerPerioderHarYtelPostering, + KravgrunnlagValidator::validerPerioderHarFeilPosteringMedNegativFeilutbetaltBeløp, + KravgrunnlagValidator::validerYtelseMotFeilutbetaling, + KravgrunnlagValidator::validerYtelPosteringTilbakekrevesMotNyttOgOpprinneligUtbetalt, + KravgrunnlagValidator::validerReferanse, + KravgrunnlagValidator::validerPeriodeMedFeilutbetalingHarVirkedager ); public static void validerGrunnlag(Kravgrunnlag431 kravgrunnlag) throws UgyldigKravgrunnlagException { @@ -76,9 +79,9 @@ private static void validerPerioderHarYtelPostering(Kravgrunnlag431 kravgrunnlag private static void validerOverlappendePerioder(Kravgrunnlag431 kravgrunnlag) { List sortertePerioder = kravgrunnlag.getPerioder().stream() - .map(KravgrunnlagPeriode432::getPeriode) - .sorted(Comparator.comparing(Periode::getFom)) - .toList(); + .map(KravgrunnlagPeriode432::getPeriode) + .sorted(Comparator.comparing(Periode::getFom)) + .toList(); for (int i = 1; i < sortertePerioder.size(); i++) { Periode forrige = sortertePerioder.get(i - 1); Periode denne = sortertePerioder.get(i); @@ -90,8 +93,8 @@ private static void validerOverlappendePerioder(Kravgrunnlag431 kravgrunnlag) { private static void validerSkatt(Kravgrunnlag431 kravgrunnlag) { Map> grupppertPåMåned = kravgrunnlag.getPerioder() - .stream() - .collect(Collectors.groupingBy(p -> tilMåned(p.getPeriode()))); + .stream() + .collect(Collectors.groupingBy(p -> tilMåned(p.getPeriode()))); for (Map.Entry> entry : grupppertPåMåned.entrySet()) { validerSkattForPeriode(entry.getKey(), entry.getValue()); @@ -138,17 +141,18 @@ private static void validerSkattForPeriode(YearMonth måned, List KlasseType.YTEL.equals(b.getKlasseType())) - .map(KravgrunnlagBelop433::getTilbakekrevesBelop) - .reduce(BigDecimal::add) - .orElse(BigDecimal.ZERO); + .filter(b -> KlasseType.YTEL.equals(b.getKlasseType())) + .map(KravgrunnlagBelop433::getTilbakekrevesBelop) + .reduce(BigDecimal::add) + .orElse(BigDecimal.ZERO); BigDecimal sumNyttBelopFraFeilposteringer = periode.getKravgrunnlagBeloper433().stream() - .filter(b -> KlasseType.FEIL.equals(b.getKlasseType())) - .map(KravgrunnlagBelop433::getNyBelop) - .reduce(BigDecimal::add) - .orElse(BigDecimal.ZERO); + .filter(b -> KlasseType.FEIL.equals(b.getKlasseType())) + .map(KravgrunnlagBelop433::getNyBelop) + .reduce(BigDecimal::add) + .orElse(BigDecimal.ZERO); if (sumNyttBelopFraFeilposteringer.compareTo(sumTilbakekrevesFraYtelsePosteringer) != 0) { - throw KravgrunnlagFeil.feilYtelseEllerFeilutbetaling(kravgrunnlag.getEksternKravgrunnlagId(), periode.getPeriode(), sumTilbakekrevesFraYtelsePosteringer, sumNyttBelopFraFeilposteringer); + throw KravgrunnlagFeil.feilYtelseEllerFeilutbetaling(kravgrunnlag.getEksternKravgrunnlagId(), periode.getPeriode(), + sumTilbakekrevesFraYtelsePosteringer, sumNyttBelopFraFeilposteringer); } } } @@ -160,11 +164,29 @@ private static void validerYtelPosteringTilbakekrevesMotNyttOgOpprinneligUtbetal BigDecimal diff = kgBeløp.getOpprUtbetBelop().subtract(kgBeløp.getNyBelop()); if (kgBeløp.getTilbakekrevesBelop().compareTo(diff) > 0) { throw KravgrunnlagFeil.ytelPosteringHvorTilbakekrevesIkkeStemmerMedNyttOgOpprinneligBeløp( - kravgrunnlag.getEksternKravgrunnlagId(), - periode.getPeriode(), - kgBeløp.getTilbakekrevesBelop(), - kgBeløp.getNyBelop(), - kgBeløp.getOpprUtbetBelop()); + kravgrunnlag.getEksternKravgrunnlagId(), + periode.getPeriode(), + kgBeløp.getTilbakekrevesBelop(), + kgBeløp.getNyBelop(), + kgBeløp.getOpprUtbetBelop()); + } + } + } + } + } + + private static void validerPeriodeMedFeilutbetalingHarVirkedager(Kravgrunnlag431 kravgrunnlag) { + if (kravgrunnlag.getFagOmrådeKode() == FagOmrådeKode.ENGANGSSTØNAD) { + return; //OK med engangssønad i helg + } + for (KravgrunnlagPeriode432 periode : kravgrunnlag.getPerioder()) { + if (Ukedager.beregnAntallVirkedager(periode.getPeriode()) == 0) { + for (KravgrunnlagBelop433 kgBeløp : periode.getKravgrunnlagBeloper433()) { + if (KlasseType.YTEL.equals(kgBeløp.getKlasseType()) && kgBeløp.getTilbakekrevesBelop().signum() != 0) { + throw KravgrunnlagFeil.feilutbetaltPeriodeUtenVirkedager( + kravgrunnlag.getEksternKravgrunnlagId(), + periode.getPeriode(), + kgBeløp.getTilbakekrevesBelop()); } } } @@ -185,27 +207,35 @@ public UgyldigKravgrunnlagException(String kode, String message) { public static class KravgrunnlagFeil { static UgyldigKravgrunnlagException manglerFelt(String felt, Periode periode) { - return new UgyldigKravgrunnlagException("FPT-879715", String.format("Ugyldig kravgrunnlag. Mangler forventet felt %s for periode %s.", felt, periode)); + return new UgyldigKravgrunnlagException("FPT-879715", + String.format("Ugyldig kravgrunnlag. Mangler forventet felt %s for periode %s.", felt, periode)); } static UgyldigKravgrunnlagException manglerReferanse(String kravgrunnlagId) { - return new UgyldigKravgrunnlagException("FPT-879716", String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Mangler referanse.", kravgrunnlagId)); + return new UgyldigKravgrunnlagException("FPT-879716", + String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Mangler referanse.", kravgrunnlagId)); } static UgyldigKravgrunnlagException overlappendePerioder(String kravgrunnlagId, Periode a, Periode b) { - return new UgyldigKravgrunnlagException("FPT-936521", String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Overlappende perioder %s og %s.", kravgrunnlagId, a, b)); + return new UgyldigKravgrunnlagException("FPT-936521", + String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Overlappende perioder %s og %s.", kravgrunnlagId, a, b)); } static UgyldigKravgrunnlagException manglerKlasseTypeFeil(String kravgrunnlagId, Periode periode) { - return new UgyldigKravgrunnlagException("FPT-727260", String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Perioden %s mangler postering med klasseType=FEIL.", kravgrunnlagId, periode)); + return new UgyldigKravgrunnlagException("FPT-727260", + String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Perioden %s mangler postering med klasseType=FEIL.", kravgrunnlagId, + periode)); } static UgyldigKravgrunnlagException manglerKlasseTypeYtel(String kravgrunnlagId, Periode periode) { - return new UgyldigKravgrunnlagException("FPT-727261", String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Perioden %s mangler postering med klasseType=YTEL.", kravgrunnlagId, periode)); + return new UgyldigKravgrunnlagException("FPT-727261", + String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Perioden %s mangler postering med klasseType=YTEL.", kravgrunnlagId, + periode)); } static UgyldigKravgrunnlagException periodeIkkInnenforMåned(String kravgrunnlagId, Periode periode) { - return new UgyldigKravgrunnlagException("FPT-438893", String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Perioden %s er ikke innenfor en kalendermåned.", kravgrunnlagId, periode)); + return new UgyldigKravgrunnlagException("FPT-438893", + String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Perioden %s er ikke innenfor en kalendermåned.", kravgrunnlagId, periode)); } static UgyldigKravgrunnlagException manglerMaksSkatt(YearMonth måned) { @@ -213,23 +243,47 @@ static UgyldigKravgrunnlagException manglerMaksSkatt(YearMonth måned) { } static UgyldigKravgrunnlagException feilSkatt(YearMonth måned) { - return new UgyldigKravgrunnlagException("FPT-560295", String.format("Ugyldig kravgrunnlag. For måned %s er opplyses ulike verdier maks skatt i ulike perioder", måned)); + return new UgyldigKravgrunnlagException("FPT-560295", + String.format("Ugyldig kravgrunnlag. For måned %s er opplyses ulike verdier maks skatt i ulike perioder", måned)); } static UgyldigKravgrunnlagException feilSkatt(YearMonth måned, BigDecimal maxSkatt, BigDecimal maxUtregnbarSkatt) { - return new UgyldigKravgrunnlagException("FPT-930235", String.format("Ugyldig kravgrunnlag. For måned %s er maks skatt %s, men maks tilbakekreving ganget med skattesats blir %s", måned, maxSkatt, maxUtregnbarSkatt)); + return new UgyldigKravgrunnlagException("FPT-930235", + String.format("Ugyldig kravgrunnlag. For måned %s er maks skatt %s, men maks tilbakekreving ganget med skattesats blir %s", måned, + maxSkatt, maxUtregnbarSkatt)); + } + + static UgyldigKravgrunnlagException feilYtelseEllerFeilutbetaling(String kravgrunnlagId, + Periode periode, + BigDecimal sumTilbakekrevingYtel, + BigDecimal belopNyttFraFeilpostering) { + return new UgyldigKravgrunnlagException("FPT-361605", String.format( + "Ugyldig kravgrunnlag for kravgrunnlagId %s. For periode %s er sum tilkakekreving fra YTEL %s, mens belopNytt i FEIL er %s. Det er forventet at disse er like.", + kravgrunnlagId, periode, sumTilbakekrevingYtel, belopNyttFraFeilpostering)); } - static UgyldigKravgrunnlagException feilYtelseEllerFeilutbetaling(String kravgrunnlagId, Periode periode, BigDecimal sumTilbakekrevingYtel, BigDecimal belopNyttFraFeilpostering) { - return new UgyldigKravgrunnlagException("FPT-361605", String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. For periode %s er sum tilkakekreving fra YTEL %s, mens belopNytt i FEIL er %s. Det er forventet at disse er like.", kravgrunnlagId, periode, sumTilbakekrevingYtel, belopNyttFraFeilpostering)); + static UgyldigKravgrunnlagException ytelPosteringHvorTilbakekrevesIkkeStemmerMedNyttOgOpprinneligBeløp(String kravgrunnlagId, + Periode periode, + BigDecimal tilbakekrevesBeløp, + BigDecimal nyttBeløp, + BigDecimal opprinneligBeløp) { + return new UgyldigKravgrunnlagException("FPT-615761", String.format( + "Ugyldig kravgrunnlag for kravgrunnlagId %s. For perioden %s finnes YTEL-postering med tilbakekrevesBeløp %s som er større enn differanse mellom nyttBeløp %s og opprinneligBeløp %s", + kravgrunnlagId, periode, tilbakekrevesBeløp, nyttBeløp, opprinneligBeløp)); } - static UgyldigKravgrunnlagException ytelPosteringHvorTilbakekrevesIkkeStemmerMedNyttOgOpprinneligBeløp(String kravgrunnlagId, Periode periode, BigDecimal tilbakekrevesBeløp, BigDecimal nyttBeløp, BigDecimal opprinneligBeløp) { - return new UgyldigKravgrunnlagException("FPT-615761", String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. For perioden %s finnes YTEL-postering med tilbakekrevesBeløp %s som er større enn differanse mellom nyttBeløp %s og opprinneligBeløp %s", kravgrunnlagId, periode, tilbakekrevesBeløp, nyttBeløp, opprinneligBeløp)); + static UgyldigKravgrunnlagException feilutbetaltPeriodeUtenVirkedager(String kravgrunnlagId, + Periode periode, + BigDecimal tilbakekrevesBeløp) { + return new UgyldigKravgrunnlagException("FPT-25803", String.format( + "Ugyldig kravgrunnlag for kravgrunnlagId %s. For perioden %s som kun inneholder helg, finnes YTEL-postering med tilbakekrevesBeløp %s som er større enn 0", + kravgrunnlagId, periode, tilbakekrevesBeløp)); } static UgyldigKravgrunnlagException feilBeløp(String kravgrunnlagId, Periode periode) { - return new UgyldigKravgrunnlagException("FPT-930247", String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Perioden %s har FEIL postering med negativ beløp", kravgrunnlagId, periode)); + return new UgyldigKravgrunnlagException("FPT-930247", + String.format("Ugyldig kravgrunnlag for kravgrunnlagId %s. Perioden %s har FEIL postering med negativ beløp", kravgrunnlagId, + periode)); } } }