diff --git a/src/main/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenMeldingMedMetadataDAO.kt b/src/main/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenMeldingMedMetadataDAO.kt index 622e6b329..add2e03ed 100644 --- a/src/main/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenMeldingMedMetadataDAO.kt +++ b/src/main/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenMeldingMedMetadataDAO.kt @@ -1,5 +1,6 @@ package no.nav.veilarbaktivitet.oversikten +import no.nav.common.types.identer.AktorId import no.nav.common.types.identer.Fnr import no.nav.veilarbaktivitet.config.database.Database import no.nav.veilarbaktivitet.veilarbdbutil.VeilarbAktivitetSqlParameterSource @@ -72,6 +73,52 @@ open class OversiktenMeldingMedMetadataDAO( return jdbc.queryForObject(sql, params, rowMapper) } + open fun hentUdelteSamtalereferatDerViIkkeHarSendtMeldingTilOversikten(): List { + val sql = """ + WITH oversikten_meldinger_gruppert_per_key_og_rangert AS ( + SELECT + melding_key, + operasjon, + kategori, + ROW_NUMBER() OVER (PARTITION BY melding_key ORDER BY opprettet DESC) AS rank + FROM oversikten_melding_med_metadata + WHERE operasjon = 'START' + AND kategori = 'UDELT_SAMTALEREFERAT' + ), + aktivitet_id_sendt_til_oversikten AS ( + SELECT DISTINCT ma.aktivitet_id + FROM oversikten_melding_aktivitet_mapping ma + JOIN oversikten_meldinger_gruppert_per_key_og_rangert me + ON ma.oversikten_melding_key = me.melding_key + WHERE me.rank = 1 + ) + SELECT + a.aktivitet_id, + a.aktor_id + FROM aktivitet a + LEFT JOIN mote m + ON a.aktivitet_id = m.aktivitet_id + AND m.versjon = a.versjon + WHERE a.gjeldende = 1 + AND (a.aktivitet_type_kode IN ('MOTE', 'SAMTALEREFERAT')) + AND (m.referat_publisert = 0 AND m.referat IS NOT NULL) + AND a.historisk_dato IS NULL + AND a.fra_dato < NOW() + AND a.aktivitet_id NOT IN (SELECT aktivitet_id FROM aktivitet_id_sendt_til_oversikten) + ORDER BY a.aktivitet_id; + """.trimIndent() + + return jdbc.query(sql) { rs: ResultSet, rowNum: Int -> + UdeltSamtalereferatUtenMelding(AktorId.of(rs.getString("aktor_id")), rs.getLong("aktivitet_id")) + } + } + + data class UdeltSamtalereferatUtenMelding( + val aktorId: AktorId, + val aktivitetId: Long, + ) + + open val rowMapper = RowMapper { rs: ResultSet, rowNum: Int -> LagretOversiktenMeldingMedMetadata( id = rs.getLong("id"), diff --git a/src/main/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenService.kt b/src/main/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenService.kt index 5ae0ff879..b29edb625 100644 --- a/src/main/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenService.kt +++ b/src/main/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenService.kt @@ -24,8 +24,8 @@ open class OversiktenService( private val log = LoggerFactory.getLogger(OversiktenService::class.java) private val erProd = EnvironmentUtils.isProduction().orElse(false) - @Scheduled(cron = "0 0 * * * *") // Hvert minutt - @SchedulerLock(name = "oversikten_melding_med_metadata_scheduledTask", lockAtMostFor = "PT3M") +// @Scheduled(cron = "0 0 * * * *") // Hver time +// @SchedulerLock(name = "oversikten_melding_med_metadata_scheduledTask", lockAtMostFor = "PT3M") open fun sendUsendteMeldingerTilOversikten() { val kanPublisereMeldinger = !EnvironmentUtils.isProduction().getOrElse { false } && !EnvironmentUtils.isDevelopment().getOrElse { false } @@ -44,6 +44,16 @@ open class OversiktenService( } } + @Scheduled(cron = "0 50 13 * * ?") + @SchedulerLock(name = "oversikten_melding_gamle_udelte_scheduledTask", lockAtMostFor = "PT15M") + open fun sendAlleGamleUdelte() { + val alleUdelte = oversiktenMeldingMedMetadataRepository.hentUdelteSamtalereferatDerViIkkeHarSendtMeldingTilOversikten() + log.info("antall udelte referat", alleUdelte.size) + alleUdelte.forEach { + lagreStartMeldingOmUdeltSamtalereferatIUtboks(AktorId(it.aktorId.get()), it.aktivitetId) + } + } + open fun lagreStartMeldingOmUdeltSamtalereferatIUtboks(aktorId: AktorId, aktivitetId: AktivitetId) { val fnr = aktorOppslagClient.hentFnr(no.nav.common.types.identer.AktorId.of(aktorId.get())) val melding = diff --git a/src/test/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenMeldingMedMetadataDAOTest.kt b/src/test/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenMeldingMedMetadataDAOTest.kt new file mode 100644 index 000000000..ddc5c340f --- /dev/null +++ b/src/test/kotlin/no/nav/veilarbaktivitet/oversikten/OversiktenMeldingMedMetadataDAOTest.kt @@ -0,0 +1,120 @@ +package no.nav.veilarbaktivitet.oversikten + +import no.nav.veilarbaktivitet.SpringBootTestBase +import no.nav.veilarbaktivitet.aktivitet.dto.AktivitetDTO +import no.nav.veilarbaktivitet.aktivitet.dto.AktivitetTypeDTO +import no.nav.veilarbaktivitet.db.DbTestUtils +import no.nav.veilarbaktivitet.mock_nav_modell.MockBruker +import no.nav.veilarbaktivitet.testutils.AktivitetDtoTestBuilder +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +open class OversiktenMeldingMedMetadataDAOTest: SpringBootTestBase() { + + @Autowired + lateinit var oversiktenService: OversiktenService + + @Autowired + private lateinit var oversiktenMeldingMedMetadataDAO: OversiktenMeldingMedMetadataDAO + + @BeforeEach + fun beforeEach() { + DbTestUtils.cleanupTestDb(jdbcTemplate) + } + + @Test + fun `UdeltSamtalereferatForMøte IkkeSendtMelding ReturnererEttResultat`() { + val (happyBruker, aktivitet) = settOppUdeltSamtalereferatUtenMelding(AktivitetTypeDTO.MOTE) + + val resultat = oversiktenMeldingMedMetadataDAO.hentUdelteSamtalereferatDerViIkkeHarSendtMeldingTilOversikten() + + assertThat(resultat).hasSize(1) + assertThat(resultat.first().aktorId.get()).isEqualTo(happyBruker.aktorId.get()) + assertThat(resultat.first().aktivitetId.toString()).isEqualTo(aktivitet.id) + } + + @Test + fun `UdeltSamtalereferatForSamtalereferat IkkeSendtMelding ReturnererEttResultat`() { + val (happyBruker, aktivitet) = settOppUdeltSamtalereferatUtenMelding(AktivitetTypeDTO.SAMTALEREFERAT) + + val resultat = oversiktenMeldingMedMetadataDAO.hentUdelteSamtalereferatDerViIkkeHarSendtMeldingTilOversikten() + + assertThat(resultat).hasSize(1) + assertThat(resultat.first().aktorId.get()).isEqualTo(happyBruker.aktorId.get()) + assertThat(resultat.first().aktivitetId.toString()).isEqualTo(aktivitet.id) + } + + @Test + fun `UdeltSamtalereferatForMøte SendtStartMelding ReturnererIngen`() { + val (happyBruker, aktivitet) = settOppUdeltSamtalereferatUtenMelding(AktivitetTypeDTO.MOTE) + oversiktenService.lagreStartMeldingOmUdeltSamtalereferatIUtboks(happyBruker.aktorId, aktivitet.id.toLong()) + oversiktenService.sendUsendteMeldingerTilOversikten() + + val resultat = oversiktenMeldingMedMetadataDAO.hentUdelteSamtalereferatDerViIkkeHarSendtMeldingTilOversikten() + + assertThat(resultat).isEmpty() + } + + @Test + fun `UdeltSamtalereferatForSamtalereferat SendtStartMelding ReturnererIngen`() { + val (happyBruker, aktivitet) = settOppUdeltSamtalereferatUtenMelding(AktivitetTypeDTO.SAMTALEREFERAT) + oversiktenService.lagreStartMeldingOmUdeltSamtalereferatIUtboks(happyBruker.aktorId, aktivitet.id.toLong()) + oversiktenService.sendUsendteMeldingerTilOversikten() + + val resultat = oversiktenMeldingMedMetadataDAO.hentUdelteSamtalereferatDerViIkkeHarSendtMeldingTilOversikten() + + assertThat(resultat).isEmpty() + } + + @Test + fun `DeltSamtalereferatForMøte IkkeSendtMelding ReturnererIngen`() { + settOppDeltSamtalereferatUtenMelding(AktivitetTypeDTO.MOTE) + + val resultat = oversiktenMeldingMedMetadataDAO.hentUdelteSamtalereferatDerViIkkeHarSendtMeldingTilOversikten() + + assertThat(resultat).isEmpty() + } + + @Test + fun `DeltSamtalereferatForSamtalereferat IkkeSendtMelding ReturnererIngen`() { + settOppDeltSamtalereferatUtenMelding(AktivitetTypeDTO.SAMTALEREFERAT) + + val resultat = oversiktenMeldingMedMetadataDAO.hentUdelteSamtalereferatDerViIkkeHarSendtMeldingTilOversikten() + + assertThat(resultat).isEmpty() + } + + private fun settOppUdeltSamtalereferatUtenMelding(aktivitetType: AktivitetTypeDTO): Pair { + val happyBruker = navMockService.createBruker() + val veileder = navMockService.createVeileder(happyBruker) + val aktivitet = aktivitetTestService.opprettAktivitet( + happyBruker, + veileder, + AktivitetDtoTestBuilder.nyAktivitet(aktivitetType).setErReferatPublisert(false) + .setReferat("Et referat") + ) + + jdbcTemplate.execute("TRUNCATE OVERSIKTEN_MELDING_AKTIVITET_MAPPING") + jdbcTemplate.execute("TRUNCATE OVERSIKTEN_MELDING_MED_METADATA") + + return Pair(happyBruker, aktivitet) + } + + private fun settOppDeltSamtalereferatUtenMelding(aktivitetType: AktivitetTypeDTO): Pair { + val happyBruker = navMockService.createBruker() + val veileder = navMockService.createVeileder(happyBruker) + val aktivitet = aktivitetTestService.opprettAktivitet( + happyBruker, + veileder, + AktivitetDtoTestBuilder.nyAktivitet(aktivitetType).setErReferatPublisert(true) + .setReferat("Et referat") + ) + + jdbcTemplate.execute("TRUNCATE OVERSIKTEN_MELDING_AKTIVITET_MAPPING") + jdbcTemplate.execute("TRUNCATE OVERSIKTEN_MELDING_MED_METADATA") + + return Pair(happyBruker, aktivitet) + } +} \ No newline at end of file