package finki.diplomska.tripplanner.service.impl; import finki.diplomska.tripplanner.models.Location; import finki.diplomska.tripplanner.models.Planner; import finki.diplomska.tripplanner.models.dto.PlannerLocationDto; import finki.diplomska.tripplanner.models.exceptions.LocationNotFoundException; import finki.diplomska.tripplanner.repository.jpa.JpaLocationRepository; import finki.diplomska.tripplanner.repository.jpa.JpaPlannerRepository; import finki.diplomska.tripplanner.service.LocationService; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; @Service public class LocationServiceImpl implements LocationService { private final JpaLocationRepository locationRepository; private final JpaPlannerRepository plannerRepository; public LocationServiceImpl(JpaLocationRepository locationRepository, JpaPlannerRepository plannerRepository) { this.locationRepository = locationRepository; this.plannerRepository = plannerRepository; } @Override public List findLocationsFromCity(String locName, String companion, List categories) { return this.locationRepository.findLocationsFromCity(locName, companion, categories); } @Override public List findLocationsFromCountry(String locName, String companion, String region, List categories) { return this.locationRepository.findLocationsFromCountry(locName, companion, region, categories); } @Override public List findAll() { return this.locationRepository.findAll(); } @Override public Location getById(Long id) { Optional location = this.locationRepository.findById(id); if (!location.isPresent()) { throw new LocationNotFoundException(id); } return location.get(); } @Override public Optional findById(Long id) { return this.locationRepository.findById(id); } @Override public List findLocationsFromCityForm(Long cityId, Long companionId, Long lengthOfStay, String categoryIds) { List categories = null; if(categoryIds != null && !categoryIds.isEmpty()){ List ids = Arrays.asList(categoryIds.split(",")); categories = ids.stream().map(Long::valueOf).collect(Collectors.toList()); } Long maxMinutesPerDay = lengthOfStay *6 * 60; int minutesPerDay = 0; List citylocations = this.locationRepository.findLocationsFromCityForm(cityId, companionId, categories); List newList = new ArrayList<>(); int listSize = citylocations.size(); while(minutesPerDay < maxMinutesPerDay ){ for(Location l: citylocations) { if (minutesPerDay < maxMinutesPerDay && l.getDuration() + minutesPerDay <= maxMinutesPerDay && listSize != 0) { newList.add(l); listSize --; } minutesPerDay += l.getDuration(); if (minutesPerDay > maxMinutesPerDay) { break; } } } List foundLocations = locationRepository.findLocationsFromCityForm(cityId, companionId, categories); return newList; } @Override public List findLocationsFromRegionForm(Long regionId, Long companionId, Long lengthOfStay, String categoryIds) { List categories = null; if(categoryIds != null && !categoryIds.isEmpty()){ List ids = Arrays.asList(categoryIds.split(",")); categories = ids.stream().map(Long::valueOf).collect(Collectors.toList()); } Long maxMinutesPerDay = lengthOfStay *6 * 60; int minutesPerDay = 0; List countryLocations = this.locationRepository.findLocationsFromRegionForm(regionId, companionId, categories); List newList = new ArrayList<>(); int listCountrySize = countryLocations.size(); while(minutesPerDay < maxMinutesPerDay){ for(Location l: countryLocations) { if (minutesPerDay < maxMinutesPerDay && l.getDuration() + minutesPerDay <= maxMinutesPerDay && listCountrySize != 0) { newList.add(l); listCountrySize --; } minutesPerDay += l.getDuration(); if (minutesPerDay > maxMinutesPerDay) { break; } } } return newList; } @Override public List scheduleLocations(String locName, String companion, String region, List categories, int numberOfDays) { int maxMinutesPerDay = numberOfDays *6 * 60; int minutesPerDay = 0; List locations = this.locationRepository.findLocationsFromCity(locName, companion, categories); List countryLocations = this.locationRepository.findLocationsFromCountry(locName, companion, region, categories); List newList = new ArrayList<>(); int listSize = locations.size(); int listCountrySize = countryLocations.size(); if(locName.equals("Macedonia")){ while(minutesPerDay < maxMinutesPerDay){ for(Location l: countryLocations) { if (minutesPerDay < maxMinutesPerDay && l.getDuration() + minutesPerDay <= maxMinutesPerDay && listCountrySize != 0) { newList.add(l); listCountrySize --; } minutesPerDay += l.getDuration(); if (minutesPerDay > maxMinutesPerDay) { break; } } } }else{ while(minutesPerDay < maxMinutesPerDay ){ for(Location l: locations) { if (minutesPerDay < maxMinutesPerDay && l.getDuration() + minutesPerDay <= maxMinutesPerDay && listSize != 0) { newList.add(l); listSize --; } minutesPerDay += l.getDuration(); if (minutesPerDay > maxMinutesPerDay) { break; } } } } return newList; } @Override public Location addLocationToPlanner(PlannerLocationDto plannerLocationDto) { Location location = this.locationRepository.findById(plannerLocationDto.getLocationId()) .orElseThrow(() -> new LocationNotFoundException(plannerLocationDto.getLocationId())); Planner planner = this.plannerRepository.getById(plannerLocationDto.getPlannerId()); planner.getLocationList().add(location); return this.locationRepository.save(location); } @Override public List getAllLocationsForPlanner(Long plannerId) { return this.locationRepository.getAllLocationsForPlanner(plannerId); } @Override public List getWeekendGetaways() { return this.locationRepository.getWeekendGetaways(); } @Override public List getVillages() { return this.locationRepository.getVillages(); } }