updating countries

This commit is contained in:
2024-08-20 21:34:56 +03:00
parent 19e792e670
commit a0d002b465
14 changed files with 119 additions and 10 deletions

View File

@@ -0,0 +1,9 @@
using Domains;
namespace Infrastructure.Database.GeneralExceptions;
/// Exception to throw when entity not found
/// <param name="id">Identifier of entity</param>
/// <typeparam name="T">Type of entity</typeparam>
public class EntityNotFoundByIdException<T>(Guid id) : EntityNotFoundException<T>($"{typeof(T).Name} with id {id} not found.")
where T : class, IEntity;

View File

@@ -0,0 +1,9 @@
using ApplicationLayer.GeneralExceptions;
using Domains;
namespace Infrastructure.Database.GeneralExceptions;
/// Exception to throw when entity not found
/// <typeparam name="T">Not found entity type</typeparam>
public class EntityNotFoundException<T>(string message) : ApiException(message)
where T : class, IEntity;

View File

@@ -0,0 +1,7 @@
using ApplicationLayer.GeneralExceptions;
namespace Infrastructure.Database.GeneralExceptions
{
/// Exception to throw when can't complete some action on entity(delete or something) because it's needed for other entities
public class EntityUsedInDatabaseException(string message) : ApiException(message);
}

View File

@@ -3,4 +3,8 @@ using Domains.LocationDomain;
namespace ApplicationLayer.Services.Locations.NeededServices;
public interface ICitiesRepository : IGenericRepository<City>;
public interface ICitiesRepository : IGenericRepository<City>
{
/// Get <see cref="City"/> by name and country identifier
Task<City?> GetByNameAsync(Guid requestId, string existingCity, CancellationToken cancellationToken);
}

View File

@@ -6,8 +6,8 @@ namespace ApplicationLayer.Services.Locations.NeededServices;
public interface ICountriesRepository : IGenericRepository<Country>
{
/// Gets country by name
/// <param name="countryName">Name of country to seek</param>
/// <param name="cancellationToken">Cancellation Token</param>
/// <returns>Country or null if not found</returns>
Task<Country?> FindByName(string countryName, CancellationToken cancellationToken);
Task<Country?> FindByNameAsync(string countryName, CancellationToken cancellationToken);
/// Gets country by identifier
Task<Country?> FindByIdAsync(Guid id, CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,7 @@
using Infrastructure.Database.GeneralExceptions;
namespace ApplicationLayer.Services.Locations.RequestHandlers.Exceptions
{
public class CityCanNotBeDeletedException(string cityName)
: EntityUsedInDatabaseException($"{cityName} can not be deleted because some applicants live or work in it");
}

View File

@@ -0,0 +1,7 @@
using Domains.LocationDomain;
using Infrastructure.Database.GeneralExceptions;
namespace ApplicationLayer.Services.Locations.RequestHandlers.Exceptions
{
public class CountryNotFoundException(string countryName) : EntityNotFoundException<Country>($"Country {countryName} is not supported.");
}

View File

@@ -10,7 +10,10 @@ namespace ApplicationLayer.Services.Locations.RequestHandlers
/// <returns>List of available countries</returns>
Task<List<Country>> HandleGetRequestAsync(CancellationToken cancellationToken);
/// Handles add country requests
/// Handles <see cref="AddCountryRequest"/>
Task AddCountryAsync(AddCountryRequest request, CancellationToken cancellationToken);
/// Handles <see cref="UpdateCountryRequest"/>
Task UpdateCountryAsync(UpdateCountryRequest request, CancellationToken cancellationToken);
}
}

View File

@@ -1,4 +1,5 @@
using ApplicationLayer.InfrastructureServicesInterfaces;
using ApplicationLayer.Services.Applicants.NeededServices;
using ApplicationLayer.Services.Locations.NeededServices;
using ApplicationLayer.Services.Locations.RequestHandlers.Exceptions;
using ApplicationLayer.Services.Locations.Requests;
@@ -7,7 +8,11 @@ using Domains.LocationDomain;
namespace ApplicationLayer.Services.Locations.RequestHandlers
{
/// <inheritdoc cref="ILocationRequestsHandler"/>
public class LocationRequestsHandler(ICountriesRepository countries, IUnitOfWork unitOfWork) : ILocationRequestsHandler
public class LocationRequestsHandler(
ICountriesRepository countries,
ICitiesRepository cities,
IApplicantsRepository applicants,
IUnitOfWork unitOfWork) : ILocationRequestsHandler
{
async Task<List<Country>> ILocationRequestsHandler.HandleGetRequestAsync(CancellationToken cancellationToken)
{
@@ -16,7 +21,7 @@ namespace ApplicationLayer.Services.Locations.RequestHandlers
async Task ILocationRequestsHandler.AddCountryAsync(AddCountryRequest request, CancellationToken cancellationToken)
{
if (await countries.FindByName(request.CountryName, cancellationToken) is not null)
if (await countries.FindByNameAsync(request.CountryName, cancellationToken) is not null)
{
throw new CountryAlreadyExists(request.CountryName);
}
@@ -38,5 +43,49 @@ namespace ApplicationLayer.Services.Locations.RequestHandlers
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);
}
}
}

View File

@@ -0,0 +1,4 @@
namespace ApplicationLayer.Services.Locations.Requests
{
public record UpdateCountryRequest(Guid Id, string CountryName, bool IsSchengen, string[] Cities);
}