Skip to content

Commit

Permalink
Sykefraværstatistikk må ta hensyn til år og kvartal
Browse files Browse the repository at this point in the history
Dersom det blir gjort en reeksport av gammel statistikk så blir disse liggende som siste melding på kafka.
Dette skjedde i prod i februar.
Denne PR fikser problemet uten å dra ned eksisterende endepunkt som vi vet viser riktig data pga full eksport gjort 29. feb.

Det kommer en ny PR straks som tar i bruk nye tabeller og rydder opp koden.
Dette for å unngå nedetid mens vi fyller tabellen.
  • Loading branch information
kenglxn committed Mar 7, 2024
1 parent 440ffb2 commit 2d5c25e
Show file tree
Hide file tree
Showing 4 changed files with 338 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class SykefraværstatistikkController(
other = { "1" },
)

// TODO: gjør v2 om til default når ajour
@GetMapping("/api/sykefravaerstatistikk/{orgnr}")
fun getStatistikk(
@PathVariable orgnr: String,
Expand All @@ -30,6 +31,40 @@ class SykefraværstatistikkController(
.hentOrganisasjonerBasertPaRettigheter(authenticatedUserHolder.fnr, tjenestekode, tjenesteversjon)
.firstOrNull { it.organizationNumber == orgnr }

return if (org != null) {
val statistikk = sykefraværstatistikkRepository.virksomhetstatistikk_v1(orgnr)?.let {
StatistikkRespons(
type = it.kategori,
label = org.name ?: it.kode,
prosent = it.prosent,
)
} ?: sykefraværstatistikkRepository.statistikk_v1(orgnr)?.let {
StatistikkRespons(
type = it.kategori,
label = it.kode,
prosent = it.prosent,
)
}
statistikk.asResponseEntity()
} else {
sykefraværstatistikkRepository.statistikk_v1(orgnr)?.let {
StatistikkRespons(
type = it.kategori,
label = it.kode,
prosent = it.prosent,
)
}.asResponseEntity()
}
}

@GetMapping("/api/sykefravaerstatistikk_v2/{orgnr}")
fun getStatistikkV2(
@PathVariable orgnr: String,
): ResponseEntity<StatistikkRespons> {
val org = altinnService
.hentOrganisasjonerBasertPaRettigheter(authenticatedUserHolder.fnr, tjenestekode, tjenesteversjon)
.firstOrNull { it.organizationNumber == orgnr }

return if (org != null) {
val statistikk = sykefraværstatistikkRepository.virksomhetstatistikk(orgnr)?.let {
StatistikkRespons(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.ObjectMapper
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.springframework.context.annotation.Profile
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
import org.springframework.kafka.annotation.KafkaListener
import org.springframework.stereotype.Repository
import org.springframework.stereotype.Service
import java.math.BigDecimal
import java.sql.PreparedStatement

data class Statistikk(
val kategori: String,
Expand All @@ -22,82 +20,122 @@ data class Statistikk(

@Repository
class SykefraværstatistikkRepository(
private val jdbcTemplate: JdbcTemplate,
private val namedParameterJdbcTemplate: NamedParameterJdbcTemplate,
) {
fun virksomhetstatistikk(virksomhetsnummer: String): Statistikk? {
return namedParameterJdbcTemplate.queryForList(
"""
select kategori, kode, prosent
from sykefraværstatistikk
where kategori = 'VIRKSOMHET' and kode = :virksomhetsnummer
""".trimIndent(),
mapOf("virksomhetsnummer" to virksomhetsnummer)
).firstOrNull()?.let {
Statistikk(
kategori = it["kategori"] as String,
kode = it["kode"] as String,
prosent = (it["prosent"] as BigDecimal).toDouble(),
)
}
// TODO: fjern når "v2" er ajour
fun virksomhetstatistikk_v1(virksomhetsnummer: String) = namedParameterJdbcTemplate.queryForList(
"""
select kategori, kode, prosent
from sykefraværstatistikk
where kategori = 'VIRKSOMHET' and kode = :virksomhetsnummer
""".trimIndent(),
mapOf("virksomhetsnummer" to virksomhetsnummer)
).firstOrNull()?.let {
Statistikk(
kategori = it["kategori"] as String,
kode = it["kode"] as String,
prosent = (it["prosent"] as BigDecimal).toDouble(),
)
}

fun statistikk(virksomhetsnummer: String): Statistikk? {
return namedParameterJdbcTemplate.queryForList(
""" -- TODO: vurder eksplisitte felt i stedet for coalesce her, kan by på problemer
select coalesce(sb.kategori, sn.kategori) as kategori, coalesce(sb.kode, sn.kode) as kode, coalesce(sb.prosent, sn.prosent) as prosent
from sykefraværstatistikk_metadata meta
left join sykefraværstatistikk sb on sb.kategori = 'BRANSJE' and sb.kode = meta.bransje
left join sykefraværstatistikk sn on sn.kategori = 'NÆRING' and sn.kode = meta.næring
where meta.virksomhetsnummer = :virksomhetsnummer
and coalesce(sb.prosent, sn.prosent) is not null
order by coalesce(sb.kategori, sn.kategori)
""".trimIndent(),
mapOf("virksomhetsnummer" to virksomhetsnummer)
).firstOrNull()?.let {
Statistikk(
kategori = it["kategori"] as String,
kode = it["kode"] as String,
prosent = (it["prosent"] as BigDecimal).toDouble(),
)
}
// TODO: fjern når "v2" er ajour
fun statistikk_v1(virksomhetsnummer: String) = namedParameterJdbcTemplate.queryForList(
""" -- TODO: vurder eksplisitte felt i stedet for coalesce her, kan by på problemer
select coalesce(sb.kategori, sn.kategori) as kategori, coalesce(sb.kode, sn.kode) as kode, coalesce(sb.prosent, sn.prosent) as prosent
from sykefraværstatistikk_metadata meta
left join sykefraværstatistikk sb on sb.kategori = 'BRANSJE' and sb.kode = meta.bransje
left join sykefraværstatistikk sn on sn.kategori = 'NÆRING' and sn.kode = meta.næring
where meta.virksomhetsnummer = :virksomhetsnummer
and coalesce(sb.prosent, sn.prosent) is not null
order by coalesce(sb.kategori, sn.kategori)
""".trimIndent(),
mapOf("virksomhetsnummer" to virksomhetsnummer)
).firstOrNull()?.let {
Statistikk(
kategori = it["kategori"] as String,
kode = it["kode"] as String,
prosent = (it["prosent"] as BigDecimal).toDouble(),
)
}

fun virksomhetstatistikk(virksomhetsnummer: String) = namedParameterJdbcTemplate.queryForList(
"""
select kategori, kode, prosent
from sykefraværstatistikk_v2
where kategori = 'VIRKSOMHET' and kode = :virksomhetsnummer
order by arstall desc, kvartal desc
""".trimIndent(),
mapOf("virksomhetsnummer" to virksomhetsnummer)
).firstOrNull()?.let {
Statistikk(
kategori = it["kategori"] as String,
kode = it["kode"] as String,
prosent = (it["prosent"] as BigDecimal).toDouble(),
)
}

fun statistikk(virksomhetsnummer: String) = namedParameterJdbcTemplate.queryForList(
""" -- TODO: vurder eksplisitte felt i stedet for coalesce her, kan by på problemer
select
coalesce(sb.kategori, sn.kategori) as kategori,
coalesce(sb.kode, sn.kode) as kode,
coalesce(sb.prosent, sn.prosent) as prosent
from sykefraværstatistikk_metadata_v2 meta
left join sykefraværstatistikk_v2 sb on (sb.kode = meta.bransje and sb.arstall = meta.arstall and sb.kvartal = meta.kvartal)
left join sykefraværstatistikk_v2 sn on (sn.kode = meta.næring and sn.arstall = meta.arstall and sn.kvartal = meta.kvartal)
where meta.virksomhetsnummer = :virksomhetsnummer
and coalesce(sb.prosent, sn.prosent) is not null
order by meta.arstall desc, meta.kvartal desc, kategori
""".trimIndent(),
mapOf("virksomhetsnummer" to virksomhetsnummer)
).firstOrNull()?.let {
Statistikk(
kategori = it["kategori"] as String,
kode = it["kode"] as String,
prosent = (it["prosent"] as BigDecimal).toDouble(),
)
}

fun processMetadataVirksomhet(metadata: MetadataVirksomhetDto) {
jdbcTemplate.update(
namedParameterJdbcTemplate.update(
"""
insert into sykefraværstatistikk_metadata(virksomhetsnummer, bransje, næring)
values(?, ?, ?)
on conflict (virksomhetsnummer)
insert into sykefraværstatistikk_metadata_v2(virksomhetsnummer, bransje, næring, arstall, kvartal)
values(:virksomhetsnummer, :bransje, :næring, :arstall, :kvartal)
on conflict (virksomhetsnummer, arstall, kvartal)
do update set
virksomhetsnummer = EXCLUDED.virksomhetsnummer,
bransje = EXCLUDED.bransje,
næring = EXCLUDED.næring;
""".trimIndent()
) { ps: PreparedStatement ->
ps.setString(1, metadata.virksomhetsnummer)
ps.setString(2, metadata.bransje)
ps.setString(3, metadata.næring)
}
""".trimIndent(),
mapOf(
"virksomhetsnummer" to metadata.virksomhetsnummer,
"bransje" to metadata.bransje,
"næring" to metadata.næring,
"arstall" to metadata.arstall,
"kvartal" to metadata.kvartal,
)
)
}

fun processStatistikkategori(statistikkategori: StatistikkategoriDto) {
jdbcTemplate.update(
namedParameterJdbcTemplate.update(
"""
insert into sykefraværstatistikk(kode, kategori, prosent)
values(?, ?, ?)
on conflict (kode)
insert into sykefraværstatistikk_v2(kode, kategori, prosent, arstall, kvartal)
values(:kode, :kategori, :prosent, :arstall, :kvartal)
on conflict (kode, arstall, kvartal)
do update set
kode = EXCLUDED.kode,
kategori = EXCLUDED.kategori,
prosent = EXCLUDED.prosent;
""".trimIndent()
) { ps: PreparedStatement ->
ps.setString(1, statistikkategori.kode)
ps.setString(2, statistikkategori.kategori)
ps.setDouble(3, statistikkategori.prosent)
}
""".trimIndent(),
mapOf(
"kode" to statistikkategori.kode,
"kategori" to statistikkategori.kategori,
"prosent" to statistikkategori.prosent,
"arstall" to statistikkategori.siste4Kvartal?.arstall,
"kvartal" to statistikkategori.siste4Kvartal?.kvartal,
)
)
}

}
Expand All @@ -110,7 +148,7 @@ class SykefraværstatistikkKafkaListener(
) {
@Profile("dev-gcp", "prod-gcp")
@KafkaListener(
id = "min-side-arbeidsgiver-sfmeta-1",
id = "min-side-arbeidsgiver-sfmeta-2",
topics = ["arbeidsgiver.sykefravarsstatistikk-metadata-virksomhet-v1"],
containerFactory = "errorLoggingKafkaListenerContainerFactory"
)
Expand All @@ -121,7 +159,7 @@ class SykefraværstatistikkKafkaListener(

@Profile("dev-gcp", "prod-gcp")
@KafkaListener(
id = "min-side-arbeidsgiver-sfstats-1",
id = "min-side-arbeidsgiver-sfstats-2",
topics = [
"arbeidsgiver.sykefravarsstatistikk-virksomhet-v1",
"arbeidsgiver.sykefravarsstatistikk-naring-v1",
Expand All @@ -144,6 +182,8 @@ data class MetadataVirksomhetDto @JsonCreator(mode = JsonCreator.Mode.PROPERTIES
@param:JsonProperty("orgnr") val virksomhetsnummer: String,
@param:JsonProperty("naring") valring: String,
@param:JsonProperty("bransje") val bransje: String?,
@param:JsonProperty("arstall") val arstall: Number,
@param:JsonProperty("kvartal") val kvartal: Number,
)

/**
Expand All @@ -162,5 +202,7 @@ data class StatistikkategoriDto @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
@JsonIgnoreProperties(ignoreUnknown = true)
data class ProsentWrapper @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) constructor(
@param:JsonProperty("prosent") val prosent: Double,
@param:JsonProperty("arstall") val arstall: Number,
@param:JsonProperty("kvartal") val kvartal: Number,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
create table sykefraværstatistikk_metadata_v2
(
virksomhetsnummer text not null,
arstall numeric not null,
kvartal numeric not null,
bransje text,
næring text not null,
primary key (virksomhetsnummer, arstall, kvartal)
);

create table sykefraværstatistikk_v2
(
kode text not null,
arstall numeric not null,
kvartal numeric not null,
kategori text not null,
prosent decimal not null,
primary key (kode, arstall, kvartal)
);
Loading

0 comments on commit 2d5c25e

Please sign in to comment.