diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 7cc96797..3a345f9e 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -67,7 +67,7 @@ jobs: permissions: {} name: "Deploy app to dev" needs: "build" - if: github.ref == 'refs/heads/samenligning-med-bransje' + if: github.ref == 'refs/heads/matview' runs-on: "ubuntu-latest" steps: - uses: "actions/checkout@v3" diff --git a/src/main/kotlin/no/nav/lydia/App.kt b/src/main/kotlin/no/nav/lydia/App.kt index d75c5ee5..61db8f25 100644 --- a/src/main/kotlin/no/nav/lydia/App.kt +++ b/src/main/kotlin/no/nav/lydia/App.kt @@ -67,6 +67,7 @@ import no.nav.lydia.sykefraversstatistikk.api.geografi.GeografiService import no.nav.lydia.sykefraversstatistikk.api.sykefraversstatistikk import no.nav.lydia.sykefraversstatistikk.import.StatistikkMetadataVirksomhetConsumer import no.nav.lydia.sykefraversstatistikk.import.StatistikkPerKategoriConsumer +import no.nav.lydia.vedlikehold.StatistikkViewOppdaterer import no.nav.lydia.virksomhet.VirksomhetRepository import no.nav.lydia.virksomhet.VirksomhetService import no.nav.lydia.virksomhet.api.VIRKSOMHET_PATH @@ -124,6 +125,10 @@ fun startLydiaBackend() { run() }.also { HelseMonitor.leggTilHelsesjekk(it) } + StatistikkViewOppdaterer.apply { + run(dataSource = dataSource) + } + embeddedServer(Netty, port = 8080) { lydiaRestApi( naisEnvironment = naisEnv, diff --git a/src/main/kotlin/no/nav/lydia/statusoverikt/StatusoversiktRepository.kt b/src/main/kotlin/no/nav/lydia/statusoverikt/StatusoversiktRepository.kt index dce5b3ab..bdf37e6d 100644 --- a/src/main/kotlin/no/nav/lydia/statusoverikt/StatusoversiktRepository.kt +++ b/src/main/kotlin/no/nav/lydia/statusoverikt/StatusoversiktRepository.kt @@ -10,7 +10,6 @@ import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerP import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåEiere import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåKommuner import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåSektor -import no.nav.lydia.virksomhet.domene.VirksomhetStatus import javax.sql.DataSource class StatusoversiktRepository(val dataSource: DataSource) { @@ -25,34 +24,19 @@ class StatusoversiktRepository(val dataSource: DataSource) { SELECT count(*) as antall, ia_sak.status FROM - sykefravar_statistikk_virksomhet AS statistikk - JOIN virksomhet USING (orgnr) - JOIN sykefravar_statistikk_virksomhet_siste_4_kvartal AS statistikk_siste4 USING (orgnr) - ${ - if (næringsgrupperMedBransjer.isNotEmpty()) " JOIN virksomhet_naringsundergrupper AS vn on (virksomhet.id = vn.virksomhet) " - else "" - } - ${ - if (sektorer.isNotEmpty()) " LEFT JOIN virksomhet_statistikk_metadata USING (orgnr) " - else "" - } + virksomhetsstatistikk_for_prioritering AS statistikk LEFT JOIN ia_sak ON ( ia_sak.orgnr = statistikk.orgnr ) - WHERE - statistikk.arstall = :arstall - AND statistikk.kvartal = :kvartal - + true = true ${filtrerPåBransjeOgNæring(søkeparametere = søkeparametere)} ${filtrerPåKommuner(søkeparametere = søkeparametere)} ${filtrerPåSektor(søkeparametere = søkeparametere)} ${filtrerPåEiere(søkeparametere = søkeparametere)} - ${søkeparametere.sykefraværsprosentFra?.let { " AND statistikk_siste4.prosent >= $it " } ?: ""} - ${søkeparametere.sykefraværsprosentTil?.let { " AND statistikk_siste4.prosent <= $it " } ?: ""} - ${søkeparametere.ansatteFra?.let { " AND statistikk.antall_personer >= $it " } ?: ""} - ${søkeparametere.ansatteTil?.let { " AND statistikk.antall_personer <= $it " } ?: ""} - - AND virksomhet.status = '${VirksomhetStatus.AKTIV.name}' + ${søkeparametere.sykefraværsprosentFra?.let { " AND prosent >= $it " } ?: ""} + ${søkeparametere.sykefraværsprosentTil?.let { " AND prosent <= $it " } ?: ""} + ${søkeparametere.ansatteFra?.let { " AND antall_personer_siste_kvartal >= $it " } ?: ""} + ${søkeparametere.ansatteTil?.let { " AND antall_personer_siste_kvartal <= $it " } ?: ""} GROUP BY ia_sak.status """.trimIndent() @@ -60,8 +44,6 @@ class StatusoversiktRepository(val dataSource: DataSource) { val query = queryOf( statement = sql, mapOf( - "kvartal" to søkeparametere.periode.kvartal, - "arstall" to søkeparametere.periode.årstall, "naringer" to session.createArrayOf("text", næringsgrupperMedBransjer), "kommuner" to session.createArrayOf("text", søkeparametere.kommunenummer), "sektorer" to session.createArrayOf("text", sektorer), diff --git a/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/VirksomhetsinformasjonRepository.kt b/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/VirksomhetsinformasjonRepository.kt index 00214f2c..083ee676 100644 --- a/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/VirksomhetsinformasjonRepository.kt +++ b/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/VirksomhetsinformasjonRepository.kt @@ -11,20 +11,23 @@ import kotliquery.using import no.nav.lydia.ia.sak.domene.IAProsessStatus import no.nav.lydia.sykefraversstatistikk.api.Periode import no.nav.lydia.sykefraversstatistikk.api.Sorteringsnøkkel -import no.nav.lydia.sykefraversstatistikk.api.Sorteringsnøkkel.* +import no.nav.lydia.sykefraversstatistikk.api.Sorteringsnøkkel.ANTALL_PERSONER +import no.nav.lydia.sykefraversstatistikk.api.Sorteringsnøkkel.MULIGE_DAGSVERK +import no.nav.lydia.sykefraversstatistikk.api.Sorteringsnøkkel.NAVN_PÅ_VIRKSOMHET +import no.nav.lydia.sykefraversstatistikk.api.Sorteringsnøkkel.SIST_ENDRET +import no.nav.lydia.sykefraversstatistikk.api.Sorteringsnøkkel.SYKEFRAVÆRSPROSENT +import no.nav.lydia.sykefraversstatistikk.api.Sorteringsnøkkel.TAPTE_DAGSVERK import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere -import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåSnitt import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåBransjeOgNæring import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåEiere import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåKommuner import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåSektor +import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåSnitt import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.filtrerPåStatus -import no.nav.lydia.sykefraversstatistikk.api.Søkeparametere.Companion.joinTilNæringEllerBransje import no.nav.lydia.sykefraversstatistikk.domene.Virksomhetsoversikt import no.nav.lydia.sykefraversstatistikk.domene.VirksomhetsstatistikkSiste4Kvartal import no.nav.lydia.sykefraversstatistikk.domene.VirksomhetsstatistikkSisteKvartal import no.nav.lydia.sykefraversstatistikk.import.Kvartal -import no.nav.lydia.virksomhet.domene.VirksomhetStatus import javax.sql.DataSource class VirksomhetsinformasjonRepository(val dataSource: DataSource) { @@ -38,41 +41,25 @@ class VirksomhetsinformasjonRepository(val dataSource: DataSource) { val sql = """ SELECT - virksomhet.orgnr, - virksomhet.navn, + statistikk.orgnr, + statistikk.navn, statistikk.arstall, statistikk.kvartal, - statistikk.antall_personer, - statistikk_siste4.tapte_dagsverk, - statistikk_siste4.mulige_dagsverk, - statistikk_siste4.prosent, - statistikk_siste4.maskert, - statistikk_siste4.sist_endret, + statistikk.antall_personer_siste_kvartal AS antall_personer, + statistikk.tapte_dagsverk, + statistikk.mulige_dagsverk, + statistikk.prosent, + statistikk.maskert, ia_sak.status, ia_sak.eid_av, ia_sak.endret - FROM - sykefravar_statistikk_virksomhet AS statistikk - JOIN virksomhet USING (orgnr) - JOIN sykefravar_statistikk_virksomhet_siste_4_kvartal AS statistikk_siste4 - ON (statistikk.orgnr = statistikk_siste4.orgnr - AND statistikk.kvartal = statistikk_siste4.publisert_kvartal - AND statistikk.arstall = statistikk_siste4.publisert_arstall) - JOIN virksomhet_naringsundergrupper AS vn on (virksomhet.id = vn.virksomhet) - ${ - if (sektorer.isNotEmpty()) "LEFT JOIN virksomhet_statistikk_metadata " + - "ON (virksomhet.orgnr = virksomhet_statistikk_metadata.orgnr) " - else "" - } + FROM + virksomhetsstatistikk_for_prioritering AS statistikk LEFT JOIN ia_sak ON ( (ia_sak.orgnr = statistikk.orgnr) AND ia_sak.endret = (select max(endret) from ia_sak iasak2 where iasak2.orgnr = statistikk.orgnr) ) - ${joinTilNæringEllerBransje(søkeparametere)} - - WHERE - statistikk.arstall = :arstall - AND statistikk.kvartal = :kvartal + WHERE true = true ${filtrerPåBransjeOgNæring(søkeparametere = søkeparametere)} ${filtrerPåKommuner(søkeparametere = søkeparametere)} @@ -81,12 +68,10 @@ class VirksomhetsinformasjonRepository(val dataSource: DataSource) { ${filtrerPåEiere(søkeparametere = søkeparametere)} ${filtrerPåSnitt(søkeparametere = søkeparametere)} - ${søkeparametere.sykefraværsprosentFra?.let { " AND statistikk_siste4.prosent >= $it " } ?: ""} - ${søkeparametere.sykefraværsprosentTil?.let { " AND statistikk_siste4.prosent <= $it " } ?: ""} - ${søkeparametere.ansatteFra?.let { " AND statistikk.antall_personer >= $it " } ?: ""} - ${søkeparametere.ansatteTil?.let { " AND statistikk.antall_personer <= $it " } ?: ""} - - AND virksomhet.status = '${VirksomhetStatus.AKTIV.name}' + ${søkeparametere.sykefraværsprosentFra?.let { " AND prosent >= $it " } ?: ""} + ${søkeparametere.sykefraværsprosentTil?.let { " AND prosent <= $it " } ?: ""} + ${søkeparametere.ansatteFra?.let { " AND antall_personer_siste_kvartal >= $it " } ?: ""} + ${søkeparametere.ansatteTil?.let { " AND antall_personer_siste_kvartal <= $it " } ?: ""} ${søkeparametere.sorteringsnøkkel.tilOrderBy()} ${søkeparametere.sorteringsretning} NULLS LAST LIMIT ${søkeparametere.virksomheterPerSide()} OFFSET ${søkeparametere.offset()} @@ -95,8 +80,6 @@ class VirksomhetsinformasjonRepository(val dataSource: DataSource) { val query = queryOf( statement = sql, mapOf( - "kvartal" to søkeparametere.periode.kvartal, - "arstall" to søkeparametere.periode.årstall, "naringer" to session.createArrayOf("text", næringsgrupperMedBransjer), "kommuner" to session.createArrayOf("text", søkeparametere.kommunenummer), "sektorer" to session.createArrayOf("text", sektorer), @@ -112,51 +95,30 @@ class VirksomhetsinformasjonRepository(val dataSource: DataSource) { val sql = """ SELECT - COUNT(statistikk_siste4.orgnr) AS total - FROM - sykefravar_statistikk_virksomhet AS statistikk - JOIN virksomhet USING (orgnr) - JOIN sykefravar_statistikk_virksomhet_siste_4_kvartal AS statistikk_siste4 - ON (statistikk.orgnr = statistikk_siste4.orgnr - AND statistikk.kvartal = statistikk_siste4.publisert_kvartal - AND statistikk.arstall = statistikk_siste4.publisert_arstall) - ${ - if (sektorer.isNotEmpty()) "LEFT JOIN virksomhet_statistikk_metadata " + - "ON (virksomhet.orgnr = virksomhet_statistikk_metadata.orgnr) " - else "" - } + COUNT(statistikk.orgnr) AS total + FROM + virksomhetsstatistikk_for_prioritering AS statistikk LEFT JOIN ia_sak ON ( (ia_sak.orgnr = statistikk.orgnr) AND ia_sak.endret = (select max(endret) from ia_sak iasak2 where iasak2.orgnr = statistikk.orgnr) ) - JOIN virksomhet_naringsundergrupper AS vn on (virksomhet.id = vn.virksomhet) - ${joinTilNæringEllerBransje(søkeparametere)} - - WHERE - statistikk.arstall = :arstall - AND statistikk.kvartal = :kvartal - + WHERE true = true ${filtrerPåBransjeOgNæring(søkeparametere = søkeparametere)} ${filtrerPåKommuner(søkeparametere = søkeparametere)} ${filtrerPåStatus(søkeparametere = søkeparametere)} ${filtrerPåSektor(søkeparametere = søkeparametere)} ${filtrerPåEiere(søkeparametere = søkeparametere)} - ${søkeparametere.sykefraværsprosentFra?.let { " AND statistikk_siste4.prosent >= $it " } ?: ""} - ${søkeparametere.sykefraværsprosentTil?.let { " AND statistikk_siste4.prosent <= $it " } ?: ""} + ${søkeparametere.sykefraværsprosentFra?.let { " AND prosent >= $it " } ?: ""} + ${søkeparametere.sykefraværsprosentTil?.let { " AND prosent <= $it " } ?: ""} ${filtrerPåSnitt(søkeparametere = søkeparametere)} - ${søkeparametere.ansatteFra?.let { " AND statistikk.antall_personer >= $it " } ?: ""} - ${søkeparametere.ansatteTil?.let { " AND statistikk.antall_personer <= $it " } ?: ""} - - AND virksomhet.status = '${VirksomhetStatus.AKTIV.name}' - """.trimIndent() + ${søkeparametere.ansatteFra?.let { " AND antall_personer_siste_kvartal >= $it " } ?: ""} + ${søkeparametere.ansatteTil?.let { " AND antall_personer_siste_kvartal <= $it " } ?: ""} + """.trimIndent() val query = queryOf( statement = sql, mapOf( - "kvartal" to søkeparametere.periode.kvartal, - "arstall" to søkeparametere.periode.årstall, - "naringer" to session.createArrayOf("text", næringsgrupperMedBransjer), "kommuner" to session.createArrayOf("text", søkeparametere.kommunenummer), "sektorer" to session.createArrayOf("text", sektorer), @@ -242,7 +204,6 @@ class VirksomhetsinformasjonRepository(val dataSource: DataSource) { muligeDagsverk = row.doubleOrNull("mulige_dagsverk") ?: 0.0, sykefraversprosent = row.doubleOrNull("prosent") ?: 0.0, maskert = row.boolean("maskert"), - opprettet = row.localDateTime("sist_endret"), status = row.stringOrNull("status")?.let { IAProsessStatus.valueOf(it) }, @@ -267,12 +228,12 @@ class VirksomhetsinformasjonRepository(val dataSource: DataSource) { private fun Sorteringsnøkkel.tilOrderBy(): String { return when (this) { - NAVN_PÅ_VIRKSOMHET -> "ORDER BY virksomhet.navn" - ANTALL_PERSONER -> "ORDER BY statistikk.antall_personer" - SYKEFRAVÆRSPROSENT -> "ORDER BY statistikk_siste4.prosent" - TAPTE_DAGSVERK -> "ORDER BY statistikk_siste4.tapte_dagsverk" - MULIGE_DAGSVERK -> "ORDER BY statistikk_siste4.mulige_dagsverk" - SIST_ENDRET -> "ORDER BY ia_sak.endret" + NAVN_PÅ_VIRKSOMHET -> "ORDER BY navn" + ANTALL_PERSONER -> "ORDER BY antall_personer" + SYKEFRAVÆRSPROSENT -> "ORDER BY prosent" + TAPTE_DAGSVERK -> "ORDER BY tapte_dagsverk" + MULIGE_DAGSVERK -> "ORDER BY mulige_dagsverk" + SIST_ENDRET -> "ORDER BY endret" } } } diff --git "a/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/api/S\303\270keparametere.kt" "b/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/api/S\303\270keparametere.kt" index 9be2421d..2007be1d 100644 --- "a/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/api/S\303\270keparametere.kt" +++ "b/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/api/S\303\270keparametere.kt" @@ -20,7 +20,6 @@ import java.time.LocalDateTime data class Søkeparametere( val kommunenummer: Set, val næringsgruppeKoder: Set, - val periode: Periode, val sorteringsnøkkel: Sorteringsnøkkel, val sorteringsretning: Sorteringsretning, val sykefraværsprosentFra: Sykefraværsprosent?, @@ -37,7 +36,6 @@ data class Søkeparametere( fun toLogString() = "Søk med parametere:" + (sykefraværsprosentFra?.let { " $SYKEFRAVÆRSPROSENT_FRA=$sykefraværsprosentFra" } ?: "") + (sykefraværsprosentTil?.let { " $SYKEFRAVÆRSPROSENT_TIL=$sykefraværsprosentTil" } ?: "") + - " $KVARTAL=${periode.kvartal} $ÅRSTALL=${periode.årstall}" + (ansatteFra?.let { " $ANSATTE_FRA=$ansatteFra" } ?: "") + (ansatteTil?.let { " $ANSATTE_TIL=$ansatteTil" } ?: "") + (if (kommunenummer.isNotEmpty()) " $KOMMUNER=$kommunenummer" else "") + @@ -52,8 +50,6 @@ data class Søkeparametere( companion object { const val VIRKSOMHETER_PER_SIDE = 100 - const val KVARTAL = "kvartal" - const val ÅRSTALL = "arstall" const val KOMMUNER = "kommuner" const val FYLKER = "fylker" const val NÆRINGSGRUPPER = "neringsgrupper" @@ -73,16 +69,14 @@ data class Søkeparametere( fun ApplicationRequest.søkeparametere(gjeldendePeriode: Periode, geografiService: GeografiService, navAnsatt: NavAnsatt) = queryParameters[SYKEFRAVÆRSPROSENT_FRA].tilSykefraværsProsent().zip( queryParameters[SYKEFRAVÆRSPROSENT_TIL].tilSykefraværsProsent(), - Periode.tilValidertPeriode(kvartal = queryParameters[KVARTAL], årstall = queryParameters[ÅRSTALL], gjeldendePeriode), queryParameters[SIDE].tomSomNull()?.tilValidertHeltall() ?: Valid(1), queryParameters[ANSATTE_FRA].tomSomNull()?.tilValidertHeltall() ?: Valid(null), queryParameters[ANSATTE_TIL].tomSomNull()?.tilValidertHeltall() ?: Valid(null) - ) { sykefraværsProsentFra, sykefraværsProsentTil, periode, side, ansatteFra, ansatteTil -> + ) { sykefraværsProsentFra, sykefraværsProsentTil, side, ansatteFra, ansatteTil -> Søkeparametere( sykefraværsprosentFra = sykefraværsProsentFra, sykefraværsprosentTil = sykefraværsProsentTil, snittFilter = queryParameters[SNITT_FILTER].tomSomNull()?.let { SnittFilter.valueOf(it) }, - periode = periode, side = side, ansatteFra = ansatteFra, ansatteTil = ansatteTil, @@ -101,7 +95,7 @@ data class Søkeparametere( fun filtrerPåSektor(søkeparametere: Søkeparametere) = if(søkeparametere.sektor.isEmpty()) "" - else " AND virksomhet_statistikk_metadata.sektor in (select unnest(:sektorer)) " + else " AND sektor in (select unnest(:sektorer)) " fun filtrerPåEiere(søkeparametere: Søkeparametere) = if (søkeparametere.navIdenter.isEmpty()) "" @@ -124,32 +118,25 @@ data class Søkeparametere( fun filtrerPåKommuner(søkeparametere: Søkeparametere) = if (søkeparametere.kommunenummer.isEmpty()) "" - else " AND virksomhet.kommunenummer in (select unnest(:kommuner)) " + else " AND kommunenummer in (select unnest(:kommuner)) " fun filtrerPåSnitt(søkeparametere: Søkeparametere) = søkeparametere.snittFilter?.let { snittFilter -> - when (snittFilter) { - SnittFilter.BRANSJE_NÆRING_OVER -> """ AND ( - (bransje_siste4.prosent is null AND statistikk_siste4.prosent > naring_siste4.prosent) + (statistikk.bransje_prosent is null AND statistikk.prosent ${snittFilterTilSammenligningstegn(snittFilter)} statistikk.naring_prosent) OR - (bransje_siste4.prosent is not null AND statistikk_siste4.prosent > bransje_siste4.prosent) + (statistikk.bransje_prosent is not null AND statistikk.prosent ${snittFilterTilSammenligningstegn(snittFilter)} statistikk.bransje_prosent) ) """.trimIndent() - SnittFilter.BRANSJE_NÆRING_UNDER_ELLER_LIK -> - """ - AND ( - (bransje_siste4.prosent is null AND statistikk_siste4.prosent <= naring_siste4.prosent) - OR - (bransje_siste4.prosent is not null AND statistikk_siste4.prosent <= bransje_siste4.prosent) - ) - """.trimIndent() - else -> - "" - } } ?: "" + private fun snittFilterTilSammenligningstegn(snittFilter: SnittFilter) = + when (snittFilter) { + SnittFilter.BRANSJE_NÆRING_OVER -> ">" + SnittFilter.BRANSJE_NÆRING_UNDER_ELLER_LIK -> "<=" + } + fun joinTilNæringEllerBransje(søkeparametere: Søkeparametere) = if (søkeparametere.snittFilter == SnittFilter.BRANSJE_NÆRING_OVER || søkeparametere.snittFilter == SnittFilter.BRANSJE_NÆRING_UNDER_ELLER_LIK) {""" @@ -174,9 +161,9 @@ data class Søkeparametere( else """ AND ( - substr(vn.naringsundergruppe1, 1, 2) in (select unnest(:naringer)) - OR substr(vn.naringsundergruppe2, 1, 2) in (select unnest(:naringer)) - OR substr(vn.naringsundergruppe3, 1, 2) in (select unnest(:naringer)) + substr(naringsundergruppe1, 1, 2) in (select unnest(:naringer)) + OR substr(naringsundergruppe2, 1, 2) in (select unnest(:naringer)) + OR substr(naringsundergruppe3, 1, 2) in (select unnest(:naringer)) ${ if (søkeparametere.bransjeprogram.isNotEmpty()) { val koder = søkeparametere.bransjeprogram.flatMap { it.næringskoder }.groupBy { @@ -184,9 +171,9 @@ data class Søkeparametere( } val femsifrede = koder[5]?.joinToString { "'${it.take(2)}.${it.takeLast(3)}'" } femsifrede?.let { - "OR (vn.naringsundergruppe1 in (select (unnest(:naringer))))" + - "OR (vn.naringsundergruppe2 in (select (unnest(:naringer))))" + - "OR (vn.naringsundergruppe3 in (select (unnest(:naringer))))" + "OR (naringsundergruppe1 in (select (unnest(:naringer))))" + + "OR (naringsundergruppe2 in (select (unnest(:naringer))))" + + "OR (naringsundergruppe3 in (select (unnest(:naringer))))" } ?: "" } else "" } diff --git a/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/domene/Virksomhetsoversikt.kt b/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/domene/Virksomhetsoversikt.kt index ef9d58e6..a1f9318a 100644 --- a/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/domene/Virksomhetsoversikt.kt +++ b/src/main/kotlin/no/nav/lydia/sykefraversstatistikk/domene/Virksomhetsoversikt.kt @@ -2,7 +2,6 @@ package no.nav.lydia.sykefraversstatistikk.domene import kotlinx.datetime.LocalDate import no.nav.lydia.ia.sak.domene.IAProsessStatus -import java.time.LocalDateTime data class Virksomhetsoversikt( val virksomhetsnavn: String, @@ -14,7 +13,6 @@ data class Virksomhetsoversikt( val muligeDagsverk: Double, val sykefraversprosent: Double, val maskert: Boolean, - val opprettet: LocalDateTime, val status: IAProsessStatus?, val eidAv: String?, val sistEndret: LocalDate? diff --git a/src/main/kotlin/no/nav/lydia/vedlikehold/StatistikkViewOppdaterer.kt b/src/main/kotlin/no/nav/lydia/vedlikehold/StatistikkViewOppdaterer.kt new file mode 100644 index 00000000..ea8aaf55 --- /dev/null +++ b/src/main/kotlin/no/nav/lydia/vedlikehold/StatistikkViewOppdaterer.kt @@ -0,0 +1,66 @@ +package no.nav.lydia.vedlikehold + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlinx.datetime.Clock.System.now +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime +import kotliquery.queryOf +import kotliquery.sessionOf +import kotliquery.using +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import javax.sql.DataSource +import kotlin.coroutines.CoroutineContext +import kotlin.system.measureTimeMillis + +object StatistikkViewOppdaterer: CoroutineScope { + private val logger: Logger = LoggerFactory.getLogger(this::class.java) + lateinit var job: Job + lateinit var dataSource: DataSource + + override val coroutineContext: CoroutineContext + get() = Dispatchers.IO + job + + init { + Runtime.getRuntime().addShutdownHook(Thread(StatistikkViewOppdaterer::cancel)) + } + + fun run(dataSource: DataSource) { + logger.info("Starter statistikkview oppdaterer") + + job = Job() + StatistikkViewOppdaterer.dataSource = dataSource + + launch { + while (job.isActive) { + if (now().toLocalDateTime(TimeZone.UTC).hour == 0) { + logger.info("Oppdaterer statistikkview...") + val tidBrukt = measureTimeMillis { + using(sessionOf(dataSource)) { session -> + session.run( + queryOf( + "REFRESH MATERIALIZED VIEW virksomhetsstatistikk_for_prioritering" + ).asExecute + ) + } + } + logger.info("Oppdaterte statistikkview på $tidBrukt ms") + } else + logger.debug("Statistikkview oppdateres kun mellom kl 00:00 og 00:59") + + delay(1000 * 60 * 30) // 30 minutter + } + } + } + + fun cancel() = runBlocking { + logger.info("Avslutter statistikkview oppdaterer") + job.cancelAndJoin() + } +} \ No newline at end of file diff --git a/src/main/resources/db/migration/V58__legg_til_materialized_statistikk_view.sql b/src/main/resources/db/migration/V58__legg_til_materialized_statistikk_view.sql new file mode 100644 index 00000000..6d2c4d29 --- /dev/null +++ b/src/main/resources/db/migration/V58__legg_til_materialized_statistikk_view.sql @@ -0,0 +1,57 @@ +CREATE MATERIALIZED VIEW virksomhetsstatistikk_for_prioritering +AS +SELECT + virksomhet.orgnr AS orgnr, + virksomhet.navn AS navn, + virksomhet.kommunenummer AS kommunenummer, + virksomhet_statistikk_metadata.sektor AS sektor, + vn.naringsundergruppe1 AS naringsundergruppe1, + vn.naringsundergruppe2 AS naringsundergruppe2, + vn.naringsundergruppe3 AS naringsundergruppe3, + statistikk_siste_kvartal.arstall AS arstall, + statistikk_siste_kvartal.kvartal AS kvartal, + statistikk_siste_kvartal.antall_personer AS antall_personer_siste_kvartal, + statistikk.tapte_dagsverk AS tapte_dagsverk, + statistikk.mulige_dagsverk AS mulige_dagsverk, + statistikk.prosent AS prosent, + statistikk.maskert AS maskert, + statistikk.sist_endret AS statistikk_sist_endret, + bransje.kode AS bransje_kode, + bransje.prosent AS bransje_prosent, + naring.kode AS naring_kode, + naring.prosent AS naring_prosent +FROM + sykefravar_statistikk_virksomhet AS statistikk_siste_kvartal +JOIN virksomhet USING (orgnr) +JOIN sykefravar_statistikk_virksomhet_siste_4_kvartal AS statistikk ON ( + statistikk_siste_kvartal.orgnr = statistikk.orgnr + AND statistikk_siste_kvartal.kvartal = statistikk.publisert_kvartal + AND statistikk_siste_kvartal.arstall = statistikk.publisert_arstall +) +JOIN virksomhet_naringsundergrupper AS vn ON (virksomhet.id = vn.virksomhet) +LEFT JOIN virksomhet_statistikk_metadata ON ( + virksomhet.orgnr = virksomhet_statistikk_metadata.orgnr +) +LEFT JOIN naringsundergrupper_per_bransje AS bransjeprogram ON ( + vn.naringsundergruppe1 = bransjeprogram.naringsundergruppe +) +LEFT JOIN sykefravar_statistikk_kategori_siste_4_kvartal AS bransje ON ( + bransjeprogram.bransje = bransje.kode + AND bransje.kategori = 'BRANSJE' + AND bransje.publisert_kvartal = statistikk_siste_kvartal.kvartal + AND bransje.publisert_arstall = statistikk_siste_kvartal.arstall +) +JOIN sykefravar_statistikk_kategori_siste_4_kvartal AS naring ON ( + substr(vn.naringsundergruppe1, 1, 2) = naring.kode + AND naring.kategori = 'NÆRING' + AND naring.publisert_kvartal = statistikk_siste_kvartal.kvartal + AND naring.publisert_arstall = statistikk_siste_kvartal.arstall +) +WHERE + statistikk_siste_kvartal.arstall = ( + SELECT gjeldende_arstall FROM siste_publiseringsinfo ORDER BY gjeldende_arstall DESC, gjeldende_kvartal DESC LIMIT 1 + ) + AND statistikk_siste_kvartal.kvartal = ( + SELECT gjeldende_kvartal FROM siste_publiseringsinfo ORDER BY gjeldende_arstall DESC, gjeldende_kvartal DESC LIMIT 1 + ) + AND virksomhet.status = 'AKTIV'; diff --git a/src/test/kotlin/no/nav/lydia/container/audit/AuditLogTest.kt b/src/test/kotlin/no/nav/lydia/container/audit/AuditLogTest.kt index 5de0a73e..48dc54a9 100644 --- a/src/test/kotlin/no/nav/lydia/container/audit/AuditLogTest.kt +++ b/src/test/kotlin/no/nav/lydia/container/audit/AuditLogTest.kt @@ -7,7 +7,6 @@ import no.nav.lydia.helper.SakHelper import no.nav.lydia.helper.StatistikkHelper import no.nav.lydia.helper.TestContainerHelper import no.nav.lydia.helper.TestContainerHelper.Companion.shouldContainLog -import no.nav.lydia.helper.TestData import no.nav.lydia.helper.TestVirksomhet import no.nav.lydia.helper.VirksomhetHelper import no.nav.lydia.helper.VirksomhetHelper.Companion.nyttOrgnummer @@ -223,17 +222,16 @@ class AuditLogTest { @Test fun `auditlogger søk med få parametere`() { - val gjeldendePeriode = TestData.gjeldendePeriode val saksbehandler = mockOAuth2Server.saksbehandler1 StatistikkHelper.hentSykefravær() .also { lydiaApiContainer shouldContainLog auditLog( - path = "/sykefraversstatistikk?kvartal=&arstall=&kommuner=&fylker=&neringsgrup", + path = "/sykefraversstatistikk?kommuner=&fylker=&neringsgrupper=&sorteringsnok", method = "GET", navIdent = saksbehandler.navIdent, auditType = AuditType.access, tillat = Tillat.Ja, - melding = "Søk med parametere: kvartal=${gjeldendePeriode.kvartal} arstall=${gjeldendePeriode.årstall} sorteringsnokkel=tapte_dagsverk sorteringsretning=desc side=1" + melding = "Søk med parametere: sorteringsnokkel=tapte_dagsverk sorteringsretning=desc side=1" ) } } @@ -242,8 +240,6 @@ class AuditLogTest { fun `auditlogger søk med masse parametere`() { val saksbehandler = mockOAuth2Server.saksbehandler1 StatistikkHelper.hentSykefravær( - kvartal = "3", - årstall = "2022", kommuner = "1750", fylker = "17", næringsgrupper = "bil", @@ -260,12 +256,12 @@ class AuditLogTest { ) .also { lydiaApiContainer shouldContainLog auditLog( - path = "/sykefraversstatistikk?kvartal=3&arstall=2022&kommuner=1750&fylker=17&", + path = "/sykefraversstatistikk?kommuner=1750&fylker=17&neringsgrupper=bil&sort", method = "GET", navIdent = saksbehandler.navIdent, auditType = AuditType.access, tillat = Tillat.Ja, - melding = "Søk med parametere: sykefraversprosentFra=5.0 sykefraversprosentTil=30.0 kvartal=3 arstall=2022 ansatteFra=10 ansatteTil=50 kommuner=[1750] neringsgrupper=[bil] iaStatus=50 sorteringsnokkel=tapte_dagsverk sorteringsretning=asc side=2" + melding = "Søk med parametere: sykefraversprosentFra=5.0 sykefraversprosentTil=30.0 ansatteFra=10 ansatteTil=50 kommuner=[1750] neringsgrupper=[bil] iaStatus=50 sorteringsnokkel=tapte_dagsverk sorteringsretning=asc side=2" ) } } diff --git a/src/test/kotlin/no/nav/lydia/container/sykefraversstatistikk/SykefraversstatistikkApiTest.kt b/src/test/kotlin/no/nav/lydia/container/sykefraversstatistikk/SykefraversstatistikkApiTest.kt index c15c0372..8ebd849c 100644 --- a/src/test/kotlin/no/nav/lydia/container/sykefraversstatistikk/SykefraversstatistikkApiTest.kt +++ b/src/test/kotlin/no/nav/lydia/container/sykefraversstatistikk/SykefraversstatistikkApiTest.kt @@ -659,23 +659,6 @@ class SykefraversstatistikkApiTest { }) } - @Test - fun `skal kunne hente virksomheter for et bestemt år og kvartal`() { - val forrigePeriode = gjeldendePeriode.forrigePeriode() - hentSykefravær( - success = { response -> - response.data shouldHaveAtLeastSize 1 - response.data.forAll { - it.kvartal shouldBe forrigePeriode.kvartal - it.arstall shouldBe forrigePeriode.årstall - } - }, - kvartal = forrigePeriode.kvartal.toString(), - årstall = forrigePeriode.årstall.toString(), - token = mockOAuth2Server.saksbehandler1.token - ) - } - @Test fun `skal kunne hente alle virksomheter`() { hentSykefravær(success = { response -> @@ -1089,9 +1072,6 @@ class SykefraversstatistikkApiTest { hentSykefraværRespons(sykefraværsprosentFra = "NaN").statuskode() shouldBe 400 hentSykefraværRespons(sykefraværsprosentFra = "aaa").statuskode() shouldBe 400 hentSykefraværRespons(side = "side").statuskode() shouldBe 400 - hentSykefraværRespons(kvartal = "5").statuskode() shouldBe 400 - hentSykefraværRespons(kvartal = "kvartal").statuskode() shouldBe 400 - hentSykefraværRespons(årstall = "årstall").statuskode() shouldBe 400 hentSykefraværRespons(ansatteFra = "ansatteFra").statuskode() shouldBe 400 hentSykefraværRespons(ansatteTil = "ansatteTil").statuskode() shouldBe 400 } diff --git a/src/test/kotlin/no/nav/lydia/helper/TestContainerHelper.kt b/src/test/kotlin/no/nav/lydia/helper/TestContainerHelper.kt index febf8fbc..e47fa17f 100644 --- a/src/test/kotlin/no/nav/lydia/helper/TestContainerHelper.kt +++ b/src/test/kotlin/no/nav/lydia/helper/TestContainerHelper.kt @@ -556,8 +556,6 @@ class StatistikkHelper { companion object { fun hentSykefravær( success: (VirksomhetsoversiktResponsDto) -> Unit, - kvartal: String = "", - årstall: String = "", kommuner: String = "", fylker: String = "", næringsgrupper: String = "", @@ -574,8 +572,6 @@ class StatistikkHelper { token: String = oauth2ServerContainer.saksbehandler1.token, ) = hentSykefraværRespons( - kvartal = kvartal, - årstall = årstall, kommuner = kommuner, fylker = fylker, næringsgrupper = næringsgrupper, @@ -596,8 +592,6 @@ class StatistikkHelper { }) fun hentSykefravær( - kvartal: String = "", - årstall: String = "", kommuner: String = "", fylker: String = "", næringsgrupper: String = "", @@ -616,8 +610,6 @@ class StatistikkHelper { token: String = oauth2ServerContainer.saksbehandler1.token, ) = hentSykefraværRespons( - kvartal = kvartal, - årstall = årstall, kommuner = kommuner, fylker = fylker, næringsgrupper = næringsgrupper, @@ -637,8 +629,6 @@ class StatistikkHelper { ).third.get() fun hentSykefraværRespons( - kvartal: String = "", - årstall: String = "", kommuner: String = "", fylker: String = "", næringsgrupper: String = "", @@ -658,9 +648,7 @@ class StatistikkHelper { ) = lydiaApiContainer.performGet( SYKEFRAVERSSTATISTIKK_PATH + - "?${Søkeparametere.KVARTAL}=$kvartal" + - "&${Søkeparametere.ÅRSTALL}=$årstall" + - "&${Søkeparametere.KOMMUNER}=$kommuner" + + "?${Søkeparametere.KOMMUNER}=$kommuner" + "&${Søkeparametere.FYLKER}=$fylker" + "&${Søkeparametere.NÆRINGSGRUPPER}=$næringsgrupper" + "&${Søkeparametere.SORTERINGSNØKKEL}=$sorteringsnokkel" + @@ -735,8 +723,6 @@ class StatistikkHelper { } fun hentTotaltAntallTreffISykefravær( - kvartal: String = "", - årstall: String = "", kommuner: String = "", fylker: String = "", næringsgrupper: String = "", @@ -754,9 +740,7 @@ class StatistikkHelper { token: String = oauth2ServerContainer.saksbehandler1.token, ): Int { return lydiaApiContainer.performGet("$SYKEFRAVERSSTATISTIKK_PATH/$ANTALL_TREFF" + - "?${Søkeparametere.KVARTAL}=$kvartal" + - "&${Søkeparametere.ÅRSTALL}=$årstall" + - "&${Søkeparametere.KOMMUNER}=$kommuner" + + "?${Søkeparametere.KOMMUNER}=$kommuner" + "&${Søkeparametere.FYLKER}=$fylker" + "&${Søkeparametere.NÆRINGSGRUPPER}=$næringsgrupper" + "&${Søkeparametere.SORTERINGSNØKKEL}=$sorteringsnokkel" + diff --git a/src/test/kotlin/no/nav/lydia/helper/VirksomhetHelper.kt b/src/test/kotlin/no/nav/lydia/helper/VirksomhetHelper.kt index 4de0763e..418e03c5 100644 --- a/src/test/kotlin/no/nav/lydia/helper/VirksomhetHelper.kt +++ b/src/test/kotlin/no/nav/lydia/helper/VirksomhetHelper.kt @@ -103,6 +103,8 @@ class VirksomhetHelper { kafkaContainerHelper.sendStatistikkMetadataVirksomhetIBulkOgVentTilKonsumert( testData.sykefraværsstatistikkMetadataVirksomhetKafkaMeldinger().toList() ) + + TestContainerHelper.postgresContainer.performUpdate("REFRESH MATERIALIZED VIEW virksomhetsstatistikk_for_prioritering") } private fun sendOppdateringForVirksomhet( @@ -112,6 +114,7 @@ class VirksomhetHelper { kafkaContainerHelper.sendBrregOppdatering( virksomhet.tilOppdateringVirksomhet(endringstype) ) + TestContainerHelper.postgresContainer.performUpdate("REFRESH MATERIALIZED VIEW virksomhetsstatistikk_for_prioritering") } fun TestVirksomhet.genererEndretNavn() = this.navn.reversed()