diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Entity.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Entity.kt index 60ece5e..fdca95c 100644 --- a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Entity.kt +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Entity.kt @@ -16,7 +16,6 @@ import javax.persistence.JoinTable import javax.persistence.ManyToMany import javax.persistence.ManyToOne import javax.persistence.OneToMany -import javax.persistence.OneToOne import javax.persistence.Table import kotlin.math.roundToInt @@ -98,22 +97,22 @@ data class Observation( "${roundScore(monitoring)},${roundScore(controlProcedural)},${roundScore(control)}," + "${roundScore(conservatism)},${roundScore(teamworkCommunications)},${roundScore(teamworkLeadership)}," + "${roundScore(teamworkWorkload)},${roundScore(knowledge)}," + - "\"${scenarios.map { it.monitoring.strengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.controlProcedural.strengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.control.strengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.conservatism.strengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.teamworkCommunications.strengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.teamworkLeadership.strengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.teamworkWorkload.strengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.knowledge.strengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.monitoring.improvements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.controlProcedural.improvements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.control.improvements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.conservatism.improvements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.teamworkCommunications.improvements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.teamworkLeadership.improvements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.teamworkWorkload.improvements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + - "\"${scenarios.map { it.knowledge.improvements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.monitoringStrengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.controlProceduralStrengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.controlStrengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.conservatismStrengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.teamworkCommunicationsStrengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.teamworkLeadershipStrengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.teamworkWorkloadStrengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.knowledgeStrengths }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.monitoringImprovements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.controlProceduralImprovements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.controlImprovements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.conservatismImprovements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.teamworkCommunicationsImprovements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.teamworkLeadershipImprovements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.teamworkWorkloadImprovements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + + "\"${scenarios.map { it.knowledgeImprovements }.filter { it.isNotEmpty() }.joinToString(separator = "; ")}\"," + ";#None;#," return tutors.joinToString("\n") { it.name + "," + dataPortion } } @@ -126,53 +125,50 @@ data class Observation( } } -@Entity -data class RatingComponent( - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = 0, - val rating: Int, - val strengths: String = "", - val improvements: String = "" -) { - fun ratingValid(): Boolean { - return rating in 1..5 - } -} - @Entity data class Scenario( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long = 0, val title: String, - @OneToOne(cascade = [CascadeType.ALL]) - val monitoring: RatingComponent, - @OneToOne(cascade = [CascadeType.ALL]) - val controlProcedural: RatingComponent, - @OneToOne(cascade = [CascadeType.ALL]) - val control: RatingComponent, - @OneToOne(cascade = [CascadeType.ALL]) - val conservatism: RatingComponent, - @OneToOne(cascade = [CascadeType.ALL]) - val teamworkCommunications: RatingComponent, - @OneToOne(cascade = [CascadeType.ALL]) - val teamworkLeadership: RatingComponent, - @OneToOne(cascade = [CascadeType.ALL]) - val teamworkWorkload: RatingComponent, - @OneToOne(cascade = [CascadeType.ALL]) - val knowledge: RatingComponent + val monitoringRating: Int, + val monitoringStrengths: String = "", + val monitoringImprovements: String = "", + val controlProceduralRating: Int, + val controlProceduralStrengths: String = "", + val controlProceduralImprovements: String = "", + val controlRating: Int, + val controlStrengths: String = "", + val controlImprovements: String = "", + val conservatismRating: Int, + val conservatismStrengths: String = "", + val conservatismImprovements: String = "", + val teamworkCommunicationsRating: Int, + val teamworkCommunicationsStrengths: String = "", + val teamworkCommunicationsImprovements: String = "", + val teamworkLeadershipRating: Int, + val teamworkLeadershipStrengths: String = "", + val teamworkLeadershipImprovements: String = "", + val teamworkWorkloadRating: Int, + val teamworkWorkloadStrengths: String = "", + val teamworkWorkloadImprovements: String = "", + val knowledgeRating: Int, + val knowledgeStrengths: String = "", + val knowledgeImprovements: String = "" ) { + private fun ratingValid(rating: Int): Boolean { + return rating in 1..5 + } fun ratingsAllValid(): Boolean { - return monitoring.ratingValid() && - controlProcedural.ratingValid() && - control.ratingValid() && - conservatism.ratingValid() && - teamworkCommunications.ratingValid() && - teamworkLeadership.ratingValid() && - teamworkWorkload.ratingValid() && - knowledge.ratingValid() + return ratingValid(monitoringRating) && + ratingValid(controlProceduralRating) && + ratingValid(controlRating) && + ratingValid(conservatismRating) && + ratingValid(teamworkCommunicationsRating) && + ratingValid(teamworkLeadershipRating) && + ratingValid(teamworkWorkloadRating) && + ratingValid(knowledgeRating) } } @@ -183,4 +179,4 @@ data class Person( val id: Long = 0, @JsonProperty val name: String -) \ 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 83e4e25..b3197e4 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 @@ -161,14 +161,14 @@ class GroupSessionController { date = LocalDate.now(), type = GroupSessionManager.trainingType!!, observed = x.scenarios.joinToString { it.title }, - monitoring = x.scenarios.map { it.monitoring.rating }.average(), - conservatism = x.scenarios.map { it.conservatism.rating }.average(), - controlProcedural = x.scenarios.map { it.controlProcedural.rating }.average(), - control = x.scenarios.map { it.control.rating }.average(), - teamworkCommunications = x.scenarios.map { it.teamworkCommunications.rating }.average(), - teamworkLeadership = x.scenarios.map { it.teamworkLeadership.rating }.average(), - teamworkWorkload = x.scenarios.map { it.teamworkWorkload.rating }.average(), - knowledge = x.scenarios.map { it.knowledge.rating }.average(), + monitoring = x.scenarios.map { it.monitoringRating }.average(), + conservatism = x.scenarios.map { it.conservatismRating }.average(), + controlProcedural = x.scenarios.map { it.controlProceduralRating }.average(), + control = x.scenarios.map { it.controlRating }.average(), + teamworkCommunications = x.scenarios.map { it.teamworkCommunicationsRating }.average(), + teamworkLeadership = x.scenarios.map { it.teamworkLeadershipRating }.average(), + teamworkWorkload = x.scenarios.map { it.teamworkWorkloadRating }.average(), + knowledge = x.scenarios.map { it.knowledgeRating }.average(), scenarios = x.scenarios, tutors = tutors, person = personRepository.findFirstByNameLike(x.person.toUpperCase()) 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 0c668d0..3a8704f 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 @@ -141,14 +141,14 @@ class ObservationsController { date = LocalDate.now(), type = newObservation.type, observed = newObservation.scenarios.joinToString { it.title }, - monitoring = newObservation.scenarios.map { it.monitoring.rating }.average(), - conservatism = newObservation.scenarios.map { it.conservatism.rating }.average(), - controlProcedural = newObservation.scenarios.map { it.controlProcedural.rating }.average(), - control = newObservation.scenarios.map { it.control.rating }.average(), - teamworkCommunications = newObservation.scenarios.map { it.teamworkCommunications.rating }.average(), - teamworkLeadership = newObservation.scenarios.map { it.teamworkLeadership.rating }.average(), - teamworkWorkload = newObservation.scenarios.map { it.teamworkWorkload.rating }.average(), - knowledge = newObservation.scenarios.map { it.knowledge.rating }.average(), + monitoring = newObservation.scenarios.map { it.monitoringRating }.average(), + conservatism = newObservation.scenarios.map { it.conservatismRating }.average(), + controlProcedural = newObservation.scenarios.map { it.controlProceduralRating }.average(), + control = newObservation.scenarios.map { it.controlRating }.average(), + teamworkCommunications = newObservation.scenarios.map { it.teamworkCommunicationsRating }.average(), + teamworkLeadership = newObservation.scenarios.map { it.teamworkLeadershipRating }.average(), + teamworkWorkload = newObservation.scenarios.map { it.teamworkWorkloadRating }.average(), + knowledge = newObservation.scenarios.map { it.knowledgeRating }.average(), scenarios = newObservation.scenarios, tutors = tutors, person = personRepository.findFirstByNameLike(newObservation.person.toUpperCase()) ?: personRepository.save(Person(name = newObservation.person.toUpperCase())) @@ -255,21 +255,21 @@ class ObservationsController { logger.debug("Calculating AFI Data for ${data.size} entries") for (x in data) { for (y in x.scenarios) { - if (y.monitoring.rating <= afiPieThreshold) + if (y.monitoringRating <= afiPieThreshold) monitoring++ - if (y.knowledge.rating <= afiPieThreshold) + if (y.knowledgeRating <= afiPieThreshold) knowledge++ - if (y.control.rating <= afiPieThreshold) + if (y.controlRating <= afiPieThreshold) control++ - if (y.controlProcedural.rating <= afiPieThreshold) + if (y.controlProceduralRating <= afiPieThreshold) control++ - if (y.conservatism.rating <= afiPieThreshold) + if (y.conservatismRating <= afiPieThreshold) conservatism++ - if (y.teamworkCommunications.rating <= afiPieThreshold) + if (y.teamworkCommunicationsRating <= afiPieThreshold) teamwork++ - if (y.teamworkLeadership.rating <= afiPieThreshold) + if (y.teamworkLeadershipRating <= afiPieThreshold) teamwork++ - if (y.teamworkWorkload.rating <= afiPieThreshold) + if (y.teamworkWorkloadRating <= afiPieThreshold) teamwork++ } } diff --git a/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/controller/GroupSessionControllerTest.kt b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/controller/GroupSessionControllerTest.kt index feeea64..31b1931 100644 --- a/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/controller/GroupSessionControllerTest.kt +++ b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/controller/GroupSessionControllerTest.kt @@ -24,7 +24,6 @@ import uk.co.neviyn.observationdatabase.Observation import uk.co.neviyn.observationdatabase.ObservationRepository import uk.co.neviyn.observationdatabase.Person import uk.co.neviyn.observationdatabase.PersonRepository -import uk.co.neviyn.observationdatabase.RatingComponent import uk.co.neviyn.observationdatabase.Scenario import uk.co.neviyn.observationdatabase.Site import uk.co.neviyn.observationdatabase.SiteRepository @@ -100,8 +99,7 @@ class GroupSessionControllerTest { Mockito.doReturn(listOf(tutor)).`when`(tutorRepository).findAllById(listOf(1)) val person = Person(1, "A Student") Mockito.doReturn(person).`when`(personRepository).save(any()) - val rc = RatingComponent(rating = 5) - val scenario = Scenario(0, "Sample title", rc, rc, rc, rc, rc, rc, rc, rc) + val scenario = Scenario(0, "Sample title", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "") Mockito.doReturn(Observation(1, site, LocalDate.now(), TrainingType.INITIAL, "Sample title", 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, listOf(scenario), setOf(tutor), person)).`when`(observationRepository).save(any()) controller.startGroupObservation(GroupObservationInit(1, TrainingType.INITIAL, listOf(1), listOf("Sample title"))) controller.addGroupObservation(GroupObservation("A Student", listOf(scenario))) @@ -126,9 +124,8 @@ class GroupSessionControllerTest { Mockito.doReturn(Optional.of(site)).`when`(siteRepository).findById(1) Mockito.doReturn(listOf(Tutor(1, "Mr X", site))).`when`(tutorRepository).findAllById(listOf(1)) controller.startGroupObservation(GroupObservationInit(1, TrainingType.INITIAL, listOf(1), listOf("Sample title"))) - val rc = RatingComponent(rating = 5) - controller.addGroupObservation(GroupObservation("A Student", listOf(Scenario(0, "Sample title", RatingComponent(rating = 0), rc, rc, rc, rc, rc, rc, rc)))) - verify(websocketMessenger, times(1)).convertAndSend("/ws/scenarios", mapOf("scenarios" to mapOf("Sample title" to listOf(Scenario(0, "A Student", RatingComponent(rating = 0), rc, rc, rc, rc, rc, rc, rc))))) + controller.addGroupObservation(GroupObservation("A Student", listOf(Scenario(0, "Sample title", 0, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "")))) + verify(websocketMessenger, times(1)).convertAndSend("/ws/scenarios", mapOf("scenarios" to mapOf("Sample title" to listOf(Scenario(0, "A Student", 0, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", ""))))) controller.pushObservationsToDatabase() } @@ -138,8 +135,7 @@ class GroupSessionControllerTest { Mockito.doReturn(Optional.of(site)).`when`(siteRepository).findById(1) Mockito.doReturn(listOf(Tutor(1, "Mr X", site))).`when`(tutorRepository).findAllById(listOf(1)) controller.startGroupObservation(GroupObservationInit(1, TrainingType.INITIAL, listOf(1), listOf("Sample title"))) - val rc = RatingComponent(rating = 5) - controller.addGroupObservation(GroupObservation("A Student", listOf(Scenario(0, "Different Title", rc, rc, rc, rc, rc, rc, rc, rc)))) + controller.addGroupObservation(GroupObservation("A Student", listOf(Scenario(0, "Different Title", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "")))) } @Test @@ -148,8 +144,7 @@ class GroupSessionControllerTest { Mockito.doReturn(Optional.of(site)).`when`(siteRepository).findById(1) Mockito.doReturn(listOf(Tutor(1, "Mr X", site))).`when`(tutorRepository).findAllById(listOf(1)) controller.startGroupObservation(GroupObservationInit(1, TrainingType.INITIAL, listOf(1), listOf("Sample title"))) - val rc = RatingComponent(rating = 5) - controller.addGroupObservation(GroupObservation("A Student", listOf(Scenario(0, "Sample title", RatingComponent(rating = 0), rc, rc, rc, rc, rc, rc, rc)))) + controller.addGroupObservation(GroupObservation("A Student", listOf(Scenario(0, "Sample title", 0, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "")))) assertEquals(1, GroupSessionManager.observations.size) assertEquals("A Student", GroupSessionManager.observations.keys.first()) assertEquals("A Student", GroupSessionManager.observations.values.first().person) @@ -162,16 +157,14 @@ class GroupSessionControllerTest { @Test(expected = ResponseStatusException::class) fun testGetParticipantData_WrongName() { - val rc = RatingComponent(rating = 5) - val testData = GroupObservation("A Student", listOf(Scenario(0, "Sample title", rc, rc, rc, rc, rc, rc, rc, rc))) + val testData = GroupObservation("A Student", listOf(Scenario(0, "Sample title", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", ""))) GroupSessionManager.observations["A Student"] = testData controller.getParticipantData("Another Student") } @Test fun testGetParticipantData() { - val rc = RatingComponent(rating = 5) - val testData = GroupObservation("A Student", listOf(Scenario(0, "Sample title", rc, rc, rc, rc, rc, rc, rc, rc))) + val testData = GroupObservation("A Student", listOf(Scenario(0, "Sample title", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", ""))) GroupSessionManager.observations["A Student"] = testData val output = controller.getParticipantData("A Student") assertEquals(testData, output) diff --git a/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/controller/ObservationsControllerTest.kt b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/controller/ObservationsControllerTest.kt index 037e263..aa9fec9 100644 --- a/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/controller/ObservationsControllerTest.kt +++ b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/controller/ObservationsControllerTest.kt @@ -25,7 +25,6 @@ import uk.co.neviyn.observationdatabase.ObservationRepository import uk.co.neviyn.observationdatabase.ObservationsRequest import uk.co.neviyn.observationdatabase.Person import uk.co.neviyn.observationdatabase.PersonRepository -import uk.co.neviyn.observationdatabase.RatingComponent import uk.co.neviyn.observationdatabase.Scenario import uk.co.neviyn.observationdatabase.Site import uk.co.neviyn.observationdatabase.SiteRepository @@ -124,8 +123,7 @@ class ObservationsControllerTest { doReturn(Optional.of(site)).`when`(siteRepository).findById(1) doReturn(listOf(tutor)).`when`(tutorRepository).findAllById(listOf(1)) doReturn(person).`when`(personRepository).findFirstByNameLike("MR X") - val defaultComponent = RatingComponent(rating = 5, strengths = "", improvements = "") - val newData = NewObservation(1, TrainingType.INITIAL, "An Observation", listOf(Scenario(title = "Something", monitoring = defaultComponent, controlProcedural = defaultComponent, control = defaultComponent, conservatism = defaultComponent, teamworkCommunications = defaultComponent, teamworkLeadership = defaultComponent, teamworkWorkload = defaultComponent, knowledge = defaultComponent)), listOf(1), "Mr X") + val newData = NewObservation(1, TrainingType.INITIAL, "An Observation", listOf(Scenario(1, "Something", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "", 5, "", "")), listOf(1), "Mr X") val observation = Observation(1, site, LocalDate.now(), TrainingType.INITIAL, "An Observation", 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, newData.scenarios, setOf(tutor), person) doReturn(observation).`when`(observationRepository).save(ArgumentMatchers.any()) val result = controller.addObservation(newData) diff --git a/frontend/src/components/ObservationEntry.vue b/frontend/src/components/ObservationEntry.vue index 2009b0b..094a504 100644 --- a/frontend/src/components/ObservationEntry.vue +++ b/frontend/src/components/ObservationEntry.vue @@ -3,22 +3,22 @@

{{ description }}

-

- {{ scenariofundamental.rating }} +

+ {{ rating }}

export default { - props: ["scenariofundamental", "description"] + props: ["rating", "strengths", "improvements", "description"] }; diff --git a/frontend/src/views/GroupSessionInput.vue b/frontend/src/views/GroupSessionInput.vue index edf1189..be0a676 100644 --- a/frontend/src/views/GroupSessionInput.vue +++ b/frontend/src/views/GroupSessionInput.vue @@ -60,9 +60,9 @@
Monitoring
@@ -71,7 +71,7 @@
Control Procedural
@@ -105,7 +105,7 @@
Control
@@ -139,7 +139,7 @@
Conservatism
@@ -173,7 +173,7 @@
Teamwork Communications
@@ -207,7 +207,7 @@
Teamwork Leadership
@@ -241,7 +241,7 @@
Teamwork Workload
@@ -275,7 +275,7 @@
Knowledge
@@ -309,7 +309,7 @@
Monitoring
Control Procedural
Control
Conservatism
Teamwork Communications
Teamwork Leadership
Teamwork Workload
Knowledge