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

Automatisk utbetaling #130

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 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
@@ -1,5 +1,6 @@
package no.nav.arbeidsgiver.tiltakrefusjon

import no.nav.arbeidsgiver.tiltakrefusjon.automatisk_utbetaling.AutomatiskInnsendingService
import no.nav.arbeidsgiver.tiltakrefusjon.autorisering.ADMIN_BRUKER
import no.nav.arbeidsgiver.tiltakrefusjon.leader.LeaderPodCheck
import no.nav.arbeidsgiver.tiltakrefusjon.okonomi.KontoregisterServiceImpl
Expand Down Expand Up @@ -40,18 +41,19 @@ class AdminController(
val leaderPodCheck: LeaderPodCheck,
val refusjonKafkaProducer: RefusjonKafkaProducer?,
val kontoregisterService: KontoregisterServiceImpl?,
val automatiskInnsendingService: AutomatiskInnsendingService
) {
val logger = LoggerFactory.getLogger(javaClass)

@Unprotected
@GetMapping("kontoregister/{orgnr}")
fun kontoregisterKall(@PathVariable orgnr: String): String{
fun kontoregisterKall(@PathVariable orgnr: String): String {
return "Bank kontonummer: " + kontoregisterService?.hentBankkontonummer(orgnr)
}

@Unprotected
@GetMapping("/")
fun hjem(): String?{
fun hjem(): String? {
return "Velkommen til Refusjon Admin API"
}

Expand Down Expand Up @@ -184,13 +186,13 @@ class AdminController(
@Unprotected
@PostMapping("sjekk-for-klar-for-innsending")
fun sjekkForKlarforInnsending() {
StatusJobb(refusjonRepository, leaderPodCheck).sjekkOmKlarForInnsending()
StatusJobb(refusjonRepository, leaderPodCheck, automatiskInnsendingService).fraForTidligTilKlarForInnsending()
}

@Unprotected
@PostMapping("sjekk-for-utgått")
fun sjekkForUtgått() {
StatusJobb(refusjonRepository, leaderPodCheck).sjekkOmUtgått()
StatusJobb(refusjonRepository, leaderPodCheck, automatiskInnsendingService).fraKlarForInnsendingTilUtgått()
}

@Unprotected
Expand Down Expand Up @@ -274,7 +276,7 @@ class AdminController(
if (refusjon.refusjonsgrunnlag.refusjonsgrunnlagetErNullSomIZero()) {
refusjonKafkaProducer!!.annullerTilskuddsperiodeEtterNullEllerMinusBeløp(refusjon, MidlerFrigjortÅrsak.REFUSJON_GODKJENT_NULL_BELØP)
return ResponseEntity.ok("Sendt godkjent nullbeløp-melding for ${refusjon.id}")
} else if (!refusjon.refusjonsgrunnlag.refusjonsgrunnlagetErPositivt()) {
} else if (refusjon.refusjonsgrunnlag.refusjonsgrunnlagetErNegativt()) {
refusjonKafkaProducer!!.annullerTilskuddsperiodeEtterNullEllerMinusBeløp(refusjon, MidlerFrigjortÅrsak.REFUSJON_MINUS_BELØP)
return ResponseEntity.ok("Sendt godkjent minusbeløp-melding for ${refusjon.id}")
} else {
Expand All @@ -297,13 +299,20 @@ class AdminController(
if (refusjon.refusjonsgrunnlag.refusjonsgrunnlagetErNullSomIZero()) {
refusjonKafkaProducer!!.annullerTilskuddsperiodeEtterNullEllerMinusBeløp(refusjon, MidlerFrigjortÅrsak.REFUSJON_GODKJENT_NULL_BELØP)
return ResponseEntity.ok("Sendt godkjent nullbeløp-melding for ${refusjon.id}")
} else if (!refusjon.refusjonsgrunnlag.refusjonsgrunnlagetErPositivt()) {
} else if (refusjon.refusjonsgrunnlag.refusjonsgrunnlagetErNegativt()) {
refusjonKafkaProducer!!.annullerTilskuddsperiodeEtterNullEllerMinusBeløp(refusjon, MidlerFrigjortÅrsak.REFUSJON_MINUS_BELØP)
return ResponseEntity.ok("Sendt godkjent minusbeløp-melding for ${refusjon.id}")
} else {
return ResponseEntity.ok("Kunne ikke annullere refusjon ${refusjon.id}")
}
}

@Unprotected
@PostMapping("utfoer-automatisk-innsending")
@Transactional
fun manuellAutomatiskUtbetaling() {
automatiskInnsendingService.utførAutomatiskInnsending()
}
}

data class ReberegnRequest(val harFerietrekkForSammeMåned: Boolean, val minusBeløp: Int, val ferieTrekk: Int)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ package no.nav.arbeidsgiver.tiltakrefusjon

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.retry.annotation.EnableRetry
import org.springframework.scheduling.annotation.EnableScheduling
import kotlin.system.exitProcess

@SpringBootApplication
@EnableScheduling
@EnableRetry
class TiltakRefusjonApplication

fun main(args: Array<String>) {
Expand All @@ -15,4 +19,4 @@ fun main(args: Array<String>) {
}
setAdditionalProfiles(System.getenv("MILJO"))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package no.nav.arbeidsgiver.tiltakrefusjon.automatisk_utbetaling

import no.nav.arbeidsgiver.tiltakrefusjon.autorisering.SYSTEM_BRUKER
import no.nav.arbeidsgiver.tiltakrefusjon.refusjon.Refusjon
import no.nav.arbeidsgiver.tiltakrefusjon.refusjon.RefusjonRepository
import no.nav.arbeidsgiver.tiltakrefusjon.refusjon.RefusjonService
import no.nav.arbeidsgiver.tiltakrefusjon.refusjon.RefusjonStatus
import no.nav.arbeidsgiver.tiltakrefusjon.refusjon.Tiltakstype
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class AutomatiskInnsendingService(
private val refusjonRepository: RefusjonRepository,
private val refusjonService: RefusjonService
) {
val log = LoggerFactory.getLogger(AutomatiskInnsendingService::class.java.name)

val tiltakstyperSomKanSendesInnAutomatisk = Tiltakstype.entries.filter { it.harFastUtbetaling() }.toSet()

@Transactional
fun utførAutomatiskInnsending() {
refusjonRepository.findAllByStatusAndRefusjonsgrunnlag_Tilskuddsgrunnlag_TiltakstypeIn(
RefusjonStatus.FOR_TIDLIG,
tiltakstyperSomKanSendesInnAutomatisk
)
.forEach { refusjon ->
refusjon.gjørKlarTilInnsending()
if (refusjon.status == RefusjonStatus.KLAR_FOR_INNSENDING) {
utførAutomatiskInnsending(refusjon)
}
}
}

fun utførAutomatiskInnsending(refusjon: Refusjon) {
val refusjonensTiltaktstype = refusjon.refusjonsgrunnlag.tilskuddsgrunnlag.tiltakstype
if (!refusjonensTiltaktstype.harFastUtbetaling()) {
throw IllegalStateException("Refusjon ${refusjon.id} kan ikke sendes inn automatisk (tiltakstype ${refusjonensTiltaktstype})")
}
log.info(
"Utfører automatisk innsending av refusjon {}-{} ({})",
refusjon.refusjonsgrunnlag.tilskuddsgrunnlag.avtaleNr,
refusjon.refusjonsgrunnlag.tilskuddsgrunnlag.løpenummer,
refusjon.id
)
refusjonService.gjørBeregning(refusjon, SYSTEM_BRUKER)
refusjon.godkjennForArbeidsgiver(utførtAv = SYSTEM_BRUKER)
refusjonRepository.save(refusjon)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class Refusjon(

@JsonProperty
fun måTaStillingTilInntekter(): Boolean =
refusjonsgrunnlag.tilskuddsgrunnlag.tiltakstype != Tiltakstype.VTAO
!refusjonsgrunnlag.tilskuddsgrunnlag.tiltakstype.harFastUtbetaling()

private fun krevStatus(vararg gyldigeStatuser: RefusjonStatus) {
if (status !in gyldigeStatuser) throw FeilkodeException(Feilkode.UGYLDIG_STATUS)
Expand Down Expand Up @@ -159,7 +159,7 @@ class Refusjon(
if (!refusjonsgrunnlag.bedriftKid?.trim().isNullOrEmpty()) {
KidValidator(refusjonsgrunnlag.bedriftKid)
}
if (refusjonsgrunnlag.inntektsgrunnlag == null || refusjonsgrunnlag.inntektsgrunnlag!!.inntekter.isEmpty()) {
if (this.måTaStillingTilInntekter() && (refusjonsgrunnlag.inntektsgrunnlag == null || refusjonsgrunnlag.inntektsgrunnlag!!.inntekter.isEmpty())) {
throw FeilkodeException(Feilkode.INGEN_INNTEKTER)
}
if (refusjonsgrunnlag.bedriftKontonummer == null) {
Expand All @@ -177,7 +177,7 @@ class Refusjon(
if (refusjonsgrunnlag.refusjonsgrunnlagetErNullSomIZero()) {
status = RefusjonStatus.GODKJENT_NULLBELØP
registerEvent(RefusjonGodkjentNullBeløp(this, utførtAv))
} else if (!refusjonsgrunnlag.refusjonsgrunnlagetErPositivt()) {
} else if (refusjonsgrunnlag.refusjonsgrunnlagetErNegativt()) {
status = RefusjonStatus.GODKJENT_MINUSBELØP
registerEvent(RefusjonGodkjentMinusBeløp(this, utførtAv))
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ interface RefusjonRepository : JpaRepository<Refusjon, String> {
pageable: Pageable
): Page<Refusjon>

fun findAllByStatusAndRefusjonsgrunnlag_Tilskuddsgrunnlag_TiltakstypeIn(status: RefusjonStatus, tiltakstype: Collection<Tiltakstype>): List<Refusjon>
fun findAllByStatusAndRefusjonsgrunnlag_Tilskuddsgrunnlag_TiltakstypeNotIn(status: RefusjonStatus, tiltakstype: Collection<Tiltakstype>): List<Refusjon>

fun findAllByRefusjonsgrunnlag_Tilskuddsgrunnlag_AvtaleNrAndStatusIn(avtaleNr: Int, status: List<RefusjonStatus>): List<Refusjon>

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,9 @@ class RefusjonService(
}

fun gjørBeregning(refusjon: Refusjon, utførtAv: InnloggetBruker) {
if (erAltOppgitt(refusjon.refusjonsgrunnlag)) {
if (refusjon.refusjonsgrunnlag.erAltOppgitt()) {
val beregning = beregnRefusjonsbeløp(
inntekter = refusjon.refusjonsgrunnlag.inntektsgrunnlag!!.inntekter.toList(),
inntekter = refusjon.refusjonsgrunnlag.inntektsgrunnlag?.inntekter?.toList() ?: emptyList(),
tilskuddsgrunnlag = refusjon.refusjonsgrunnlag.tilskuddsgrunnlag,
tidligereUtbetalt = refusjon.refusjonsgrunnlag.tidligereUtbetalt,
korrigertBruttoLønn = refusjon.refusjonsgrunnlag.endretBruttoLønn,
Expand All @@ -322,7 +322,7 @@ class RefusjonService(
}

fun gjørKorreksjonBeregning(korreksjon: Korreksjon, utførtAv: InnloggetBruker) {
if (erAltOppgitt(korreksjon.refusjonsgrunnlag)) {
if (korreksjon.refusjonsgrunnlag.erAltOppgitt()) {
val beregning = beregnRefusjonsbeløp(
inntekter = korreksjon.refusjonsgrunnlag.inntektsgrunnlag!!.inntekter.toList(),
tilskuddsgrunnlag = korreksjon.refusjonsgrunnlag.tilskuddsgrunnlag,
Expand All @@ -339,13 +339,6 @@ class RefusjonService(
}
}

private fun erAltOppgitt(refusjonsgrunnlag: Refusjonsgrunnlag): Boolean {
val inntektsgrunnlag = refusjonsgrunnlag.inntektsgrunnlag
if (inntektsgrunnlag == null || inntektsgrunnlag.inntekter.none { it.erMedIInntektsgrunnlag() }) return false
return refusjonsgrunnlag.bedriftKontonummer != null && (refusjonsgrunnlag.inntekterKunFraTiltaket == true && refusjonsgrunnlag.endretBruttoLønn == null ||
((refusjonsgrunnlag.inntekterKunFraTiltaket == false || refusjonsgrunnlag.inntekterKunFraTiltaket == null) && refusjonsgrunnlag.endretBruttoLønn != null))
}

fun endreBruttolønn(refusjon: Refusjon, inntekterKunFraTiltaket: Boolean?, bruttoLønn: Int?) {
refusjon.endreBruttolønn(inntekterKunFraTiltaket, bruttoLønn)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ private fun antallDager(
tom: LocalDate,
) = fom.datesUntil(tom.plusDays(1)).count().toInt()

fun fastBeløpBeregning(tilskuddsgrunnlag: Tilskuddsgrunnlag, tidligereUtbetalt: Int) = Beregning(
lønn = 0,
lønnFratrukketFerie = 0,
feriepenger = 0,
tjenestepensjon = 0,
arbeidsgiveravgift = 0,
sumUtgifter = 0,
beregnetBeløp = tilskuddsgrunnlag.tilskuddsbeløp,
refusjonsbeløp = tilskuddsgrunnlag.tilskuddsbeløp,
overTilskuddsbeløp = false,
tidligereUtbetalt = tidligereUtbetalt,
fratrekkLønnFerie = 0,
tidligereRefundertBeløp = 0,
overFemGrunnbeløp = false,
sumUtgifterFratrukketRefundertBeløp = 0
)

fun beregnRefusjonsbeløp(
inntekter: List<Inntektslinje>,
tilskuddsgrunnlag: Tilskuddsgrunnlag,
Expand All @@ -50,7 +67,9 @@ fun beregnRefusjonsbeløp(
harFerietrekkForSammeMåned: Boolean,
ekstraFerietrekk: Int? = null,

): Beregning {
): Beregning {
if (tilskuddsgrunnlag.tiltakstype.harFastUtbetaling()) return fastBeløpBeregning(tilskuddsgrunnlag, tidligereUtbetalt)

val kalkulertBruttoLønn = kalkulerBruttoLønn(inntekter).roundToInt()
val lønn = if (korrigertBruttoLønn != null) minOf(korrigertBruttoLønn, kalkulertBruttoLønn) else kalkulertBruttoLønn
val trekkgrunnlagFerie = if (harFerietrekkForSammeMåned) 0 else leggSammenTrekkGrunnlag(inntekter, tilskuddFom, ekstraFerietrekk).roundToInt()
Expand All @@ -61,7 +80,7 @@ fun beregnRefusjonsbeløp(
val arbeidsgiveravgift = (lønnFratrukketFerie + tjenestepensjon + feriepenger) * tilskuddsgrunnlag.arbeidsgiveravgiftSats
val sumUtgifter = lønnFratrukketFerie + tjenestepensjon + feriepenger + arbeidsgiveravgift
val sumUtgifterFratrukketRefundertBeløp = sumUtgifter - fratrekkRefunderbarBeløp
val beregnetBeløpUtenFratrukketRefundertBeløp = sumUtgifter * (tilskuddsgrunnlag.lønnstilskuddsprosent / 100.0)
val beregnetBeløpUtenFratrukketRefundertBeløp = sumUtgifter * (tilskuddsgrunnlag.lønnstilskuddsprosent / 100.0)
var beregnetBeløp = sumUtgifterFratrukketRefundertBeløp * (tilskuddsgrunnlag.lønnstilskuddsprosent / 100.0)

if (beregnetBeløpUtenFratrukketRefundertBeløp > 0 && beregnetBeløp < 0) {
Expand Down Expand Up @@ -96,11 +115,12 @@ fun beregnRefusjonsbeløp(
fratrekkLønnFerie = trekkgrunnlagFerie,
tidligereRefundertBeløp = fratrekkRefunderbarBeløp,
overFemGrunnbeløp = overFemGrunnbeløp,
sumUtgifterFratrukketRefundertBeløp = sumUtgifterFratrukketRefundertBeløp.roundToInt())
sumUtgifterFratrukketRefundertBeløp = sumUtgifterFratrukketRefundertBeløp.roundToInt()
)
}

fun leggSammenTrekkGrunnlag(inntekter: List<Inntektslinje>, tilskuddFom: LocalDate, ekstraFerietrekk: Int? = null): Double {
var ferieTrekkGrunnlag = inntekter.filter { it.skalTrekkesIfraInntektsgrunnlag(tilskuddFom) }
var ferieTrekkGrunnlag = inntekter.filter { it.skalTrekkesIfraInntektsgrunnlag(tilskuddFom) }
.sumOf { it.beløp }
if (ekstraFerietrekk != null) {
ferieTrekkGrunnlag += ekstraFerietrekk
Expand All @@ -112,4 +132,4 @@ fun kalkulerBruttoLønn(
inntekter: List<Inntektslinje>,
): Double =
inntekter.filter { it.erMedIInntektsgrunnlag() && it.erOpptjentIPeriode != null && it.erOpptjentIPeriode!! }
.sumOf { it.beløp }
.sumOf { it.beløp }
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ class Refusjonsgrunnlag(
}
}
}
if(inntektsgrunnlag.inntekter.filter { it.erMedIInntektsgrunnlag() }.find { it.erOpptjentIPeriode === null } !== null) {
if (inntektsgrunnlag.inntekter.filter { it.erMedIInntektsgrunnlag() }.find { it.erOpptjentIPeriode === null } !== null) {
this.resetEndreBruttolønn()
}
this.inntektsgrunnlag = inntektsgrunnlag
}

fun finnInntektslinjeIListeMedInntekter(linje1: Inntektslinje, inntektslinjer: Set<Inntektslinje>): Inntektslinje? {
return inntektslinjer.find {
it.inntektType == linje1.inntektType &&
it.inntektType == linje1.inntektType &&
it.beskrivelse == linje1.beskrivelse &&
it.beløp == linje1.beløp &&
it.måned == linje1.måned &&
Expand Down Expand Up @@ -88,8 +88,8 @@ class Refusjonsgrunnlag(
this.endretBruttoLønn = bruttoLønn
}

fun refusjonsgrunnlagetErPositivt(): Boolean {
return this.beregning?.refusjonsbeløp != null && this.beregning!!.refusjonsbeløp > 0
fun refusjonsgrunnlagetErNegativt(): Boolean {
return this.beregning?.refusjonsbeløp != null && this.beregning!!.refusjonsbeløp < 0
}

fun refusjonsgrunnlagetErNullSomIZero(): Boolean {
Expand All @@ -106,12 +106,12 @@ class Refusjonsgrunnlag(

var erNoenOpptjentIPerioden = false
inntektsgrunnlag?.inntekter?.forEach {
if(it.erOpptjentIPeriode == true) {
if (it.erOpptjentIPeriode == true) {
erNoenOpptjentIPerioden = true
}
}

if(!erNoenOpptjentIPerioden) {
if (!erNoenOpptjentIPerioden) {
beregning = null
endretBruttoLønn = null
fratrekkRefunderbarBeløp = null
Expand All @@ -126,4 +126,13 @@ class Refusjonsgrunnlag(
this.fratrekkRefunderbarBeløp = fratrekkRefunderbarBeløp
this.refunderbarBeløp = refunderbarBeløp
}

fun erAltOppgitt(): Boolean {
if (tilskuddsgrunnlag.tiltakstype.harFastUtbetaling()) return true

val inntektsgrunnlag = inntektsgrunnlag
if (inntektsgrunnlag == null || inntektsgrunnlag.inntekter.none { it.erMedIInntektsgrunnlag() }) return false
return bedriftKontonummer != null && (inntekterKunFraTiltaket == true && endretBruttoLønn == null ||
((inntekterKunFraTiltaket == false || inntekterKunFraTiltaket == null) && endretBruttoLønn != null))
}
}
Loading
Loading