summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul-Christian Volkmer2026-03-10 11:14:28 +0100
committerGitHub2026-03-10 10:14:28 +0000
commitec3f472f8f37a3d340ddd3a042ecb7f26bd311db (patch)
treef1ebaecdbf68e132a4e6ea92153589e8f6f82288 /src
parent65846446d2f6576875b0de982e93127b0c1f2d83 (diff)
feat: show submission statistics table (#260)
Diffstat (limited to 'src')
-rw-r--r--src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsControllerTest.kt5
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt31
-rw-r--r--src/main/resources/templates/statistics.html32
3 files changed, 66 insertions, 2 deletions
diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsControllerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsControllerTest.kt
index cb19e1a..f375f2c 100644
--- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsControllerTest.kt
+++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsControllerTest.kt
@@ -21,6 +21,7 @@ package dev.dnpm.etl.processor.web
import dev.dnpm.etl.processor.config.AppConfiguration
import dev.dnpm.etl.processor.config.AppSecurityConfiguration
+import dev.dnpm.etl.processor.services.RequestService
import org.htmlunit.WebClient
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -30,6 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.TestPropertySource
+import org.springframework.test.context.bean.override.mockito.MockitoBean
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.get
@@ -49,6 +51,7 @@ import org.springframework.test.web.servlet.htmlunit.MockMvcWebClientBuilder
"app.security.admin-password={noop}very-secret",
],
)
+@MockitoBean(types = [RequestService::class])
class StatisticsControllerTest {
private lateinit var mockMvc: MockMvc
private lateinit var webClient: WebClient
@@ -62,7 +65,7 @@ class StatisticsControllerTest {
}
@Test
- fun testShouldRequestLoginPage() {
+ fun testShouldRequestStatisticsPage() {
mockMvc.get("/statistics").andExpect {
status { isOk() }
view { name("statistics") }
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt
index e48d5df..8dfe595 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt
@@ -19,18 +19,47 @@
package dev.dnpm.etl.processor.web
+import dev.dnpm.etl.processor.monitoring.RequestStatus
+import dev.dnpm.etl.processor.monitoring.RequestType
+import dev.dnpm.etl.processor.monitoring.SubmissionType
+import dev.dnpm.etl.processor.services.RequestService
+import net.sf.saxon.tree.tiny.Statistics
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import java.time.Instant
+import java.time.ZoneId
+import java.time.format.DateTimeFormatter
@Controller
@RequestMapping(path = ["/statistics"])
-class StatisticsController {
+class StatisticsController(
+ private val requestService: RequestService,
+) {
@GetMapping
fun index(model: Model): String {
+ val submissions =
+ requestService
+ .findAll()
+ .asSequence()
+ .filter { it.type == RequestType.MTB_FILE }
+ .filter { listOf(RequestStatus.SUCCESS, RequestStatus.WARNING).contains(it.status) }
+ .sortedByDescending { it.processedAt }
+ .groupBy {
+ val formatter = DateTimeFormatter.ofPattern("yyyy-MM").withZone(ZoneId.systemDefault())
+ formatter.format(it.processedAt)
+ }.map {
+ mapOf(
+ "month" to it.key,
+ "accepted" to it.value.count { it.submissionAccepted },
+ "initial" to it.value.count { it.submissionType == SubmissionType.INITIAL },
+ "submissions" to it.value.size,
+ )
+ }.toList()
+
model.addAttribute("now", Instant.now())
+ model.addAttribute("submissions", submissions)
return "statistics"
}
}
diff --git a/src/main/resources/templates/statistics.html b/src/main/resources/templates/statistics.html
index 1da382c..231bfe9 100644
--- a/src/main/resources/templates/statistics.html
+++ b/src/main/resources/templates/statistics.html
@@ -14,6 +14,38 @@
</p>
<section>
+ <h2>Submissions</h2>
+ <p>
+ Die übermittelten Meldungen sind nach Monaten absteigen sortiert.
+ </p>
+ <p>
+ Achtung: Die Anzahl der Meldebestätigungen und die Anzahl der initialen Meldungen
+ werden erst seit Version 0.15 erfasst.
+ </p>
+ <div class="border">
+ <table>
+ <thead>
+ <tr>
+ <th>Monat</th>
+ <th>Mit Meldebestätigung</th>
+ <th>Initiale Meldungen</th>
+ <th>Meldungen Gesamt</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr th:each="submission : ${submissions}">
+ <td th:text="${submission['month']}"></td>
+ <td th:text="${submission['accepted']}"></td>
+ <td th:text="${submission['initial']}"></td>
+ <td th:text="${submission['submissions']}"></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </section>
+
+
+ <section>
<h2>MTB-File-Anfragen</h2>
<p>
Anfragen zur Aktualisierung von Patientendaten durch Übermittlung eines MTB-Files.