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

Duplikat kontroll innsending #343

Merged
merged 5 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
Expand Up @@ -37,3 +37,6 @@ fun mapInntektsmelding(
}

class UgyldigFormatException(ex: Exception) : Exception(ex)

fun Inntektsmelding.erDuplikatAv(other: Inntektsmelding): Boolean =
this == other.copy(tidspunkt = tidspunkt)
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import no.nav.helsearbeidsgiver.felles.rapidsrivers.demandValues
import no.nav.helsearbeidsgiver.felles.rapidsrivers.interestedIn
import no.nav.helsearbeidsgiver.felles.rapidsrivers.model.Behov
import no.nav.helsearbeidsgiver.inntektsmelding.db.InntektsmeldingRepository
import no.nav.helsearbeidsgiver.inntektsmelding.db.erDuplikatAv
import no.nav.helsearbeidsgiver.inntektsmelding.db.mapInntektsmelding
import no.nav.helsearbeidsgiver.utils.json.fromJson
import no.nav.helsearbeidsgiver.utils.json.toJson
Expand Down Expand Up @@ -50,13 +51,20 @@ class PersisterImLoeser(rapidsConnection: RapidsConnection, private val reposito
val arbeidsgiverInfo = behov[DataFelt.ARBEIDSGIVER_INFORMASJON].toJsonElement().fromJson(PersonDato.serializer())
val fulltNavn = arbeidstakerInfo.navn
sikkerLogger.info("Fant fulltNavn: $fulltNavn")
val innsending = behov[DataFelt.INNTEKTSMELDING].toString().fromJson(Innsending.serializer())
val innsending = behov[DataFelt.INNTEKTSMELDING].toJsonElement().fromJson(Innsending.serializer())
val inntektsmelding = mapInntektsmelding(innsending, fulltNavn, arbeidsgiver, arbeidsgiverInfo.navn)
repository.lagreInntektsmelding(behov.forespoerselId!!, inntektsmelding)
sikkerLogger.info("Lagret Inntektsmelding for forespoerselId: ${behov.forespoerselId}")
val sisteIm = repository.hentNyeste(behov.forespoerselId!!)
val erDuplikat = sisteIm?.erDuplikatAv(inntektsmelding) ?: false
if (erDuplikat) {
sikkerLogger.warn("Fant duplikat av inntektsmelding for forespoerselId: ${behov.forespoerselId}")
} else {
repository.lagreInntektsmelding(behov.forespoerselId!!, inntektsmelding)
sikkerLogger.info("Lagret Inntektsmelding for forespoerselId: ${behov.forespoerselId}")
}
behov.createData(
mapOf(
DataFelt.INNTEKTSMELDING_DOKUMENT to inntektsmelding.toJson(Inntektsmelding.serializer()).toJsonNode()
DataFelt.INNTEKTSMELDING_DOKUMENT to inntektsmelding.toJson(Inntektsmelding.serializer()).toJsonNode(),
DataFelt.ER_DUPLIKAT_IM to erDuplikat
)
).also {
publishData(it)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
package no.nav.helsearbeidsgiver.inntektsmelding.db.river

import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
import no.nav.helse.rapids_rivers.JsonMessage
import no.nav.helse.rapids_rivers.testsupport.TestRapid
import no.nav.helsearbeidsgiver.domene.inntektsmelding.AarsakInnsending
import no.nav.helsearbeidsgiver.domene.inntektsmelding.Bonus
import no.nav.helsearbeidsgiver.domene.inntektsmelding.BegrunnelseIngenEllerRedusertUtbetalingKode
import no.nav.helsearbeidsgiver.domene.inntektsmelding.FullLoennIArbeidsgiverPerioden
import no.nav.helsearbeidsgiver.domene.inntektsmelding.Innsending
import no.nav.helsearbeidsgiver.domene.inntektsmelding.Inntekt
import no.nav.helsearbeidsgiver.domene.inntektsmelding.Naturalytelse
import no.nav.helsearbeidsgiver.domene.inntektsmelding.NaturalytelseKode
import no.nav.helsearbeidsgiver.domene.inntektsmelding.Periode
import no.nav.helsearbeidsgiver.domene.inntektsmelding.Refusjon
import no.nav.helsearbeidsgiver.felles.BehovType
import no.nav.helsearbeidsgiver.felles.DataFelt
import no.nav.helsearbeidsgiver.felles.EventName
import no.nav.helsearbeidsgiver.felles.Key
import no.nav.helsearbeidsgiver.felles.PersonDato
import no.nav.helsearbeidsgiver.inntektsmelding.db.InntektsmeldingRepository
import no.nav.helsearbeidsgiver.inntektsmelding.db.mapInntektsmelding
import no.nav.helsearbeidsgiver.utils.json.toJson
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import java.time.LocalDate
Expand All @@ -40,46 +46,96 @@ class PersisterImLoeserTest {
coEvery {
repository.lagreInntektsmelding(any(), any())
} returns Unit

val request = Innsending(
"",
"",
emptyList(),
emptyList(),
emptyList(),
LocalDate.now(),
emptyList(),
Inntekt(
bekreftet = true,
500.0,
Bonus(),
true
),
FullLoennIArbeidsgiverPerioden(
true
),
Refusjon(
true
),
emptyList(),
AarsakInnsending.NY,
true
coEvery { repository.hentNyeste(any()) } returns null
sendMelding(
JsonMessage.newMessage(
mapOf(
Key.EVENT_NAME.str to EventName.INSENDING_STARTED.name,
Key.BEHOV.str to BehovType.PERSISTER_IM.name,
DataFelt.VIRKSOMHET.str to "Test Virksomhet",
DataFelt.ARBEIDSTAKER_INFORMASJON.str to PersonDato("Test person", null, ""),
DataFelt.ARBEIDSGIVER_INFORMASJON.str to PersonDato("Test person", null, ""),
Key.UUID.str to "uuid",
DataFelt.INNTEKTSMELDING.str to Mock.innsending
)
)
)

coVerify(exactly = 1) {
repository.lagreInntektsmelding(any(), any())
}
val message = rapid.inspektør.message(0)
Assertions.assertEquals(EventName.INSENDING_STARTED.name, message.path(Key.EVENT_NAME.str).asText())
Assertions.assertNotNull(message.path(DataFelt.INNTEKTSMELDING.str).asText())
Assertions.assertFalse(message.path(DataFelt.ER_DUPLIKAT_IM.str).asBoolean())
}

@Test
fun `ikke lagre ved duplikat`() {
coEvery { repository.hentNyeste(any()) } returns Mock.inntektsmelding
sendMelding(
JsonMessage.newMessage(
mapOf(
Key.EVENT_NAME.str to EventName.INSENDING_STARTED.name,
Key.BEHOV.str to BehovType.PERSISTER_IM.name,
DataFelt.VIRKSOMHET.str to "Test Virksomhet",
DataFelt.ARBEIDSTAKER_INFORMASJON.str to PersonDato("Test person", null, ""),
DataFelt.ARBEIDSGIVER_INFORMASJON.str to PersonDato("Test person", null, ""),
Key.UUID.str to "uuid",
DataFelt.INNTEKTSMELDING.str to request
DataFelt.INNTEKTSMELDING.str to Mock.innsending
)
)
)

coVerify(exactly = 0) {
repository.lagreInntektsmelding(any(), any())
}
val message = rapid.inspektør.message(0)
Assertions.assertEquals(EventName.INSENDING_STARTED.name, message.path(Key.EVENT_NAME.str).asText())
Assertions.assertNotNull(message.path(DataFelt.INNTEKTSMELDING.str).asText())
Assertions.assertTrue(message.path(DataFelt.ER_DUPLIKAT_IM.str).asBoolean())
}

object Mock {
val innsending = Innsending(
orgnrUnderenhet = "orgnr-bål",
identitetsnummer = "fnr-fredrik",
behandlingsdager = listOf(LocalDate.now().plusDays(5)),
egenmeldingsperioder = listOf(
Periode(
fom = LocalDate.now(),
tom = LocalDate.now().plusDays(2)
)
),
arbeidsgiverperioder = emptyList(),
bestemmendeFraværsdag = LocalDate.now(),
fraværsperioder = emptyList(),
inntekt = Inntekt(
bekreftet = true,
beregnetInntekt = 32100.0,
endringÅrsak = null,
manueltKorrigert = false
),
fullLønnIArbeidsgiverPerioden = FullLoennIArbeidsgiverPerioden(
utbetalerFullLønn = true,
begrunnelse = BegrunnelseIngenEllerRedusertUtbetalingKode.ArbeidOpphoert
),
refusjon = Refusjon(
utbetalerHeleEllerDeler = true,
refusjonPrMnd = 200.0,
refusjonOpphører = LocalDate.now()
),
naturalytelser = listOf(
Naturalytelse(
naturalytelse = NaturalytelseKode.KOSTDOEGN,
dato = LocalDate.now(),
beløp = 300.0
)
),
årsakInnsending = AarsakInnsending.ENDRING,
bekreftOpplysninger = true
)
val arbeidstaker = PersonDato("Test person", null, innsending.identitetsnummer)
val arbeidsgiver = PersonDato("Test person", null, innsending.identitetsnummer)
val inntektsmelding = mapInntektsmelding(innsending, arbeidstaker.navn, "Test Virksomhet", arbeidsgiver.navn)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ enum class DataFelt(override val str: String) : IKey {
SKJAERINGSTIDSPUNKT("skjaeringstidspunkt"),
TILGANG("tilgang"),
SPINN_INNTEKTSMELDING_ID("spinnInntektsmeldingId"),
EKSTERN_INNTEKTSMELDING("eksternInntektsmelding");
EKSTERN_INNTEKTSMELDING("eksternInntektsmelding"),
ER_DUPLIKAT_IM("er_duplikat_im");
override fun toString(): String =
str

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class InnsendingService(
DataFelt.ARBEIDSFORHOLD.str,
DataFelt.INNTEKTSMELDING_DOKUMENT.str,
DataFelt.ARBEIDSGIVER_INFORMASJON.str,
DataFelt.ARBEIDSTAKER_INFORMASJON.str
DataFelt.ARBEIDSTAKER_INFORMASJON.str,
DataFelt.ER_DUPLIKAT_IM.str
),
event,
it,
Expand Down Expand Up @@ -149,19 +150,21 @@ class InnsendingService(
val clientId = redisStore.get(RedisKey.of(uuid, event))
logger.info("publiserer under clientID $clientId")
redisStore.set(RedisKey.of(clientId!!), redisStore.get(RedisKey.of(uuid, DataFelt.INNTEKTSMELDING_DOKUMENT))!!)
logger.info("Publiserer INNTEKTSMELDING_DOKUMENT under uuid $uuid")
logger.info("InnsendingService: emitting event INNTEKTSMELDING_MOTTATT")

rapid.publish(
Key.EVENT_NAME to EventName.INNTEKTSMELDING_MOTTATT.toJson(),
Key.UUID to uuid.toJson(),
DataFelt.FORESPOERSEL_ID to redisStore.get(RedisKey.of(uuid, DataFelt.FORESPOERSEL_ID))!!.toJson(),
DataFelt.INNTEKTSMELDING_DOKUMENT to message[DataFelt.INNTEKTSMELDING_DOKUMENT.str].toJsonElement()
)
.also {
logger.info("Submitting INNTEKTSMELDING_MOTTATT")
sikkerLogger.info("Submitting INNTEKTSMELDING_MOTTATT ${it.toPretty()}")
}
val erDuplikat = message[DataFelt.ER_DUPLIKAT_IM.str].asBoolean()
if (!erDuplikat) {
logger.info("Publiserer INNTEKTSMELDING_DOKUMENT under uuid $uuid")
logger.info("InnsendingService: emitting event INNTEKTSMELDING_MOTTATT")
rapid.publish(
Key.EVENT_NAME to EventName.INNTEKTSMELDING_MOTTATT.toJson(),
Key.UUID to uuid.toJson(),
DataFelt.FORESPOERSEL_ID to redisStore.get(RedisKey.of(uuid, DataFelt.FORESPOERSEL_ID))!!.toJson(),
DataFelt.INNTEKTSMELDING_DOKUMENT to message[DataFelt.INNTEKTSMELDING_DOKUMENT.str].toJsonElement()
)
.also {
logger.info("Submitting INNTEKTSMELDING_MOTTATT")
sikkerLogger.info("Submitting INNTEKTSMELDING_MOTTATT ${it.toPretty()}")
}
}
}

private fun step1data(uuid: String): Array<RedisKey> = arrayOf(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest

import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.maps.shouldContainKey
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
Expand All @@ -16,12 +17,14 @@ import no.nav.helsearbeidsgiver.felles.json.les
import no.nav.helsearbeidsgiver.felles.json.toJson
import no.nav.helsearbeidsgiver.felles.json.toMap
import no.nav.helsearbeidsgiver.felles.rapidsrivers.pritopic.Pri
import no.nav.helsearbeidsgiver.inntektsmelding.db.mapInntektsmelding
import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.mock.mockInnsending
import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.EndToEndTest
import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.fromJsonToString
import no.nav.helsearbeidsgiver.utils.json.fromJson
import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer
import no.nav.helsearbeidsgiver.utils.json.toJson
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import java.time.LocalDateTime
Expand All @@ -30,6 +33,11 @@ import java.util.UUID
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class InnsendingIT : EndToEndTest() {

@BeforeEach
fun setup() {
truncateDatabase()
}

@Test
fun `skal ta imot forespørsel ny inntektsmelding, deretter opprette sak og oppgave`() {
forespoerselRepository.lagreForespoersel(Mock.forespoerselId.toString(), Mock.innsending.orgnrUnderenhet)
Expand Down Expand Up @@ -66,6 +74,13 @@ class InnsendingIT : EndToEndTest() {
// Ble lagret i databasen
it[DataFelt.INNTEKTSMELDING_DOKUMENT].shouldNotBeNull()
}
messages.filter(EventName.INSENDING_STARTED)
.filter(DataFelt.ER_DUPLIKAT_IM)
.first()
.toMap()
.also {
it[DataFelt.ER_DUPLIKAT_IM]!!.fromJson(Boolean.serializer()) shouldBe false
}

messages.filter(EventName.INNTEKTSMELDING_MOTTATT)
.first()
Expand Down Expand Up @@ -128,6 +143,52 @@ class InnsendingIT : EndToEndTest() {
bekreftMarkeringAvForespoerselSomBesvart()
}

@Test
fun `skal ikke lagre duplikat inntektsmelding`() {
forespoerselRepository.lagreForespoersel(Mock.forespoerselId.toString(), Mock.innsending.orgnrUnderenhet)
forespoerselRepository.oppdaterSakId(Mock.forespoerselId.toString(), Mock.SAK_ID)
forespoerselRepository.oppdaterOppgaveId(Mock.forespoerselId.toString(), Mock.OPPGAVE_ID)
imRepository.lagreInntektsmelding(Mock.forespoerselId.toString(), Mock.innsendtInntektsmelding)

coEvery {
dokarkivClient.opprettOgFerdigstillJournalpost(any(), any(), any(), any(), any(), any(), any())
} returns OpprettOgFerdigstillResponse(
journalpostId = Mock.JOURNALPOST_ID,
journalpostFerdigstilt = true,
melding = "Ha en fin dag!",
dokumenter = emptyList()
)

coEvery { brregClient.hentVirksomhetNavn(any()) } returns "Bedrift A/S"

publish(
Key.EVENT_NAME to EventName.INSENDING_STARTED.toJson(),
Key.OPPRETTET to LocalDateTime.now().toJson(),
Key.CLIENT_ID to UUID.randomUUID().toJson(),
Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(),
DataFelt.ORGNRUNDERENHET to Mock.innsending.orgnrUnderenhet.toJson(),
Key.IDENTITETSNUMMER to "fnr-bjarne".toJson(),
Key.ARBEIDSGIVER_ID to "fnr-max".toJson(),
DataFelt.INNTEKTSMELDING to Mock.innsending.toJson(Innsending.serializer())
)

Thread.sleep(10000)

messages.filter(EventName.INSENDING_STARTED)
.filter(DataFelt.ER_DUPLIKAT_IM)
.first()
.toMap()
.also {
it[DataFelt.ER_DUPLIKAT_IM]!!.fromJson(Boolean.serializer()) shouldBe true
}

messages.filter(EventName.INNTEKTSMELDING_MOTTATT).all() shouldHaveSize 0

messages.filter(EventName.INNTEKTSMELDING_JOURNALFOERT).all() shouldHaveSize 0

messages.filter(EventName.INNTEKTSMELDING_DISTRIBUERT).all() shouldHaveSize 0
}

private fun bekreftForventedeMeldingerForFerdigstilligAvOppgaveOgSak() {
messages.filter(EventName.FORESPOERSEL_BESVART)
.filter(BehovType.NOTIFIKASJON_HENT_ID)
Expand Down Expand Up @@ -180,6 +241,7 @@ class InnsendingIT : EndToEndTest() {
const val OPPGAVE_ID = "neglisjert-sommer"

val forespoerselId: UUID = UUID.randomUUID()
val innsending = mockInnsending()
val innsending = mockInnsending().copy(identitetsnummer = "fnr-bjarne")
val innsendtInntektsmelding = mapInntektsmelding(innsending, "Bjarne Betjent", "Bedrift A/S", "Max Mekker")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,17 @@ abstract class EndToEndTest : ContainerTest(), RapidsConnection.MessageListener
mellomnavn = null,
etternavn = "Betjent"
),
foedselsdato = 28.mai
foedselsdato = 28.mai,
ident = "fnr-bjarne"
),
FullPerson(
navn = PersonNavn(
fornavn = "Max",
mellomnavn = null,
etternavn = "Mekker"
),
foedselsdato = 6.august
foedselsdato = 6.august,
ident = "fnr-max"
)
)
coEvery { brregClient.hentVirksomhetNavn(any()) } returns "Bedrift A/S"
Expand All @@ -151,7 +153,7 @@ abstract class EndToEndTest : ContainerTest(), RapidsConnection.MessageListener

createAareg(mockk(relaxed = true))
createAltinn(altinnClient)
createBrreg(brregClient, true)
createBrreg(brregClient, false)
createDb(database, imRepository, forespoerselRepository)
createDistribusjon(mockk(relaxed = true))
createForespoerselBesvartFraSimba()
Expand Down