diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/CSV.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/CSV.kt new file mode 100644 index 0000000..e43ca3b --- /dev/null +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/CSV.kt @@ -0,0 +1,19 @@ +package uk.co.neviyn.observationdatabase + +fun csvHeaderString(): String { + return "Ob ID,Observerfull,Observer,obDate,Title,Type,Department,Station,Station Focus,Scores-Monitoring,Scores-Control Procedural," + + "Scores-Control,Scores-Conservatism,Scores-Teamwork Comms,Scores-Teamwork Leadership,Scores-Teamwork Workload,\"Scores-Knowledge, Skills and Attitudes\"," + + "Strengths-Monitoring,Strengths-Control Procedural,Strengths-Control,Strengths-Conservatism,Strengths-Teamwork Comms," + + "Strengths-Teamwork Leadership,Strengths-Teamwork Workload,\"Strengths-Knowledge, Skills and Attitudes\"," + + "Develop-Monitoring,Develop-Control Procedural,Develop-Control,Develop-Conservatism,Develop-Teamwork Comms," + + "Develop-Teamwork Leadership,Develop-Teamwork Workload,\"Develop-Knowledge, Skills and Attitudes\"" +} + +fun observationsToCSV(data: List): String { + val builder = StringBuilder(csvHeaderString()) + data.forEach { + builder.append('\n') + builder.append(it.toCsvFormat()) + } + return builder.toString() +} \ No newline at end of file diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/controller/GroupSessionController.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/controller/GroupSessionController.kt index d2348e0..6f4756c 100644 --- a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/controller/GroupSessionController.kt +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/controller/GroupSessionController.kt @@ -1,5 +1,7 @@ package uk.co.neviyn.observationdatabase.controller +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.joda.time.LocalDate import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -16,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController import org.springframework.web.server.ResponseStatusException +import uk.co.neviyn.observationdatabase.Email import uk.co.neviyn.observationdatabase.GroupObservation import uk.co.neviyn.observationdatabase.GroupObservationInit import uk.co.neviyn.observationdatabase.GroupSessionManager @@ -48,6 +51,8 @@ class GroupSessionController { lateinit var personRepository: PersonRepository @Autowired lateinit var websocketMessenger: SimpMessagingTemplate + @Autowired + lateinit var mailer: Email /** * Start a new Group Observation session @@ -124,8 +129,8 @@ class GroupSessionController { * Get the current observation data for a user with [name] in the current session. */ @GetMapping("/participant/{name}") - fun getParticipantData(@PathVariable name: String): GroupObservation{ - if(GroupSessionManager.participantExistsInSession(name)) + fun getParticipantData(@PathVariable name: String): GroupObservation { + if (GroupSessionManager.participantExistsInSession(name)) return GroupSessionManager.getObservationDataForParticipant(name)!! throw ResponseStatusException(HttpStatus.NOT_FOUND, "No participant with the name:'$name'") } @@ -149,8 +154,9 @@ class GroupSessionController { if (GroupSessionManager.isValid() && GroupSessionManager.dataComplete()) { logger.info("Completing session ${GroupSessionManager.sessionId}") val tutors = tutorRepository.findAllById(GroupSessionManager.tutors!!).toSet() + val observations = mutableListOf() GroupSessionManager.observations.values.forEach { x -> - saveObservation(Observation( + val observation = Observation( site = GroupSessionManager.site!!, date = LocalDate.now(), type = GroupSessionManager.trainingType!!, @@ -167,9 +173,17 @@ class GroupSessionController { tutors = tutors, person = personRepository.findFirstByNameLike(x.person.toUpperCase()) ?: personRepository.save(Person(name = x.person.toUpperCase())) - )) + ) + saveObservation(observation) + observations.add(observation) } GroupSessionManager.invalidate() + GlobalScope.launch { + if (::mailer.isInitialized) + mailer.sendObservationData(observations) + else + logger.error("Mailer has not been initialized.") + } websocketMessenger.convertAndSend("/ws/status", mapOf("status" to "complete")) return mapOf("success" to "The submission was successfully completed.") } else if (!GroupSessionManager.dataComplete()) { @@ -194,7 +208,7 @@ class GroupSessionController { Thread.sleep(1_000) // Sleep for 1 second } if (ipv4 != null && this::environment.isInitialized) - return mapOf("ip" to ipv4, "port" to environment["local.server.port"]) + return mapOf("ip" to ipv4, "port" to environment["local.server.port"]!!) else if (ipv4 == null) { logger.error("IP Address could not be determined") return mapOf("error" to "Could not determine IP Address") diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/controller/ObservationsController.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/controller/ObservationsController.kt index 82a097f..3ccdb41 100644 --- a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/controller/ObservationsController.kt +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/controller/ObservationsController.kt @@ -32,6 +32,7 @@ import uk.co.neviyn.observationdatabase.Site import uk.co.neviyn.observationdatabase.SiteRepository import uk.co.neviyn.observationdatabase.Tutor import uk.co.neviyn.observationdatabase.TutorRepository +import uk.co.neviyn.observationdatabase.observationsToCSV import javax.validation.Valid @RestController @@ -229,24 +230,10 @@ class ObservationsController { */ @PostMapping("/observations/csv") fun getObservationsCsvDump(@Valid @RequestBody observationsRequest: ObservationsRequest): String? { - fun csvHeaderString(): String { - return "Ob ID,Observerfull,Observer,obDate,Title,Type,Department,Station,Station Focus,Scores-Monitoring,Scores-Control Procedural," + - "Scores-Control,Scores-Conservatism,Scores-Teamwork Comms,Scores-Teamwork Leadership,Scores-Teamwork Workload,\"Scores-Knowledge, Skills and Attitudes\"," + - "Strengths-Monitoring,Strengths-Control Procedural,Strengths-Control,Strengths-Conservatism,Strengths-Teamwork Comms," + - "Strengths-Teamwork Leadership,Strengths-Teamwork Workload,\"Strengths-Knowledge, Skills and Attitudes\"," + - "Develop-Monitoring,Develop-Control Procedural,Develop-Control,Develop-Conservatism,Develop-Teamwork Comms," + - "Develop-Teamwork Leadership,Develop-Teamwork Workload,\"Develop-Knowledge, Skills and Attitudes\"" - } val data = getObservations(observationsRequest) if (data.isEmpty()) return null logger.debug("Building CSV") - val builder = StringBuilder(csvHeaderString()) - data.forEach { - builder.append('\n') - builder.append(it.toCsvFormat()) - } - logger.debug("Returning constructed CSV") - return builder.toString() + return observationsToCSV(data) } val afiPieThreshold = 3