Skip to content

Commit

Permalink
Legg inn manglende juridiske henvisninger
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasDev committed Sep 28, 2023
1 parent c0da40e commit 4df32fc
Show file tree
Hide file tree
Showing 15 changed files with 465 additions and 357 deletions.
116 changes: 66 additions & 50 deletions README.md

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions src/main/kotlin/no/nav/syfo/rules/common/GenerateMermaid.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,25 @@ import no.nav.syfo.rules.gradert.gradertRuleTree
import no.nav.syfo.rules.hpr.hprRuleTree
import no.nav.syfo.rules.legesuspensjon.legeSuspensjonRuleTree
import no.nav.syfo.rules.patientageover70.patientAgeOver70RuleTree
import no.nav.syfo.rules.periodlogic.periodLogicRuleTree
import no.nav.syfo.rules.patientunder13.patientAgeUnder13RuleTree
import no.nav.syfo.rules.periode.periodeRuleTree
import no.nav.syfo.rules.periodvalidering.periodLogicRuleTree
import no.nav.syfo.rules.tilbakedatering.tilbakedateringRuleTree
import no.nav.syfo.rules.validation.validationRuleTree

fun main() {
val ruleTrees =
listOf(
"Lege suspensjon" to legeSuspensjonRuleTree,
"Validation" to validationRuleTree,
"Periode validering" to periodLogicRuleTree,
"HPR" to hprRuleTree,
"Arbeidsuforhet" to arbeidsuforhetRuleTree,
"Validation" to validationRuleTree,
"Pasient under 13" to patientAgeUnder13RuleTree,
"Pasient over 70" to patientAgeOver70RuleTree,
"Periode" to periodLogicRuleTree,
"Tilbakedatering" to tilbakedateringRuleTree,
"Periode" to periodeRuleTree,
"Gradert" to gradertRuleTree,
"Tilbakedatering" to tilbakedateringRuleTree,
)

ruleTrees.forEach {
Expand Down
16 changes: 14 additions & 2 deletions src/main/kotlin/no/nav/syfo/rules/hpr/HPRRulesExecution.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package no.nav.syfo.rules.hpr

import no.nav.syfo.logger
import no.nav.syfo.model.Sykmelding
import no.nav.syfo.model.juridisk.JuridiskHenvisning
import no.nav.syfo.model.juridisk.Lovverk
import no.nav.syfo.rules.common.MedJuridisk
import no.nav.syfo.rules.common.RuleExecution
import no.nav.syfo.rules.common.RuleResult
import no.nav.syfo.rules.common.UtenJuridisk
import no.nav.syfo.rules.dsl.ResultNode
import no.nav.syfo.rules.dsl.RuleNode
import no.nav.syfo.rules.dsl.TreeNode
Expand All @@ -22,7 +24,17 @@ class HPRRulesExecution(private val rootNode: HPRTreeNode = hprRuleTree) : RuleE
override fun runRules(sykmelding: Sykmelding, ruleMetadata: RuleMetadataSykmelding) =
rootNode.evaluate(sykmelding, ruleMetadata.behandlerOgStartdato).also { hprRulePath ->
logger.info("Rules ${sykmelding.id}, ${hprRulePath.printRulePath()}")
} to UtenJuridisk
} to
MedJuridisk(
JuridiskHenvisning(
lovverk = Lovverk.HELSEPERSONELLOVEN,
paragraf = "3",
ledd = null,
punktum = null,
bokstav = null,
rundskriv = null
)
)
}

private fun TreeNode<HPRRules, RuleResult>.evaluate(
Expand Down
43 changes: 43 additions & 0 deletions src/main/kotlin/no/nav/syfo/rules/periode/PeriodeRuleHit.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package no.nav.syfo.rules.periode

import no.nav.syfo.model.Status
import no.nav.syfo.rules.common.RuleHit

enum class PeriodeRuleHit(val ruleHit: RuleHit) {
FREMDATERT_MER_ENN_30_DAGER(
ruleHit =
RuleHit(
rule = "FREMDATERT",
status = Status.INVALID,
messageForSender =
"Sykmeldingen kan ikke rettes, det må skrives en ny. " +
"Pasienten har fått beskjed om å vente på ny sykmelding fra deg. Grunnet følgende:" +
"Hvis sykmeldingen er fremdatert mer enn 30 dager etter behandletDato avvises meldingen.",
messageForUser = "Sykmeldingen er datert mer enn 30 dager fram i tid.",
),
),
TILBAKEDATERT_MER_ENN_3_AR(
ruleHit =
RuleHit(
rule = "TILBAKEDATERT_MER_ENN_3_AR",
status = Status.INVALID,
messageForSender =
"Sykmeldingen kan ikke rettes, det må skrives en ny. " +
"Pasienten har fått beskjed om å vente på ny sykmelding fra deg. Grunnet følgende: " +
"Sykmeldinges fom-dato er mer enn 3 år tilbake i tid.",
messageForUser = "Startdatoen er mer enn tre år tilbake.",
),
),
TOTAL_VARIGHET_OVER_ETT_AAR(
ruleHit =
RuleHit(
rule = "TOTAL_VARIGHET_OVER_ETT_AAR",
status = Status.INVALID,
messageForSender =
"Sykmeldingen kan ikke rettes, det må skrives en ny. " +
"Pasienten har fått beskjed om å vente på ny sykmelding fra deg. Grunnet følgende:" +
"Sykmeldingen første fom og siste tom har ein varighet som er over 1 år",
messageForUser = "Den kan ikke ha en varighet på over ett år.",
),
),
}
50 changes: 50 additions & 0 deletions src/main/kotlin/no/nav/syfo/rules/periode/PeriodeRuleTree.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package no.nav.syfo.rules.periode

import no.nav.syfo.model.Status
import no.nav.syfo.model.Status.INVALID
import no.nav.syfo.model.Status.OK
import no.nav.syfo.rules.common.RuleResult
import no.nav.syfo.rules.dsl.RuleNode
import no.nav.syfo.rules.dsl.tree
import no.nav.syfo.rules.periode.PeriodeRuleHit.*
import no.nav.syfo.rules.periodvalidering.PeriodLogicRuleHit

enum class PeriodeRules {
FREMDATERT,
TILBAKEDATERT_MER_ENN_3_AR,
TOTAL_VARIGHET_OVER_ETT_AAR,
}

val periodeRuleTree =
tree<PeriodeRules, RuleResult>(PeriodeRules.FREMDATERT) {
yes(INVALID, FREMDATERT_MER_ENN_30_DAGER)
no(PeriodeRules.TILBAKEDATERT_MER_ENN_3_AR) {
yes(INVALID, TILBAKEDATERT_MER_ENN_3_AR)
no(PeriodeRules.TOTAL_VARIGHET_OVER_ETT_AAR) {
yes(INVALID, TOTAL_VARIGHET_OVER_ETT_AAR)
no(OK)
}
}
}

internal fun RuleNode<PeriodeRules, RuleResult>.yes(
status: Status,
ruleHit: PeriodeRuleHit? = null
) {
yes(RuleResult(status, ruleHit?.ruleHit))
}

internal fun RuleNode<PeriodeRules, RuleResult>.no(
status: Status,
ruleHit: PeriodLogicRuleHit? = null
) {
no(RuleResult(status, ruleHit?.ruleHit))
}

fun getRule(rules: PeriodeRules): Rule<PeriodeRules> {
return when (rules) {
PeriodeRules.FREMDATERT -> fremdatertOver30Dager
PeriodeRules.TILBAKEDATERT_MER_ENN_3_AR -> tilbakeDatertOver3Ar
PeriodeRules.TOTAL_VARIGHET_OVER_ETT_AAR -> varighetOver1AAr
}
}
51 changes: 51 additions & 0 deletions src/main/kotlin/no/nav/syfo/rules/periode/PeriodeRulesExecution.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package no.nav.syfo.rules.periode

import no.nav.syfo.logger
import no.nav.syfo.model.Sykmelding
import no.nav.syfo.model.juridisk.JuridiskHenvisning
import no.nav.syfo.model.juridisk.Lovverk
import no.nav.syfo.rules.common.MedJuridisk
import no.nav.syfo.rules.common.RuleExecution
import no.nav.syfo.rules.common.RuleResult
import no.nav.syfo.rules.dsl.ResultNode
import no.nav.syfo.rules.dsl.RuleNode
import no.nav.syfo.rules.dsl.TreeNode
import no.nav.syfo.rules.dsl.TreeOutput
import no.nav.syfo.rules.dsl.join
import no.nav.syfo.rules.dsl.printRulePath
import no.nav.syfo.services.RuleMetadataSykmelding

typealias PeriodeRuleTreeOutput = TreeOutput<PeriodeRules, RuleResult>

class PeriodeRulesExecution(
private val rootNode: TreeNode<PeriodeRules, RuleResult> = periodeRuleTree
) : RuleExecution<PeriodeRules> {
override fun runRules(sykmelding: Sykmelding, ruleMetadata: RuleMetadataSykmelding) =
rootNode.evaluate(sykmelding, ruleMetadata).also {
logger.info("Rules ${sykmelding.id}, ${it.printRulePath()}")
} to
MedJuridisk(
JuridiskHenvisning(
Lovverk.FOLKETRYGDLOVEN,
"8-13",
1,
null,
null,
null,
)
)

private fun TreeNode<PeriodeRules, RuleResult>.evaluate(
sykmelding: Sykmelding,
ruleMetadata: RuleMetadataSykmelding,
): PeriodeRuleTreeOutput =
when (this) {
is ResultNode -> PeriodeRuleTreeOutput(treeResult = result)
is RuleNode -> {
val rule = getRule(rule)
val result = rule(sykmelding, ruleMetadata.ruleMetadata)
val childNode = if (result.ruleResult) yes else no
result join childNode.evaluate(sykmelding, ruleMetadata)
}
}
}
70 changes: 70 additions & 0 deletions src/main/kotlin/no/nav/syfo/rules/periode/Rules.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package no.nav.syfo.rules.periode

import java.time.LocalDate
import java.time.temporal.ChronoUnit
import no.nav.syfo.model.RuleMetadata
import no.nav.syfo.model.Sykmelding
import no.nav.syfo.rules.dsl.RuleResult
import no.nav.syfo.rules.periodvalidering.sortedTOMDate
import no.nav.syfo.services.sortedFOMDate

typealias Rule<T> = (sykmelding: Sykmelding, ruleMetadata: RuleMetadata) -> RuleResult<T>

typealias PeriodeRule = Rule<PeriodeRules>

val fremdatertOver30Dager: PeriodeRule = { sykmelding, ruleMetadata ->
val forsteFomDato = sykmelding.perioder.sortedFOMDate().first()
val genereringsTidspunkt = ruleMetadata.signatureDate

val fremdatert =
when (forsteFomDato) {
null -> false
else -> forsteFomDato > genereringsTidspunkt.plusDays(30).toLocalDate()
}

RuleResult(
ruleInputs =
mapOf(
"genereringsTidspunkt" to genereringsTidspunkt,
"fom" to forsteFomDato,
"fremdatert" to fremdatert
),
rule = PeriodeRules.FREMDATERT,
ruleResult = fremdatert,
)
}

val varighetOver1AAr: PeriodeRule = { sykmelding, _ ->
val forsteFomDato = sykmelding.perioder.sortedFOMDate().first()
val sisteTomDato = sykmelding.perioder.sortedTOMDate().last()

val varighetOver1AAr = ChronoUnit.DAYS.between(forsteFomDato, sisteTomDato) > 365

RuleResult(
ruleInputs =
mapOf(
"fom" to forsteFomDato,
"tom" to sisteTomDato,
"varighetOver1AAr" to varighetOver1AAr
),
rule = PeriodeRules.TOTAL_VARIGHET_OVER_ETT_AAR,
ruleResult = varighetOver1AAr,
)
}

val tilbakeDatertOver3Ar: PeriodeRule = { sykmelding, ruleMetadata ->
val forsteFomDato = sykmelding.perioder.sortedFOMDate().first()
val tilbakeDatertMerEnn3AAr = forsteFomDato.isBefore(LocalDate.now().minusYears(3))
val genereringsTidspunkt = ruleMetadata.signatureDate

RuleResult(
ruleInputs =
mapOf(
"genereringsTidspunkt" to genereringsTidspunkt,
"fom" to forsteFomDato,
"tilbakeDatertMerEnn3AAr" to tilbakeDatertMerEnn3AAr,
),
rule = PeriodeRules.TILBAKEDATERT_MER_ENN_3_AR,
ruleResult = tilbakeDatertMerEnn3AAr,
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package no.nav.syfo.rules.periodlogic
package no.nav.syfo.rules.periodvalidering

import no.nav.syfo.model.Status
import no.nav.syfo.rules.common.RuleHit
Expand Down Expand Up @@ -69,42 +69,6 @@ enum class PeriodLogicRuleHit(
"(den må være enten 100 prosent, gradert, avventende, reisetilskudd eller behandlingsdager).",
),
),
TILBAKEDATERT_MER_ENN_3_AR(
ruleHit =
RuleHit(
rule = "TILBAKEDATERT_MER_ENN_3_AR",
status = Status.INVALID,
messageForSender =
"Sykmeldingen kan ikke rettes, det må skrives en ny. " +
"Pasienten har fått beskjed om å vente på ny sykmelding fra deg. Grunnet følgende: " +
"Sykmeldinges fom-dato er mer enn 3 år tilbake i tid.",
messageForUser = "Startdatoen er mer enn tre år tilbake.",
),
),
FREMDATERT(
ruleHit =
RuleHit(
rule = "FREMDATERT",
status = Status.INVALID,
messageForSender =
"Sykmeldingen kan ikke rettes, det må skrives en ny. " +
"Pasienten har fått beskjed om å vente på ny sykmelding fra deg. Grunnet følgende:" +
"Hvis sykmeldingen er fremdatert mer enn 30 dager etter behandletDato avvises meldingen.",
messageForUser = "Sykmeldingen er datert mer enn 30 dager fram i tid.",
),
),
TOTAL_VARIGHET_OVER_ETT_AAR(
ruleHit =
RuleHit(
rule = "TOTAL_VARIGHET_OVER_ETT_AAR",
status = Status.INVALID,
messageForSender =
"Sykmeldingen kan ikke rettes, det må skrives en ny. " +
"Pasienten har fått beskjed om å vente på ny sykmelding fra deg. Grunnet følgende:" +
"Sykmeldingen første fom og siste tom har ein varighet som er over 1 år",
messageForUser = "Den kan ikke ha en varighet på over ett år.",
),
),
BEHANDLINGSDATO_ETTER_MOTTATTDATO(
ruleHit =
RuleHit(
Expand Down
Loading

0 comments on commit 4df32fc

Please sign in to comment.