diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Controller.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Controller.kt index c388fdc..cd9e4e6 100644 --- a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Controller.kt +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Controller.kt @@ -21,6 +21,8 @@ class Controller { lateinit var tutorRepository: TutorRepository @Autowired lateinit var observationRepository: ObservationRepository + @Autowired + lateinit var personRepository: PersonRepository /** * Returns a list of all current sites. @@ -100,7 +102,9 @@ class Controller { knowledge = overallScores[RatingCategory.KNOWLEDGE], entries = newObservation.entries, tutors = tutors, - persons = newObservation.persons.asSequence().map { Person(it.toUpperCase()) }.toSet() + persons = newObservation.persons.asSequence().map { + personRepository.findByName(it.toUpperCase()) ?: personRepository.save(Person(name = it.toUpperCase())) + }.toSet() ) observation = observationRepository.save(observation) tutors.forEach { 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 5fe2370..a18fb62 100644 --- a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Entity.kt +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Entity.kt @@ -93,7 +93,7 @@ data class Observation( @JsonIgnore @ManyToMany(mappedBy = "observations") val tutors: Set, - @ElementCollection + @ManyToMany val persons: Set ) @@ -116,8 +116,11 @@ data class Entry( val improvements: String ) -@Embeddable +@Entity data class Person( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + 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/Repository.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Repository.kt index d5c9489..66b3255 100644 --- a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Repository.kt +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Repository.kt @@ -1,7 +1,6 @@ package uk.co.neviyn.observationdatabase import org.joda.time.LocalDate -import org.springframework.data.jpa.repository.JpaSpecificationExecutor import org.springframework.data.repository.CrudRepository import org.springframework.stereotype.Repository @@ -12,7 +11,7 @@ interface SiteRepository : CrudRepository interface TutorRepository : CrudRepository @Repository -interface ObservationRepository : CrudRepository, JpaSpecificationExecutor { +interface ObservationRepository : CrudRepository { fun findBySiteAndDateBetween(site: Site, startDate: LocalDate, endDate: LocalDate): List @@ -21,4 +20,13 @@ interface ObservationRepository : CrudRepository, JpaSpecific fun findBySiteAndWhomAndDateBetween(site: Site, whom: String, startDate: LocalDate, endDate: LocalDate): List fun findByTutorsAndWhomAndDateBetween(tutor: Tutor, whom: String, startDate: LocalDate, endDate: LocalDate): List + + fun findBySiteAndPersonsAndDateBetween(site: Site, person: Person, startDate: LocalDate, endDate: LocalDate): List +} + +@Repository +interface PersonRepository : CrudRepository { + + fun findByName(name: String): Person? + } \ No newline at end of file diff --git a/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/RepositoryTest.kt b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/RepositoryTest.kt index 62acc82..aa4b4fb 100644 --- a/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/RepositoryTest.kt +++ b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/RepositoryTest.kt @@ -19,6 +19,9 @@ class RepositoryTest { @Autowired lateinit var observationRepository: ObservationRepository + @Autowired + lateinit var personRepository: PersonRepository + @Test fun testFindBySiteAndDateBetween_EmptyRepository() { val result = observationRepository.findBySiteAndDateBetween(Site(1, "x"), LocalDate.now(), LocalDate.now()) @@ -46,25 +49,26 @@ class RepositoryTest { @Test fun testFindBySiteAndDateBetween() { val correctSite = entityManager.persist(Site(name = "Correct")) + val person = entityManager.persist(Person(name = "Foo Bar")) val incorrectSite = entityManager.persist(Site(name = "Incorrect")) val tutor = entityManager.persist(Tutor(name = "X", site = correctSite)) val tutor2 = entityManager.persist(Tutor(name = "N", site = incorrectSite)) val tooEarly = Observation(site = correctSite, date = LocalDate.now().minusDays(5), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) val tooLate = Observation(site = correctSite, date = LocalDate.now().plusDays(5), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) val wrongSite = Observation(site = incorrectSite, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor2), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor2), persons = setOf(person)) val justRight = Observation(site = correctSite, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) entityManager.persist(tooEarly) entityManager.persist(tooLate) entityManager.persist(wrongSite) @@ -78,28 +82,29 @@ class RepositoryTest { fun testFindBySiteAndWhomAndDateBetween() { val correctSite = entityManager.persist(Site(name = "Correct")) val incorrectSite = entityManager.persist(Site(name = "Incorrect")) + val person = entityManager.persist(Person(name = "Foo Bar")) val tutor = entityManager.persist(Tutor(name = "X", site = correctSite)) val tutor2 = entityManager.persist(Tutor(name = "N", site = incorrectSite)) val tooEarly = Observation(site = correctSite, date = LocalDate.now().minusDays(5), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) val tooLate = Observation(site = correctSite, date = LocalDate.now().plusDays(5), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) val wrongSite = Observation(site = incorrectSite, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor2), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor2), persons = setOf(person)) val justRight = Observation(site = correctSite, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) val wrongWhom = Observation(site = correctSite, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G2", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) entityManager.persist(tooEarly) entityManager.persist(tooLate) entityManager.persist(wrongSite) @@ -113,28 +118,29 @@ class RepositoryTest { @Test fun testFindByTutorsAndDateBetween() { val site = entityManager.persist(Site(name = "Correct")) + val person = entityManager.persist(Person(name = "Foo Bar")) val correctTutor = entityManager.persist(Tutor(name = "X", site = site)) val incorrectTutor = entityManager.persist(Tutor(name = "N", site = site)) val tooEarly = Observation(site = site, date = LocalDate.now().minusDays(5), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(person)) val tooLate = Observation(site = site, date = LocalDate.now().plusDays(5), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(person)) val wrongTutor = Observation(site = site, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(incorrectTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(incorrectTutor), persons = setOf(person)) val justRight = Observation(site = site, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(person)) val justRightMultipleTutors = Observation(site = site, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor, incorrectTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor, incorrectTutor), persons = setOf(person)) entityManager.persist(tooEarly) entityManager.persist(tooLate) entityManager.persist(wrongTutor) @@ -154,32 +160,33 @@ class RepositoryTest { @Test fun testFindByTutorsAndWhomAndDateBetween() { val site = entityManager.persist(Site(name = "Correct")) + val person = entityManager.persist(Person(name = "Foo Bar")) val correctTutor = entityManager.persist(Tutor(name = "X", site = site)) val incorrectTutor = entityManager.persist(Tutor(name = "N", site = site)) val tooEarly = Observation(site = site, date = LocalDate.now().minusDays(5), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(person)) val tooLate = Observation(site = site, date = LocalDate.now().plusDays(5), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(person)) val wrongTutor = Observation(site = site, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(incorrectTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(incorrectTutor), persons = setOf(person)) val justRight = Observation(site = site, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(person)) val wrongGroup = Observation(site = site, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G2", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor), persons = setOf(person)) val justRightMultipleTutors = Observation(site = site, date = LocalDate.now(), type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, - teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor, incorrectTutor), persons = setOf(Person("Foo Bar"))) + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(correctTutor, incorrectTutor), persons = setOf(person)) entityManager.persist(tooEarly) entityManager.persist(tooLate) entityManager.persist(wrongTutor) @@ -197,4 +204,58 @@ class RepositoryTest { assertFalse(result.contains(wrongTutor)) assertFalse(result.contains(wrongGroup)) } + + @Test + fun testFindBySiteAndPersonsAndDateBetween() { + val person = entityManager.persist(Person(name = "Foo Bar")) + val otherPerson = entityManager.persist(Person(name = "Wrong")) + val site = entityManager.persist(Site(name = "Incorrect")) + val tutor = entityManager.persist(Tutor(name = "X", site = site)) + val tooEarly = Observation(site = site, date = LocalDate.now().minusDays(5), + type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, + control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) + val tooLate = Observation(site = site, date = LocalDate.now().plusDays(5), + type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, + control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) + val wrongPerson = Observation(site = site, date = LocalDate.now(), + type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, + control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(otherPerson)) + val justRight = Observation(site = site, date = LocalDate.now(), + type = TrainingType.INITIAL, observed = "1", whom = "G1", monitoring = 5.0, controlProcedural = 3.0, + control = 4.0, conservatism = 3.0, teamworkCommunications = 2.0, teamworkLeadership = 3.0, + teamworkWorkload = 1.0, knowledge = 1.0, entries = listOf(), tutors = setOf(tutor), persons = setOf(person)) + entityManager.persist(tooEarly) + entityManager.persist(tooLate) + entityManager.persist(wrongPerson) + entityManager.persist(justRight) + val result = observationRepository.findBySiteAndPersonsAndDateBetween(site = site, person = person, startDate = LocalDate.now().minusDays(1), endDate = LocalDate.now().plusDays(1)) + assertEquals(1, result.size) + assertEquals(justRight, result.first()) + } + + @Test + fun testFindPersonByName() { + val person = entityManager.persist(Person(name = "Foo Bar")) + entityManager.persist(person) + val result = personRepository.findByName("Foo Bar") + assertEquals(person, result) + } + + @Test + fun testFindPersonByName_IncorrectName() { + val person = entityManager.persist(Person(name = "Foo Bar")) + entityManager.persist(person) + val result = personRepository.findByName("Foo") + assertNotSame(person, result) + assertNull(result) + } + + @Test + fun testFindPersonByName_NoPersons() { + val result = personRepository.findByName("Foo") + assertNull(result) + } } \ No newline at end of file