Skip to content

Commit

Permalink
Gjør utregn av skatteperiode smartere
Browse files Browse the repository at this point in the history
  • Loading branch information
hestad committed Jan 3, 2024
1 parent e5c602f commit bcf53c6
Show file tree
Hide file tree
Showing 12 changed files with 222 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class StubClientsBuilder(
klageClient = KlageClientStub.also { log.warn("********** Using stub for ${KlageClientStub::class.java} **********") },
queryJournalpostClient = QueryJournalpostClientStub.also { log.warn("********** Using stub for ${QueryJournalpostClientStub::class.java} **********") },
tilbakekrevingClient = TilbakekrevingClientStub(clock).also { log.warn("********** Using stub for ${TilbakekrevingClient::class.java} **********") },
skatteOppslag = SkatteClientStub().also { log.warn("********** Using stub for ${SkatteClient::class.java} **********") },
skatteOppslag = SkatteClientStub(clock).also { log.warn("********** Using stub for ${SkatteClient::class.java} **********") },
)
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package no.nav.su.se.bakover.client.skatteetaten

import arrow.core.NonEmptyList
import arrow.core.left
import arrow.core.right
import no.nav.su.se.bakover.common.extensions.mars
import no.nav.su.se.bakover.common.extensions.toNonEmptyList
import no.nav.su.se.bakover.common.person.Fnr
import no.nav.su.se.bakover.common.tid.YearRange
import no.nav.su.se.bakover.domain.skatt.KunneIkkeHenteSkattemelding
import no.nav.su.se.bakover.domain.skatt.SamletSkattegrunnlagForÅr
import no.nav.su.se.bakover.domain.skatt.SamletSkattegrunnlagForÅrOgStadie
import no.nav.su.se.bakover.domain.skatt.Skattegrunnlag
import no.nav.su.se.bakover.domain.skatt.Skatteoppslag
import java.time.Clock
import java.time.LocalDate
import java.time.Year

class SkatteClientStub() : Skatteoppslag {
class SkatteClientStub(private val clock: Clock) : Skatteoppslag {

override fun hentSamletSkattegrunnlag(
fnr: Fnr,
år: Year,
Expand Down Expand Up @@ -50,17 +56,27 @@ class SkatteClientStub() : Skatteoppslag {
// }
}

private fun samletYearr: Year) = SamletSkattegrunnlagForÅr(
år = år,
utkast = SamletSkattegrunnlagForÅrOgStadie.Utkast(
oppslag = årsgrunnlag().right(),
inntektsår = år,
),
oppgjør = SamletSkattegrunnlagForÅrOgStadie.Oppgjør(
oppslag = årsgrunnlag().right(),
inntektsår = år,
),
)
private fun samletYearr: Year): SamletSkattegrunnlagForÅr {
val currentYear = Year.now(clock)
val grenseverdi = 7.mars(currentYear.value)
val= LocalDate.now(clock)
val oppslag = when {
år < currentYear.minusYears(1) -> årsgrunnlag().right()
år < currentYear &&>= grenseverdi -> årsgrunnlag().right()
else -> KunneIkkeHenteSkattemelding.FinnesIkke.left()
}
return SamletSkattegrunnlagForÅr(
år = år,
utkast = SamletSkattegrunnlagForÅrOgStadie.Utkast(
oppslag = oppslag,
inntektsår = år,
),
oppgjør = SamletSkattegrunnlagForÅrOgStadie.Oppgjør(
oppslag = oppslag,
inntektsår = år,
),
)
}

private fun årsgrunnlag() = Skattegrunnlag.SkattegrunnlagForÅr(
oppgjørsdato = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,27 @@ fun YearRange.krympTilØvreGrense(øvreGrense: Year): YearRange {
}
}

/**
* Utivder nedre grense hvis nedre grense er før start.
*/
fun YearRange.utvidNedreGrense(nedreGrense: Year): YearRange {
return if (nedreGrense >= start) {
this
} else {
YearRange(nedreGrense, endInclusive)
}
}

fun YearRange.krymptTilNedreGrense(nedreGrense: Year): YearRange {
return if (nedreGrense > endInclusive) {
YearRange(nedreGrense, nedreGrense)
} else {
YearRange(max(start, nedreGrense), endInclusive)
}
}

fun min(y1: Year, y2: Year): Year = if (y1.value <= y2.value) y1 else y2
fun max(y1: Year, y2: Year): Year = if (y1.value > y2.value) y1 else y2

fun min(a: YearRange, b: YearRange): YearRange = when {
a.start < b.start -> a
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package no.nav.su.se.bakover.domain.skatt

import no.nav.su.se.bakover.common.tid.YearRange
import no.nav.su.se.bakover.common.tid.krympTilØvreGrense
import no.nav.su.se.bakover.common.tid.utvidNedreGrense
import no.nav.su.se.bakover.domain.søknadsbehandling.stønadsperiode.Stønadsperiode
import java.time.Clock
import java.time.Year

/**
* @return Skatteperiode for stønadsperiode. Hvis stønadsperiode er null, returneres skatteperiode for de tre siste årene.
*/
fun Stønadsperiode?.regnUtSkatteperiodeForStønadsperiode(clock: Clock): YearRange {
val iÅr = Year.now(clock)
val iForFjor = iÅr.minusYears(2)
if (this == null) {
return YearRange(iForFjor, iÅr)
}

return this
.toYearRange()
.krympTilØvreGrense(iÅr)
.utvidNedreGrense(iForFjor)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package no.nav.su.se.bakover.domain.skatt

import io.kotest.matchers.shouldBe
import no.nav.su.se.bakover.common.extensions.januar
import no.nav.su.se.bakover.common.tid.YearRange
import no.nav.su.se.bakover.common.tid.periode.desember
import no.nav.su.se.bakover.common.tid.periode.januar
import no.nav.su.se.bakover.common.tid.periode.juli
import no.nav.su.se.bakover.common.tid.periode.juni
import no.nav.su.se.bakover.domain.søknadsbehandling.stønadsperiode.Stønadsperiode
import no.nav.su.se.bakover.test.fixedClockAt
import org.junit.jupiter.api.Test
import java.time.Year

internal class RegnUtSkatteperiodeForStønadsperiodeKtTest {
private val jan24 = fixedClockAt(1.januar(2024))

@Test
fun `stønadsperiode null`() {
null.regnUtSkatteperiodeForStønadsperiode(jan24).shouldBe(
YearRange(Year.of(2022), Year.of(2024)),
)
}

@Test
fun `stønadsperiode 21`() {
val stønadsperiode = Stønadsperiode.create(januar(2021)..desember(2021))
stønadsperiode.regnUtSkatteperiodeForStønadsperiode(jan24).shouldBe(
YearRange(Year.of(2021), Year.of(2021)),
)
}

@Test
fun `stønadsperiode 21 og 22`() {
val stønadsperiode = Stønadsperiode.create(juli(2021)..juni(2022))
stønadsperiode.regnUtSkatteperiodeForStønadsperiode(jan24).shouldBe(
YearRange(Year.of(2021), Year.of(2022)),
)
}

@Test
fun `stønadsperiode 22`() {
val stønadsperiode = Stønadsperiode.create(januar(2022)..desember(2022))
stønadsperiode.regnUtSkatteperiodeForStønadsperiode(jan24).shouldBe(
YearRange(Year.of(2022), Year.of(2022)),
)
}

@Test
fun `stønadsperiode 22 og 23`() {
val stønadsperiode = Stønadsperiode.create(juli(2022)..juni(2023))
stønadsperiode.regnUtSkatteperiodeForStønadsperiode(jan24).shouldBe(
YearRange(Year.of(2022), Year.of(2023)),
)
}

@Test
fun `stønadsperiode 23`() {
val stønadsperiode = Stønadsperiode.create(januar(2023)..desember(2023))
stønadsperiode.regnUtSkatteperiodeForStønadsperiode(jan24).shouldBe(
YearRange(Year.of(2022), Year.of(2023)),
)
}

@Test
fun `stønadsperiode 23 og 24`() {
val stønadsperiode = Stønadsperiode.create(juli(2023)..juni(2024))
stønadsperiode.regnUtSkatteperiodeForStønadsperiode(jan24).shouldBe(
YearRange(Year.of(2022), Year.of(2024)),
)
}

@Test
fun `stønadsperiode 24`() {
val stønadsperiode = Stønadsperiode.create(januar(2024)..desember(2024))
stønadsperiode.regnUtSkatteperiodeForStønadsperiode(jan24).shouldBe(
YearRange(Year.of(2022), Year.of(2024)),
)
}

@Test
fun `stønadsperiode 25`() {
// Kun tenkt eksempel fram i tid (merk at dette skjer i jan 24). Dette skal ikke skje i praksis.
val stønadsperiode = Stønadsperiode.create(januar(2025)..desember(2025))
stønadsperiode.regnUtSkatteperiodeForStønadsperiode(jan24).shouldBe(
YearRange(Year.of(2022), Year.of(2024)),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import no.nav.su.se.bakover.common.tid.YearRange
import no.nav.su.se.bakover.domain.skatt.Skattegrunnlag

interface SkatteService {
/**
* Ikke i bruk. TODO jah: Slett?
*/
fun hentSamletSkattegrunnlag(
fnr: Fnr,
saksbehandler: NavIdentBruker.Saksbehandler,
Expand All @@ -19,6 +22,9 @@ interface SkatteService {
yearRange: YearRange,
): Skattegrunnlag

/**
* Brukes for frioppslag på skattemelding.
*/
fun hentOgLagSkattePdf(request: FrioppslagSkattRequest): Either<KunneIkkeHenteOgLagePdfAvSkattegrunnlag, PdfA>
fun hentLagOgJournalførSkattePdf(request: FrioppslagSkattRequest): Either<KunneIkkeGenerereSkattePdfOgJournalføre, PdfA>
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import no.nav.su.se.bakover.common.persistence.SessionFactory
import no.nav.su.se.bakover.common.persistence.TransactionContext
import no.nav.su.se.bakover.common.person.Fnr
import no.nav.su.se.bakover.common.tid.YearRange
import no.nav.su.se.bakover.common.tid.krympTilØvreGrense
import no.nav.su.se.bakover.common.tid.toRange
import no.nav.su.se.bakover.domain.Sak
import no.nav.su.se.bakover.domain.behandling.BehandlingMetrics
import no.nav.su.se.bakover.domain.grunnlag.Bosituasjon.Companion.harEPS
Expand All @@ -29,6 +27,7 @@ import no.nav.su.se.bakover.domain.revurdering.vilkår.bosituasjon.LeggTilBositu
import no.nav.su.se.bakover.domain.sak.SakService
import no.nav.su.se.bakover.domain.sak.lagNyUtbetaling
import no.nav.su.se.bakover.domain.skatt.Skattegrunnlag
import no.nav.su.se.bakover.domain.skatt.regnUtSkatteperiodeForStønadsperiode
import no.nav.su.se.bakover.domain.statistikk.StatistikkEvent
import no.nav.su.se.bakover.domain.statistikk.StatistikkEventObserver
import no.nav.su.se.bakover.domain.statistikk.notify
Expand Down Expand Up @@ -98,7 +97,6 @@ import satser.domain.SatsFactory
import vilkår.formue.domain.FormuegrenserFactory
import økonomi.domain.utbetaling.UtbetalingsinstruksjonForEtterbetalinger
import java.time.Clock
import java.time.Year
import java.util.UUID
import kotlin.reflect.KClass

Expand Down Expand Up @@ -787,7 +785,8 @@ class SøknadsbehandlingServiceImpl(
saksbehandler: NavIdentBruker.Saksbehandler,
samletSkattegrunnlag: (Fnr, NavIdentBruker.Saksbehandler, YearRange) -> Skattegrunnlag,
clock: Clock,
): Skattegrunnlag = samletSkattegrunnlag(fnr, saksbehandler, getYearRangeForSkatt(clock))
): Skattegrunnlag =
samletSkattegrunnlag(fnr, saksbehandler, stønadsperiode.regnUtSkatteperiodeForStønadsperiode(clock))

private fun Søknadsbehandling.hentSkattegrunnlagForEps(
saksbehandler: NavIdentBruker.Saksbehandler,
Expand All @@ -797,15 +796,9 @@ class SøknadsbehandlingServiceImpl(
samletSkattegrunnlag(
grunnlagsdata.bosituasjon.singleFullstendigEpsOrNull()!!.fnr,
saksbehandler,
getYearRangeForSkatt(clock),
stønadsperiode.regnUtSkatteperiodeForStønadsperiode(clock),
)
} else {
null
}

private fun Søknadsbehandling.getYearRangeForSkatt(clock: Clock): YearRange {
return Year.now(clock).minusYears(1).let {
stønadsperiode?.toYearRange()?.krympTilØvreGrense(it) ?: it.toRange()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package no.nav.su.se.bakover.service.søknadsbehandling
import io.kotest.assertions.arrow.core.shouldBeLeft
import io.kotest.assertions.arrow.core.shouldBeRight
import io.kotest.matchers.shouldBe
import no.nav.su.se.bakover.common.tid.toRange
import no.nav.su.se.bakover.common.tid.YearRange
import no.nav.su.se.bakover.domain.grunnlag.EksterneGrunnlagSkatt
import no.nav.su.se.bakover.domain.grunnlag.StøtterHentingAvEksternGrunnlag
import no.nav.su.se.bakover.domain.søknadsbehandling.SøknadsbehandlingRepo
Expand All @@ -18,7 +18,6 @@ import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyNoMoreInteractions
import java.time.Year
Expand Down Expand Up @@ -47,7 +46,7 @@ class SøknadsbehandlingSkattTest {
verify(skatteServiceMock).hentSamletSkattegrunnlagForÅr(
argThat { it shouldBe søknadsbehandling.fnr },
argThat { it shouldBe saksbehandler },
argThat { it shouldBe Year.of(2020).toRange() },
argThat { it shouldBe YearRange(Year.of(2019), Year.of(2021)) },
)

verify(søknadsbehandlingRepoMock).lagre(
Expand Down
39 changes: 27 additions & 12 deletions test-common/src/main/kotlin/JSONAssertEx.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package no.nav.su.se.bakover.test

import org.json.JSONObject
import org.skyscreamer.jsonassert.Customization
import org.skyscreamer.jsonassert.JSONAssert
import org.skyscreamer.jsonassert.JSONCompareMode
Expand All @@ -13,16 +14,30 @@ fun jsonAssertEquals(
actual: String,
vararg ignorePaths: String,
) {
JSONAssert.assertEquals(
expected,
actual,
CustomComparator(
JSONCompareMode.STRICT,
*ignorePaths.map {
Customization(
it,
) { _, _ -> true }
}.toTypedArray(),
),
)
try {
JSONAssert.assertEquals(
expected,
actual,
CustomComparator(
JSONCompareMode.STRICT,
*ignorePaths.map {
Customization(
it,
) { _, _ -> true }
}.toTypedArray(),
),
)
} catch (error: AssertionError) {
throw AssertionError(
"""
|JSONAssert.assertEquals failed:
|
|Expected: ${JSONObject(expected).toString(2)}
|
|Actual: ${JSONObject(actual).toString(2)}
|
|Error: ${error.message}
""".trimMargin(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ data class TestClientsBuilder(
klageClient = KlageClientStub,
queryJournalpostClient = QueryJournalpostClientStub,
tilbakekrevingClient = TilbakekrevingClientStub(clock),
skatteOppslag = SkatteClientStub(),
skatteOppslag = SkatteClientStub(clock),
)

override fun build(applicationConfig: ApplicationConfig): Clients = testClients
Expand Down
Loading

0 comments on commit bcf53c6

Please sign in to comment.