FavoritePetService.java
package org.petify.shelter.service;
import org.petify.shelter.client.AchievementClient;
import org.petify.shelter.dto.PetResponseWithImages;
import org.petify.shelter.enums.MatchType;
import org.petify.shelter.exception.PetIsArchivedException;
import org.petify.shelter.exception.PetNotFoundException;
import org.petify.shelter.exception.ShelterIsNotActiveException;
import org.petify.shelter.mapper.PetMapper;
import org.petify.shelter.model.FavoritePet;
import org.petify.shelter.model.Pet;
import org.petify.shelter.repository.FavoritePetRepository;
import org.petify.shelter.repository.PetRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Slf4j
@RequiredArgsConstructor
@Service
public class FavoritePetService {
private final FavoritePetRepository favoritePetRepository;
private final PetRepository petRepository;
private final PetMapper petMapper;
private final AchievementClient achievementClient;
private void upsertFavoritePet(String username, Long petId, MatchType status) {
Pet pet = petRepository.findById(petId)
.orElseThrow(() -> new PetNotFoundException(petId));
if (pet.isArchived()) {
throw new PetIsArchivedException(petId);
} else if (!pet.getShelter().getIsActive()) {
throw new ShelterIsNotActiveException();
}
FavoritePet favoritePet = favoritePetRepository.findByUsernameAndPetId(username, petId)
.orElseGet(() -> {
FavoritePet newFavorite = new FavoritePet();
newFavorite.setUsername(username);
newFavorite.setPet(pet);
return newFavorite;
});
favoritePet.setStatus(status);
favoritePetRepository.save(favoritePet);
}
@Transactional
public void like(String username, Long petId) {
upsertFavoritePet(username, petId, MatchType.LIKE);
try {
achievementClient.trackLikeProgressForUser(username);
log.info("Successfully tracked like progress for user: {}", username);
} catch (Exception e) {
log.error("Failed to track achievement progress for like action by user: {}", username, e);
}
}
@Transactional
public void dislike(String username, Long petId) {
upsertFavoritePet(username, petId, MatchType.DISLIKE);
}
@Transactional
public void support(String username, Long petId) {
upsertFavoritePet(username, petId, MatchType.SUPPORT);
try {
achievementClient.trackSupportProgressForUser(username);
log.info("Successfully tracked support progress for user: {}", username);
} catch (Exception e) {
log.error("Failed to track achievement progress for support action by user: {}", username, e);
}
}
@Transactional(readOnly = true)
public List<PetResponseWithImages> getFavoritePets(String username) {
return favoritePetRepository.findByUsernameAndStatus(username, MatchType.LIKE)
.orElse(List.of())
.stream()
.map(FavoritePet::getPet)
.filter(pet -> !pet.isArchived())
.filter(pet -> pet.getShelter().getIsActive())
.map(petMapper::toDtoWithImages)
.toList();
}
@Transactional(readOnly = true)
public List<PetResponseWithImages> getSupportedPets(String username) {
return favoritePetRepository.findByUsernameAndStatus(username, MatchType.SUPPORT)
.orElse(List.of())
.stream()
.map(FavoritePet::getPet)
.filter(pet -> !pet.isArchived())
.filter(pet -> pet.getShelter().getIsActive())
.map(petMapper::toDtoWithImages)
.toList();
}
}