Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ val cglibVersion by extra("3.3.0")
val mockitoKotlinVersion by extra("6.3.0")

group = "com.josdem.vetlog"
version = "3.6.8"
version = "3.7.0"

configurations {
compileOnly {
Expand Down
50 changes: 35 additions & 15 deletions src/main/java/com/josdem/vetlog/helper/VaccinationHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,15 @@ public class VaccinationHelper {
private static final String C6CV_VACCINE = "C6CV";
private static final String TRICAT_VACCINE = "TRICAT";
private static final String TRICAT_BOOST_VACCINE = "TRICAT_BOOST";
private static final String FELV_VACCINE = "FeLV";

private static final Map<String, String> NEXT_VACCINE = Map.of(
PUPPY_VACCINE, C4CV_VACCINE,
C4CV_VACCINE, C6CV_VACCINE,
TRICAT_VACCINE, TRICAT_BOOST_VACCINE);

private static final Map<String, java.time.Period> NEXT_VACCINE_OFFSET = Map.of(
PUPPY_VACCINE, java.time.Period.ofDays(15),
C4CV_VACCINE, java.time.Period.ofDays(15),
TRICAT_VACCINE, java.time.Period.ofDays(21));
private static final Map<String, Map<String, java.time.Period>> NEXT_VACCINE_AND_OFFSET = Map.of(
PUPPY_VACCINE, Map.of(C4CV_VACCINE, java.time.Period.ofDays(15)),
C4CV_VACCINE, Map.of(C6CV_VACCINE, java.time.Period.ofDays(15)),
TRICAT_VACCINE,
Map.of(
TRICAT_BOOST_VACCINE, java.time.Period.ofDays(21),
FELV_VACCINE, java.time.Period.ofDays(21)));

private static final Map<String, java.time.Period> NEXT_RABIES_VACCINE_OFFSET = Map.of(
TRICAT_VACCINE, java.time.Period.ofDays(21),
Expand All @@ -78,14 +77,17 @@ && isSpecificCriteriaSatisfiedForApplyingNextVaccine(appliedName, RABIES_VACCINE
public void validateNextVaccines(List<Vaccination> previousVaccines, List<Vaccination> newVaccines, Pet pet) {
for (Vaccination newVaccine : newVaccines) {
String appliedName = newVaccine.getName();
if (NEXT_VACCINE.containsKey(appliedName)
if (NEXT_VACCINE_AND_OFFSET.containsKey(appliedName)
&& newVaccine.getStatus() == VaccinationStatus.APPLIED
&& previousVaccines.stream()
.anyMatch(previousVaccine -> appliedName.equalsIgnoreCase(previousVaccine.getName())
&& previousVaccine.getStatus() == VaccinationStatus.PENDING)) {
String nextName = NEXT_VACCINE.get(appliedName);
if (!isSpecificCriteriaSatisfiedForApplyingNextVaccine(appliedName, nextName, pet)) continue;
saveNewVaccine(nextName, LocalDate.now().plus(NEXT_VACCINE_OFFSET.get(appliedName)), pet);
Map<String, java.time.Period> nextNamesAndOffsets = NEXT_VACCINE_AND_OFFSET.get(appliedName);
for (Map.Entry<String, java.time.Period> nextNameAndOffset : nextNamesAndOffsets.entrySet()) {
if (!isSpecificCriteriaSatisfiedForApplyingNextVaccine(
appliedName, nextNameAndOffset.getKey(), pet)) continue;
saveNewVaccine(nextNameAndOffset.getKey(), LocalDate.now().plus(nextNameAndOffset.getValue()), pet);
}
}
}
}
Expand All @@ -100,17 +102,35 @@ private boolean isSpecificCriteriaSatisfiedForApplyingNextVaccine(String applied
.map(birthDate -> ChronoUnit.WEEKS.between(birthDate, LocalDate.now()))
.map(weeks -> weeks >= 9 && weeks <= 16)
.orElse(false);
}
if (TRICAT_VACCINE.equalsIgnoreCase(appliedName) && RABIES_VACCINE.equalsIgnoreCase(nextName)) {
} else if (TRICAT_VACCINE.equalsIgnoreCase(appliedName) && RABIES_VACCINE.equalsIgnoreCase(nextName)) {
return Optional.ofNullable(pet)
.map(Pet::getBirthDate)
.map(dob -> ChronoUnit.DAYS.between(dob, LocalDate.now()))
.map(days -> days > (16 * 7))
.orElse(false);
} else if (TRICAT_VACCINE.equalsIgnoreCase(appliedName)
&& FELV_VACCINE.equalsIgnoreCase(nextName)
&& petNeedsLeukemiaVaccine(pet)) {
return Optional.ofNullable(pet)
.map(Pet::getBreed)
.map(Breed::getType)
.filter(PetType.CAT::equals)
.flatMap(type -> Optional.ofNullable(pet.getGoingOutOften()))
.orElse(false);
}
return true;
}

private boolean petNeedsLeukemiaVaccine(Pet pet) {
return Optional.ofNullable(pet)
.filter(p ->
p.getBreed() != null && PetType.CAT.equals(p.getBreed().getType()))
.filter(p -> Boolean.TRUE.equals(p.getGoingOutOften()))
.map(Pet::getBirthDate)
.map(birthDate -> birthDate.isBefore(LocalDate.now().minusWeeks(16)))
.orElse(false);
}
Comment thread
khawaja-abdullah marked this conversation as resolved.
Outdated

private void saveNewVaccine(String name, LocalDate date, Pet pet) {
Vaccination future = new Vaccination(null, name, date, VaccinationStatus.NEW, pet);
vaccinationRepository.save(future);
Expand Down
92 changes: 74 additions & 18 deletions src/test/java/com/josdem/vetlog/helper/VaccinationHelperTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class VaccinationHelperTest {
}

@Test
fun `should not create TRICAT_BOOST 45 days later when TRICAT applied and pet is cat not aged 9 to 16 weeks`(testInfo: TestInfo) {
fun `should not create TRICAT_BOOST when TRICAT applied and pet is cat not aged 9 to 16 weeks`(testInfo: TestInfo) {
log.info(testInfo.displayName)
val pet = Pet()
val breed = Breed()
Expand All @@ -209,23 +209,12 @@ class VaccinationHelperTest {

vaccinationHelper.validateNextVaccines(listOf(previousVaccines), listOf(newVaccines), pet)

verify(vaccinationRepository, times(0)).save(any())
}

@Test
fun `should not create TRICAT_BOOST 45 days later when TRICAT applied and pet is not cat`(testInfo: TestInfo) {
log.info(testInfo.displayName)
val pet = Pet()
val breed = Breed()
breed.type = PetType.DOG
pet.breed = breed
val previousVaccines = Vaccination(1L, "TRICAT", LocalDate.now(), VaccinationStatus.PENDING, pet)
val newVaccines = Vaccination(1L, "TRICAT", LocalDate.now(), VaccinationStatus.APPLIED, pet)
whenever(vaccinationRepository.findAllByPetId(1L)).thenReturn(listOf(previousVaccines))

vaccinationHelper.validateNextVaccines(listOf(previousVaccines), listOf(newVaccines), pet)

verify(vaccinationRepository, times(0)).save(any())
verify(vaccinationRepository, times(0)).save(
argThat { vaccination ->
vaccination.name == "TRICAT_BOOST" &&
vaccination.status == VaccinationStatus.NEW
},
)
}

@Test
Expand Down Expand Up @@ -291,4 +280,71 @@ class VaccinationHelperTest {

verify(vaccinationRepository).save(any())
}

@Test
fun `should update TRICAT_BOOST vaccination status to APPLIED`(testInfo: TestInfo) {
log.info(testInfo.displayName)
val previousVaccines = Vaccination(3L, "TRICAT_BOOST", LocalDate.now(), VaccinationStatus.PENDING, pet)
val newVaccines = Vaccination(3L, "TRICAT_BOOST", LocalDate.now(), VaccinationStatus.APPLIED, pet)
whenever(vaccinationRepository.findAllByPetId(1L)).thenReturn(listOf(previousVaccines))
vaccinationHelper.validateRabiesVaccine(listOf(previousVaccines), listOf(newVaccines), pet)
val expectedDate = LocalDate.now().plusDays(21)
verify(vaccinationRepository).save(
argThat { vaccination ->
vaccination.name == "Rabies" &&
vaccination.status == VaccinationStatus.NEW &&
vaccination.date == expectedDate &&
vaccination.pet == pet
},
)
}

@Test
fun `should create new FeLV vaccine when TRICAT is applied`(testInfo: TestInfo) {
log.info(testInfo.displayName)
val pet = Pet()
pet.id = 1L
pet.birthDate = LocalDate.now().minusWeeks(17)
pet.goingOutOften = true
pet.breed = Breed().apply { type = PetType.CAT }
val previousVaccines = Vaccination(1L, "TRICAT", LocalDate.now(), VaccinationStatus.PENDING, pet)
val newVaccines = Vaccination(1L, "TRICAT", LocalDate.now(), VaccinationStatus.APPLIED, pet)

val expectedDate = LocalDate.now().plusDays(21)
whenever(vaccinationRepository.findAllByPetId(1L)).thenReturn(listOf(previousVaccines))

vaccinationHelper.validateNextVaccines(listOf(previousVaccines), listOf(newVaccines), pet)

verify(vaccinationRepository).save(
argThat { vaccination ->
vaccination.name == "FeLV" &&
vaccination.status == VaccinationStatus.NEW &&
vaccination.date == expectedDate &&
vaccination.pet == pet
},
)
}

@Test
fun `should not create new FELV vaccine when cat is 16 months old or younger`(testInfo: TestInfo) {
log.info(testInfo.displayName)
val pet = Pet()
pet.id = 1L
pet.birthDate = LocalDate.now().minusWeeks(16)
pet.goingOutOften = true
pet.breed = Breed().apply { type = PetType.CAT }
val previousVaccines = Vaccination(1L, "TRICAT", LocalDate.now(), VaccinationStatus.PENDING, pet)
val newVaccines = Vaccination(1L, "TRICAT", LocalDate.now(), VaccinationStatus.APPLIED, pet)
whenever(vaccinationRepository.findAllByPetId(1L)).thenReturn(listOf(previousVaccines))

vaccinationHelper.validateRabiesVaccine(listOf(previousVaccines), listOf(newVaccines), pet)
Comment thread
khawaja-abdullah marked this conversation as resolved.

verify(vaccinationRepository, never()).save(
argThat { vaccination ->
vaccination.name == "FeLV" &&
vaccination.status == VaccinationStatus.NEW &&
vaccination.pet == pet
},
)
}
}
Loading