using ApplicationLayer.InfrastructureServicesInterfaces; using ApplicationLayer.Services.Applicants.NeededServices; using ApplicationLayer.Services.Locations.NeededServices; using ApplicationLayer.Services.Locations.RequestHandlers.Exceptions; using ApplicationLayer.Services.Locations.Requests; using Domains.LocationDomain; namespace ApplicationLayer.Services.Locations.RequestHandlers { /// public class LocationRequestsHandler( ICountriesRepository countries, ICitiesRepository cities, IApplicantsRepository applicants, IUnitOfWork unitOfWork) : ILocationRequestsHandler { async Task> ILocationRequestsHandler.HandleGetRequestAsync(CancellationToken cancellationToken) { return await countries.GetAllAsync(cancellationToken); } async Task ILocationRequestsHandler.AddCountryAsync(AddCountryRequest request, CancellationToken cancellationToken) { if (await countries.FindByNameAsync(request.CountryName, cancellationToken) is not null) { throw new CountryAlreadyExists(request.CountryName); } if (request.Cities.Distinct().Count() < request.Cities.Length) { throw new MultipleIdenticalCitiesInCountryException(); } //todo mapper var country = new Country { Name = request.CountryName, IsSchengen = request.IsSchengen, Cities = request.Cities.Select(cityName => new City { Name = cityName }).ToList() }; await countries.AddAsync(country, cancellationToken); await unitOfWork.SaveAsync(cancellationToken); } async Task ILocationRequestsHandler.UpdateCountryAsync(UpdateCountryRequest request, CancellationToken cancellationToken) { if (await countries.FindByNameAsync(request.CountryName, cancellationToken) is not null) { throw new CountryAlreadyExists(request.CountryName); } var country = await countries.FindByIdAsync(request.Id, cancellationToken); if (country is null) { throw new CountryNotFoundException(request.CountryName); } var existingCities = country.Cities; var citiesToAdd = request.Cities.Except(existingCities.Select(c => c.Name)).ToList(); var citiesToRemove = existingCities.Where(c => !request.Cities.Contains(c.Name)); var applicantsList = await applicants.GetAllAsync(cancellationToken); //todo mapper foreach (var city in citiesToRemove) { if (applicantsList.All(a => a.CityOfBirth.Id != city.Id && a.PlaceOfWork.Address.City.Id != city.Id)) { cities.Remove(city); } else { throw new CityCanNotBeDeletedException(city.Name); } } foreach (var city in citiesToAdd) { await cities.AddAsync(new City { Name = city, Country = country }, cancellationToken); } country.Name = request.CountryName; country.IsSchengen = request.IsSchengen; await countries.UpdateAsync(country, cancellationToken); await unitOfWork.SaveAsync(cancellationToken); } } }