/* * This file is part of ETL-Processor * * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package dev.dnpm.etl.processor.web import dev.dnpm.etl.processor.NotFoundException import dev.dnpm.etl.processor.PatientPseudonym import dev.dnpm.etl.processor.RequestId import dev.dnpm.etl.processor.Tan import dev.dnpm.etl.processor.config.AppConfigProperties import dev.dnpm.etl.processor.monitoring.ReportService import dev.dnpm.etl.processor.services.RequestService import dev.dnpm.etl.processor.services.filter import org.springframework.core.convert.converter.Converter import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort import org.springframework.data.web.PageableDefault import org.springframework.security.core.context.SecurityContextHolder import org.springframework.stereotype.Component import org.springframework.stereotype.Controller import org.springframework.ui.Model import org.springframework.web.bind.annotation.* @Controller @RequestMapping(path = ["/"]) class HomeController( private val requestService: RequestService, private val reportService: ReportService, private val appConfigProperties: AppConfigProperties, ) { @GetMapping fun index( @RequestParam(name = "q", required = false) queryString: String?, @RequestParam(name = "f", required = false) filter: RequestService.Filter?, @PageableDefault(page = 0, size = 10, sort = ["processedAt"], direction = Sort.Direction.DESC) pageable: Pageable, model: Model, ): String { val isAdminOrUser = SecurityContextHolder .getContext() .authentication ?.authorities ?.any { it.authority == "ROLE_USER" || it.authority == "ROLE_ADMIN" } == true val requests = // Only available for logged-in admins or users if (null != queryString && isAdminOrUser) { model.addAttribute("query", queryString) if (null != filter) { model.addAttribute("filter", filter.value) requestService .searchRequestLike(PatientPseudonym(queryString), Tan(queryString)) .filter(filter, pageable) } else { requestService .searchRequestLike(PatientPseudonym(queryString), Tan(queryString), pageable) } } else { requestService.findAll(pageable) } model.addAttribute("requests", requests) model.addAttribute("postInitialSubmissionBlock", appConfigProperties.postInitialSubmissionBlock) return "index" } @GetMapping(path = ["patient/{patientPseudonym}"]) fun byPatient( @PathVariable patientPseudonym: PatientPseudonym, @PageableDefault(page = 0, size = 10, sort = ["processedAt"], direction = Sort.Direction.DESC) pageable: Pageable, model: Model, ): String { val requests = requestService.findRequestByPatientId(patientPseudonym, pageable) model.addAttribute("patientPseudonym", patientPseudonym.value) model.addAttribute("requests", requests) model.addAttribute("postInitialSubmissionBlock", appConfigProperties.postInitialSubmissionBlock) return "index" } @GetMapping(path = ["/report/{id}"]) fun report( @PathVariable id: RequestId, model: Model, ): String { val request = requestService.findByUuid(id).orElse(null) ?: throw NotFoundException() model.addAttribute("request", request) model.addAttribute("issues", reportService.deserialize(request.report?.dataQualityReport)) model.addAttribute("postInitialSubmissionBlock", appConfigProperties.postInitialSubmissionBlock) return "report" } @PutMapping(path = ["/submission/{id}/accepted"]) fun acceptSubmission( @PathVariable id: RequestId, model: Model, ): String { val request = requestService.findByUuid(id).orElse(null) ?: throw NotFoundException() request.submissionAccepted = true val savedRequest = requestService.save(request) model.addAttribute("request", savedRequest) model.addAttribute("postInitialSubmissionBlock", appConfigProperties.postInitialSubmissionBlock) return "fragments :: request" } @DeleteMapping(path = ["/submission/{id}/accepted"]) fun unacceptSubmission( @PathVariable id: RequestId, model: Model, ): String { val request = requestService.findByUuid(id).orElse(null) ?: throw NotFoundException() request.submissionAccepted = false val savedRequest = requestService.save(request) model.addAttribute("request", savedRequest) model.addAttribute("postInitialSubmissionBlock", appConfigProperties.postInitialSubmissionBlock) return "fragments :: request" } @Component class FilterConverter : Converter { override fun convert(source: String): RequestService.Filter? { return when (source) { "all-dip" -> RequestService.Filter.ALL_DIP "confirmed" -> RequestService.Filter.CONFIRMED "unconfirmed" -> RequestService.Filter.UNCONFIRMED else -> null } } } }