Skip to content

Commit

Permalink
more wip in handlepapirsykmelding
Browse files Browse the repository at this point in the history
  • Loading branch information
helehar committed Nov 18, 2024
1 parent ae328de commit dca7045
Show file tree
Hide file tree
Showing 14 changed files with 311 additions and 141 deletions.
2 changes: 1 addition & 1 deletion naiserator-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,5 @@ spec:
value: dev-gcp.teamsykmelding.smtss
- name: SYFOSMPAPIRREGLER_URL
value: http://syfosmpapirregler
- name: SYFOSMPAPIRREGLER_SCOPE
- name: SYFOSMPAPIRREGLER_CLIENT_ID
value: dev-gcp.teamsykmelding.syfosmpapirregler
2 changes: 1 addition & 1 deletion naiserator-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,5 @@ spec:
value: prod-gcp.teamsykmelding.smtss
- name: SYFOSMPAPIRREGLER_URL
value: http://syfosmpapirregler
- name: SYFOSMPAPIRREGLER_SCOPE
- name: SYFOSMPAPIRREGLER_CLIENT_ID
value: prod-gcp.teamsykmelding.syfosmpapirregler
11 changes: 9 additions & 2 deletions src/main/kotlin/no/nav/sykdig/config/M2MRestTemplate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,19 @@ class M2MRestTemplate(
.build()
}

/* @Bean
@Bean
fun helsenettM2mRestTemplate(): RestTemplate {
return restTemplateBuilder
.additionalInterceptors(bearerTokenInterceptor("helsenett-m2m"))
.build()
}*/
}

@Bean
fun regeltM2mRestTemplate(): RestTemplate {
return restTemplateBuilder
.additionalInterceptors(bearerTokenInterceptor("regel-m2m"))
.build()
}

private fun bearerTokenInterceptor(type: String): ClientHttpRequestInterceptor {
return ClientHttpRequestInterceptor { request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package no.nav.sykdig.digitalisering.exceptions

import graphql.GraphQLException
import no.nav.sykdig.digitalisering.sykmelding.ValidationResult

class IkkeTilgangException(override val message: String) : GraphQLException(message)

Expand All @@ -12,4 +13,6 @@ class NoOppgaveException(override val message: String) : RuntimeException(messag

class SykmelderNotFoundException(message: String) : RuntimeException(message)

class UnauthorizedException(message: String) : Exception(message)
class UnauthorizedException(message: String) : Exception(message)

class ValidationException(val validationResult: ValidationResult) : Exception()
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import no.nav.sykdig.applog
import no.nav.sykdig.digitalisering.exceptions.SykmelderNotFoundException
import no.nav.sykdig.digitalisering.helsenett.client.HelsenettClient
import no.nav.sykdig.digitalisering.helsenett.client.SmtssClient
import no.nav.sykdig.digitalisering.papirsykmelding.api.RegelClient
import no.nav.sykdig.digitalisering.papirsykmelding.api.model.Godkjenning
import no.nav.sykdig.digitalisering.papirsykmelding.api.model.Kode
import no.nav.sykdig.digitalisering.papirsykmelding.api.model.Sykmelder
Expand All @@ -16,7 +17,7 @@ import org.springframework.stereotype.Service
class SykmelderService(
private val helsenettClient: HelsenettClient,
private val personService: PersonService,
private val smtssClient: SmtssClient
private val smtssClient: SmtssClient,
) {
val log = applog()
val securelog = securelog()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import no.nav.sykdig.digitalisering.ferdigstilling.mapping.fellesformatMarshalle
import no.nav.sykdig.digitalisering.ferdigstilling.mapping.get
import no.nav.sykdig.digitalisering.ferdigstilling.mapping.toString
import no.nav.sykdig.digitalisering.helsenett.SykmelderService
import no.nav.sykdig.digitalisering.papirsykmelding.api.RegelClient
import no.nav.sykdig.digitalisering.papirsykmelding.api.model.*
import no.nav.sykdig.digitalisering.papirsykmelding.db.NasjonalOppgaveRepository
import no.nav.sykdig.digitalisering.papirsykmelding.db.model.NasjonalManuellOppgaveDAO
Expand All @@ -31,6 +32,7 @@ class NasjonalOppgaveService(
private val nasjonalOppgaveRepository: NasjonalOppgaveRepository,
private val personService: PersonService,
private val sykmelderService: SykmelderService
private val regelClient: RegelClient

) {
val log = applog()
Expand All @@ -46,7 +48,7 @@ class NasjonalOppgaveService(


// usikker på hva som skal returneres her
suspend fun sendPapirsykmelding(smRegistreringManuell: SmRegistreringManuell, navEnhet: String, callId: String, oppgaveId: String): ResponseEntity<String> {
suspend fun sendPapirsykmelding(smRegistreringManuell: SmRegistreringManuell, navEnhet: String, callId: String, oppgaveId: Int): ResponseEntity<String> {
val oppgave = nasjonalOppgaveRepository.findByOppgaveId(oppgaveId)
if (!oppgave.isPresent) return ResponseEntity(HttpStatus.NOT_FOUND) // TODO: bedre error handeling

Expand Down Expand Up @@ -136,6 +138,43 @@ class NasjonalOppgaveService(
"Papirsykmelding manuell registering mappet til internt format uten feil {}",
StructuredArguments.fields(loggingMeta),
)
val validationResult = regelClient.valider(receivedSykmelding, sykmeldingId)
log.info(
"Resultat: {}, {}, {}",
StructuredArguments.keyValue("ruleStatus", validationResult.status.name),
StructuredArguments.keyValue(
"ruleHits",
validationResult.ruleHits.joinToString(", ", "(", ")") { it.ruleName },
),
StructuredArguments.fields(loggingMeta),
)

val dokumentInfoId = oppgave.get().dokumentInfoId

/*val ferdigstillRegistrering =
FerdigstillRegistrering(
oppgaveId = oppgaveId,
journalpostId = journalpostId,
dokumentInfoId = dokumentInfoId,
pasientFnr = receivedSykmelding.personNrPasient,
sykmeldingId = sykmeldingId,
sykmelder = sykmelder,
navEnhet = navEnhet,
veileder = authorizationService.getVeileder(accessToken),
avvist = false,
oppgave = null,
)*/
/*auditlogg.info(
AuditLogger()
.createcCefMessage(
fnr = smRegistreringManuell.pasientFnr,
accessToken = accessToken,
operation = AuditLogger.Operation.WRITE,
requestPath = requestPath,
permit = AuditLogger.Permit.PERMIT,
),
)*/




Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class NasjonalOppgaveController(
@PreAuthorize("@oppgaveSecurityService.hasAccessToOppgave(#oppgaveId)")
@ResponseBody
suspend fun sendOppgave(
@PathVariable oppgaveId: String,
@PathVariable oppgaveId: Int,
@RequestHeader("Authorization") authorization: String,
@RequestHeader("X-Nav-Enhet") navEnhet: String,
@RequestBody papirSykmelding: SmRegistreringManuell,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,40 @@
package no.nav.sykdig.digitalisering.papirsykmelding.api

import net.logstash.logback.argument.StructuredArguments.kv
import no.nav.sykdig.applog
import no.nav.sykdig.digitalisering.papirsykmelding.db.model.ReceivedSykmeldingNasjonal
import no.nav.sykdig.digitalisering.sykmelding.ValidationResult
import no.nav.sykdig.securelog
import org.springframework.beans.factory.annotation.Value
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Component
import org.springframework.web.client.HttpClientErrorException
import org.springframework.web.client.RestTemplate
import org.springframework.web.client.exchange


@Component
class RegelClient(
@Value("\$regel.url") private val regelUrl: String,
private val regelRestTemplate: RestTemplate
private val regeltM2mRestTemplate: RestTemplate
){
val log = applog()
val securelog = securelog()

fun valider(sykmelding: ReceivedSykmeldingNasjonal, msgId: String): ValidationResult {
log.info("validating against rules {}", kv("sykmeldingId", sykmelding.sykmelding.id))
val headers = HttpHeaders()
headers["Nav-CallId"] = msgId

val response = regeltM2mRestTemplate.exchange(
"$regelUrl/api/v2/rules/validate",
HttpMethod.POST,
HttpEntity(sykmelding, headers),
ValidationResult::class.java
)
return response.body ?: throw HttpClientErrorException(HttpStatus.NOT_FOUND, "regelvalidering feilet for sykmeldingId ${sykmelding.sykmelding.id}")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package no.nav.sykdig.digitalisering.papirsykmelding.api.model

import no.nav.sykdig.oppgavemottak.Oppgave


data class FerdigstillRegistrering(
val oppgaveId: Int?,
val journalpostId: String,
val dokumentInfoId: String?,
val pasientFnr: String,
val sykmeldingId: String,
val sykmelder: Sykmelder,
val navEnhet: String,
val veileder: Veileder,
val avvist: Boolean,
val oppgave: Oppgave?,
)

class Veileder(
val veilederIdent: String,
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package no.nav.sykdig.digitalisering.papirsykmelding.api.model

import java.time.LocalDate
import no.nav.sykdig.digitalisering.exceptions.ValidationException
import no.nav.sykdig.digitalisering.sykmelding.RuleInfo
import no.nav.sykdig.digitalisering.sykmelding.Status
import no.nav.sykdig.digitalisering.sykmelding.ValidationResult

fun checkValidState(
smRegistreringManuell: SmRegistreringManuell,
sykmelder: Sykmelder,
validationResult: ValidationResult,
) {
when {
smRegistreringManuell.perioder.isEmpty() -> {
val vr =
ValidationResult(
status = Status.MANUAL_PROCESSING,
ruleHits =
listOf(
RuleInfo(
ruleName = "periodeValidation",
messageForSender =
"Sykmeldingen må ha minst én periode oppgitt for å være gyldig",
messageForUser =
"Sykmelder har gjort en feil i utfyllingen av sykmeldingen.",
ruleStatus = Status.MANUAL_PROCESSING,
),
),
)
throw ValidationException(vr)
}
harOverlappendePerioder(smRegistreringManuell.perioder) -> {
val vr =
ValidationResult(
status = Status.MANUAL_PROCESSING,
ruleHits =
listOf(
RuleInfo(
ruleName = "overlappendePeriodeValidation",
messageForSender = "Sykmeldingen har overlappende perioder",
messageForUser =
"Sykmelder har gjort en feil i utfyllingen av sykmeldingen.",
ruleStatus = Status.MANUAL_PROCESSING,
),
),
)
throw ValidationException(vr)
}
harUlovligKombinasjonMedReisetilskudd(smRegistreringManuell.perioder) -> {
val vr =
ValidationResult(
status = Status.MANUAL_PROCESSING,
ruleHits =
listOf(
RuleInfo(
ruleName = "reisetilskuddValidation",
messageForSender =
"Sykmeldingen inneholder periode som kombinerer reisetilskudd med annen sykmeldingstype",
messageForUser =
"Sykmelder har gjort en feil i utfyllingen av sykmeldingen.",
ruleStatus = Status.MANUAL_PROCESSING,
),
),
)
throw ValidationException(vr)
}
erFremtidigDato(smRegistreringManuell.behandletDato) -> {
val vr =
ValidationResult(
status = Status.MANUAL_PROCESSING,
ruleHits =
listOf(
RuleInfo(
ruleName = "behandletDatoValidation",
messageForSender = "Behandletdato kan ikke være frem i tid.",
messageForUser =
"Sykmelder har gjort en feil i utfyllingen av sykmeldingen.",
ruleStatus = Status.MANUAL_PROCESSING,
),
),
)
throw ValidationException(vr)
}
studentBehandlerUtenAutorisasjon(validationResult, sykmelder) -> {
val vr =
ValidationResult(
status = Status.MANUAL_PROCESSING,
ruleHits =
listOf(
RuleInfo(
ruleName =
RuleHitCustomError.BEHANDLER_MANGLER_AUTORISASJON_I_HPR.name,
messageForSender =
"Studenter har ikke lov til å skrive sykmelding. Sykmelding må avvises.",
messageForUser = "Studenter har ikke lov til å skrive sykmelding.",
ruleStatus = Status.MANUAL_PROCESSING,
),
),
)
throw ValidationException(vr)
}
suspendertBehandler(validationResult) -> {
val vr =
ValidationResult(
status = Status.MANUAL_PROCESSING,
ruleHits =
listOf(
RuleInfo(
ruleName = RuleHitCustomError.BEHANDLER_SUSPENDERT.name,
messageForSender =
"Legen har mistet retten til å skrive sykmelding.",
messageForUser = "Legen har mistet retten til å skrive sykmelding.",
ruleStatus = Status.MANUAL_PROCESSING,
),
),
)
throw ValidationException(vr)
}
}
}

fun suspendertBehandler(validationResult: ValidationResult): Boolean {
return validationResult.ruleHits.any {
it.ruleName == RuleHitCustomError.BEHANDLER_SUSPENDERT.name
}
}

fun studentBehandlerUtenAutorisasjon(
validationResult: ValidationResult,
sykmelder: Sykmelder
): Boolean {
val behandlerManglerAutorisasjon =
validationResult.ruleHits.any {
it.ruleName == RuleHitCustomError.BEHANDLER_MANGLER_AUTORISASJON_I_HPR.name
}

val erStudent =
sykmelder.godkjenninger?.any {
it.autorisasjon?.aktiv == true &&
it.autorisasjon.oid == 7704 &&
it.autorisasjon.verdi == "3"
}

return behandlerManglerAutorisasjon && erStudent == true
}

fun harOverlappendePerioder(perioder: List<Periode>): Boolean {
return harIdentiskePerioder(perioder) ||
perioder.any { periodA ->
perioder
.filter { periodB -> periodB != periodA }
.any { periodB -> periodA.fom in periodB.range() || periodA.tom in periodB.range() }
}
}

private fun harIdentiskePerioder(perioder: List<Periode>): Boolean {
return perioder.distinct().count() != perioder.size
}

fun harUlovligKombinasjonMedReisetilskudd(perioder: List<Periode>): Boolean {
perioder.forEach {
if (
it.reisetilskudd &&
(it.aktivitetIkkeMulig != null ||
it.gradert != null ||
it.avventendeInnspillTilArbeidsgiver != null ||
it.behandlingsdager != null)
) {
return true
}
}
return false
}

fun Periode.range(): ClosedRange<LocalDate> = fom.rangeTo(tom)

fun erFremtidigDato(dato: LocalDate): Boolean {
return dato.isAfter(LocalDate.now())
}
Loading

0 comments on commit dca7045

Please sign in to comment.