From 7cf3f34f28220c8cc4f57eb5c5271022f2e12350 Mon Sep 17 00:00:00 2001 From: cuqmbr Date: Wed, 24 May 2023 20:48:27 +0300 Subject: [PATCH] refactor: change Route CRUD to perform only compound data manipulations This removes enpoints where you can CRUD only RouteAddress database table and refines those where you can CRUD both Route and RouteAddress --- Server/Configurations/MapperInitializer.cs | 47 +++-- Server/Controllers/RouteAddressController.cs | 86 --------- Server/Controllers/RouteController.cs | 66 +------ Server/Program.cs | 3 +- .../IRouteAddressManagementService.cs | 18 -- Server/Services/IRouteManagementService.cs | 24 +-- .../Services/RouteAddressManagementService.cs | 164 ---------------- Server/Services/RouteManagementService.cs | 182 ++++-------------- .../Services/TicketGroupManagementService.cs | 2 +- .../DatabaseModels/RouteAddressDetailsDto.cs | 29 --- .../DatabaseModels/RouteAddressDto.cs | 37 +--- .../DatabaseModels/RouteDto.cs | 20 +- .../Objects/RouteAddressParameters.cs | 15 -- .../Objects/RouteParameters.cs | 2 +- .../Objects/RouteWithAddressesParameters.cs | 15 -- 15 files changed, 104 insertions(+), 606 deletions(-) delete mode 100644 Server/Controllers/RouteAddressController.cs delete mode 100644 Server/Services/IRouteAddressManagementService.cs delete mode 100644 Server/Services/RouteAddressManagementService.cs delete mode 100644 SharedModels/QueryParameters/Objects/RouteAddressParameters.cs delete mode 100644 SharedModels/QueryParameters/Objects/RouteWithAddressesParameters.cs diff --git a/Server/Configurations/MapperInitializer.cs b/Server/Configurations/MapperInitializer.cs index 82623bb..3be0b46 100644 --- a/Server/Configurations/MapperInitializer.cs +++ b/Server/Configurations/MapperInitializer.cs @@ -36,22 +36,50 @@ public class MapperInitializer : Profile CreateMap().ReverseMap(); CreateMap().ReverseMap(); - CreateMap().ReverseMap(); + CreateMap() + .ForMember(d => d.AddressName, opt => opt.MapFrom(src => src.Address.Name)) + .ForMember(d => d.CityName, opt => opt.MapFrom(src => src.Address.City.Name)) + .ForMember(d => d.StateName, opt => opt.MapFrom(src => src.Address.City.State.Name)) + .ForMember(d => d.CountryName, opt => opt.MapFrom(src => src.Address.City.State.Country.Name)) + .ForMember(d => d.FullName, opt => opt.MapFrom(src => src.Address.GetFullName())) + .ForMember(d => d.Latitude, opt => opt.MapFrom(src => src.Address.Latitude)) + .ForMember(d => d.Longitude, opt => opt.MapFrom(src => src.Address.Longitude)); + CreateMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); - CreateMap().ReverseMap(); - CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); - CreateMap().ReverseMap(); - CreateMap().ReverseMap(); - CreateMap().ReverseMap(); - CreateMap(); + CreateMap() + .ForMember(d => d.Addresses, + opt => opt.MapFrom(src => src.VehicleEnrollment.Route.RouteAddresses.Select(ra => ra.Address))); - CreateMap().ReverseMap(); + CreateMap() + .ForMember(d => d.DepartureAddressName, + opt => opt.MapFrom(src => src.Tickets.First().GetDepartureAddress().Name)) + .ForMember(d => d.DepartureCityName, + opt => opt.MapFrom(src => src.Tickets.First().GetDepartureAddress().City.Name)) + .ForMember(d => d.DepartureStateName, + opt => opt.MapFrom(src => src.Tickets.First().GetDepartureAddress().City.State.Name)) + .ForMember(d => d.DepartureCountryName, + opt => opt.MapFrom(src => src.Tickets.First().GetDepartureAddress().City.State.Country.Name)) + .ForMember(d => d.DepartureFullName, + opt => opt.MapFrom(src => src.Tickets.First().GetDepartureAddress().GetFullName())) + .ForMember(d => d.DepartureDateTime, + opt => opt.MapFrom(src => src.Tickets.First().GetDepartureTime())) + .ForMember(d => d.ArrivalAddressName, + opt => opt.MapFrom(src => src.Tickets.Last().GetArrivalAddress().Name)) + .ForMember(d => d.ArrivalCityName, + opt => opt.MapFrom(src => src.Tickets.Last().GetArrivalAddress().City.Name)) + .ForMember(d => d.ArrivalStateName, + opt => opt.MapFrom(src => src.Tickets.Last().GetArrivalAddress().City.State.Name)) + .ForMember(d => d.ArrivalCountryName, + opt => opt.MapFrom(src => src.Tickets.Last().GetArrivalAddress().City.State.Country.Name)) + .ForMember(d => d.ArrivalFullName, + opt =>opt.MapFrom(src => src.Tickets.Last().GetArrivalAddress().GetFullName())) + .ForMember(d => d.ArrivalDateTime, opt => opt.MapFrom(src => src.Tickets.Last().GetArrivalTime())); CreateMap().ReverseMap(); CreateMap().ReverseMap(); @@ -83,9 +111,6 @@ public class MapperInitializer : Profile CreateMap().ReverseMap(); CreateMap().ReverseMap(); - CreateMap().ReverseMap(); - CreateMap().ReverseMap(); - CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); } diff --git a/Server/Controllers/RouteAddressController.cs b/Server/Controllers/RouteAddressController.cs deleted file mode 100644 index 0172fdb..0000000 --- a/Server/Controllers/RouteAddressController.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json; -using Server.Services; -using SharedModels.DataTransferObjects.Model; -using SharedModels.QueryParameters.Objects; - -namespace Server.Controllers; - -[Route("api/routeAddresses")] -[ApiController] -public class RouteAddressController : ControllerBase -{ - private readonly IRouteAddressManagementService _routeAddressManagementService; - - public RouteAddressController(IRouteAddressManagementService routeAddressManagementService) - { - _routeAddressManagementService = routeAddressManagementService; - } - - [HttpPost] - public async Task AddRouteAddress(CreateRouteAddressDto routeAddress) - { - var result = await _routeAddressManagementService.AddRouteAddress(routeAddress); - - if (!result.isSucceed) - { - return result.actionResult; - } - - return CreatedAtAction(nameof(GetRouteAddress), new {id = result.routeAddress.Id}, result.routeAddress); - } - - [HttpGet] - public async Task GetRouteAddresses([FromQuery] RouteAddressParameters parameters) - { - var result = await _routeAddressManagementService.GetRouteAddresses(parameters); - - if (!result.isSucceed) - { - return result.actionResult; - } - - Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(result.pagingMetadata)); - - return Ok(result.routeAddresses); - } - - [HttpGet("{id}")] - public async Task GetRouteAddress(int id, [FromQuery] string? fields) - { - var result = await _routeAddressManagementService.GetRouteAddress(id, fields); - - if (!result.isSucceed) - { - return result.actionResult; - } - - return Ok(result.routeAddress); - } - - [HttpPut("{id}")] - public async Task UpdateRouteAddress(int id, UpdateRouteAddressDto routeAddress) - { - var result = await _routeAddressManagementService.UpdateRouteAddress(routeAddress); - - if (!result.isSucceed) - { - return result.actionResult; - } - - return Ok(result.routeAddress); - } - - [HttpDelete("{id}")] - public async Task DeleteRouteAddress(int id) - { - var result = await _routeAddressManagementService.DeleteRouteAddress(id); - - if (!result.isSucceed) - { - return result.actionResult; - } - - return NoContent(); - } -} \ No newline at end of file diff --git a/Server/Controllers/RouteController.cs b/Server/Controllers/RouteController.cs index 4644141..458440f 100644 --- a/Server/Controllers/RouteController.cs +++ b/Server/Controllers/RouteController.cs @@ -33,20 +33,6 @@ public class RouteController : ControllerBase return CreatedAtAction(nameof(GetRoute), new {id = result.route.Id}, result.route); } - [Authorize(Policy = "CompanyAccess")] - [HttpPost("withAddresses")] - public async Task AddRouteWithAddresses(CreateRouteWithAddressesDto route) - { - var result = await _routeManagementService.AddRouteWithAddresses(route); - - if (!result.isSucceed) - { - return result.actionResult; - } - - return CreatedAtAction(nameof(GetRoute), new {id = result.route.Id}, result.route); - } - [Authorize(Policy = "DriverAccess")] [HttpGet] public async Task GetRoutes([FromQuery] RouteParameters parameters) @@ -63,31 +49,10 @@ public class RouteController : ControllerBase return Ok(result.routes); } - [Authorize(Policy = "DriverAccess")] - [HttpGet("withAddresses")] - public async Task GetRouteWithAddresses([FromQuery] RouteWithAddressesParameters parameters) - { - var result = await _routeManagementService.GetRoutesWithAddresses(parameters); - - if (!result.isSucceed) - { - return result.actionResult; - } - - Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(result.pagingMetadata)); - - return Ok(result.routes); - } - [Authorize(Policy = "DriverAccess")] [HttpGet("{id}")] public async Task GetRoute(int id, [FromQuery] string? fields) { - if (!await _routeManagementService.IsRouteExists(id)) - { - return NotFound(); - } - var result = await _routeManagementService.GetRoute(id, fields); if (!result.isSucceed) @@ -97,36 +62,12 @@ public class RouteController : ControllerBase return Ok(result.route); } - - [Authorize(Policy = "DriverAccess")] - [HttpGet("withAddresses/{id}")] - public async Task GetRouteWithAddresses(int id, [FromQuery] string? fields) - { - if (!await _routeManagementService.IsRouteExists(id)) - { - return NotFound(); - } - - var result = await _routeManagementService.GetRouteWithAddresses(id, fields); - - if (!result.isSucceed) - { - return result.actionResult; - } - - return Ok(result.route); - } [Authorize(Policy = "CompanyAccess")] [HttpPut("{id}")] public async Task UpdateRoute(int id, UpdateRouteDto route) { - if (id != route.Id) - { - return BadRequest(); - } - - var result = await _routeManagementService.UpdateRoute(route); + var result = await _routeManagementService.UpdateRoute(id, route); if (!result.isSucceed) { @@ -140,11 +81,6 @@ public class RouteController : ControllerBase [HttpDelete("{id}")] public async Task DeleteRoute(int id) { - if (!await _routeManagementService.IsRouteExists(id)) - { - return NotFound(); - } - var result = await _routeManagementService.DeleteRoute(id); if (!result.isSucceed) diff --git a/Server/Program.cs b/Server/Program.cs index c0be134..a3894ad 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -120,7 +120,6 @@ services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); -services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -135,7 +134,7 @@ services.AddScoped, DataShaper>(); services.AddScoped, DataShaper>(); services.AddScoped, DataShaper>(); services.AddScoped, DataShaper>(); -services.AddScoped, DataShaper>(); +services.AddScoped, DataShaper>(); services.AddScoped, DataShaper>(); services.AddScoped, DataShaper>(); services.AddScoped, DataShaper>(); diff --git a/Server/Services/IRouteAddressManagementService.cs b/Server/Services/IRouteAddressManagementService.cs deleted file mode 100644 index d1b7b79..0000000 --- a/Server/Services/IRouteAddressManagementService.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Dynamic; -using Microsoft.AspNetCore.Mvc; -using SharedModels.DataTransferObjects.Model; -using SharedModels.QueryParameters; -using SharedModels.QueryParameters.Objects; - -namespace Server.Services; - -public interface IRouteAddressManagementService -{ - Task<(bool isSucceed, IActionResult? actionResult, RouteAddressDto routeAddress)> AddRouteAddress(CreateRouteAddressDto createRouteAddressDto); - Task<(bool isSucceed, IActionResult? actionResult, IEnumerable routeAddresses, - PagingMetadata pagingMetadata)> GetRouteAddresses(RouteAddressParameters parameters); - Task<(bool isSucceed, IActionResult? actionResult, ExpandoObject routeAddress)> GetRouteAddress(int id, string? fields); - Task<(bool isSucceed, IActionResult? actionResult, RouteAddressDto routeAddress)> UpdateRouteAddress(UpdateRouteAddressDto updateRouteAddressDto); - Task<(bool isSucceed, IActionResult? actionResult)> DeleteRouteAddress(int id); - Task IsRouteAddressExists(int id); -} \ No newline at end of file diff --git a/Server/Services/IRouteManagementService.cs b/Server/Services/IRouteManagementService.cs index 4a8e952..0479c32 100644 --- a/Server/Services/IRouteManagementService.cs +++ b/Server/Services/IRouteManagementService.cs @@ -8,15 +8,17 @@ namespace Server.Services; public interface IRouteManagementService { - Task<(bool isSucceed, IActionResult? actionResult, RouteDto route)> AddRoute(CreateRouteDto createRouteDto); - Task<(bool isSucceed, IActionResult? actionResult, RouteWithAddressesDto route)> AddRouteWithAddresses(CreateRouteWithAddressesDto createRouteWithAddressesDto); - Task<(bool isSucceed, IActionResult? actionResult, IEnumerable routes, - PagingMetadata pagingMetadata)> GetRoutes(RouteParameters parameters); - Task<(bool isSucceed, IActionResult? actionResult, IEnumerable routes, - PagingMetadata pagingMetadata)> GetRoutesWithAddresses(RouteWithAddressesParameters parameters); - Task<(bool isSucceed, IActionResult? actionResult, ExpandoObject route)> GetRoute(int id, string? fields); - Task<(bool isSucceed, IActionResult? actionResult, ExpandoObject route)> GetRouteWithAddresses(int id, string? fields); - Task<(bool isSucceed, IActionResult? actionResult, UpdateRouteDto route)> UpdateRoute(UpdateRouteDto updateRouteDto); - Task<(bool isSucceed, IActionResult? actionResult)> DeleteRoute(int id); - Task IsRouteExists(int id); + Task<(bool isSucceed, IActionResult actionResult, RouteDto route)> + AddRoute(CreateRouteDto createRouteDto); + + Task<(bool isSucceed, IActionResult actionResult, IEnumerable routes, PagingMetadata pagingMetadata)> + GetRoutes(RouteParameters parameters); + + Task<(bool isSucceed, IActionResult actionResult, ExpandoObject route)> + GetRoute(int id, string? fields); + + Task<(bool isSucceed, IActionResult actionResult, UpdateRouteDto route)> + UpdateRoute(int id, UpdateRouteDto updateRouteDto); + + Task<(bool isSucceed, IActionResult actionResult)> DeleteRoute(int id); } diff --git a/Server/Services/RouteAddressManagementService.cs b/Server/Services/RouteAddressManagementService.cs deleted file mode 100644 index 7be22b9..0000000 --- a/Server/Services/RouteAddressManagementService.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System.Dynamic; -using AutoMapper; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using Server.Data; -using Server.Helpers; -using Server.Models; -using SharedModels.DataTransferObjects.Model; -using SharedModels.QueryParameters; -using SharedModels.QueryParameters.Objects; - -namespace Server.Services; - -public class RouteAddressManagementService : IRouteAddressManagementService -{ - private readonly ApplicationDbContext _dbContext; - private readonly IMapper _mapper; - private readonly ISortHelper _routeAddressSortHelper; - private readonly IDataShaper _routeAddressDataShaper; - private readonly IPager _pager; - - public RouteAddressManagementService(ApplicationDbContext dbContext, - IMapper mapper, ISortHelper routeAddressSortHelper, - IDataShaper routeAddressDataShaper, IPager pager) - { - _dbContext = dbContext; - _mapper = mapper; - _routeAddressSortHelper = routeAddressSortHelper; - _routeAddressDataShaper = routeAddressDataShaper; - _pager = pager; - } - - public async Task<(bool isSucceed, IActionResult? actionResult, RouteAddressDto routeAddress)> AddRouteAddress(CreateRouteAddressDto createRouteAddressDto) - { - var routeAddress = _mapper.Map(createRouteAddressDto); - - await _dbContext.RouteAddresses.AddAsync(routeAddress); - await _dbContext.SaveChangesAsync(); - - return (true, null, _mapper.Map(routeAddress)); - } - - public async Task<(bool isSucceed, IActionResult? actionResult, IEnumerable routeAddresses, - PagingMetadata pagingMetadata)> GetRouteAddresses(RouteAddressParameters parameters) - { - var dbRouteAddresses = _dbContext.RouteAddresses - .Include(ra => ra.Route) - .Include(ra => ra.Address) - .ThenInclude(a => a.City).ThenInclude(c => c.State) - .ThenInclude(s => s.Country) - .AsQueryable(); - - FilterByRouteAddressRouteId(ref dbRouteAddresses, parameters.RouteId); - FilterByRouteAddressAddressId(ref dbRouteAddresses, parameters.AddressId); - - var routeAddressDtos = _mapper.ProjectTo(dbRouteAddresses); - var shapedData = _routeAddressDataShaper.ShapeData(routeAddressDtos, parameters.Fields).AsQueryable(); - - try - { - shapedData = _routeAddressSortHelper.ApplySort(shapedData, parameters.Sort); - } - catch (Exception) - { - return (false, new BadRequestObjectResult("Invalid sorting string"), null!, null!); - } - - var pagingMetadata = _pager.ApplyPaging(ref shapedData, parameters.PageNumber, - parameters.PageSize); - - return (true, null, shapedData, pagingMetadata); - - void FilterByRouteAddressRouteId(ref IQueryable routeAddresses, - int? routeId) - { - if (!routeAddresses.Any() || routeId == null) - { - return; - } - - routeAddresses = routeAddresses.Where(ra => ra.RouteId == routeId); - } - - void FilterByRouteAddressAddressId(ref IQueryable routeAddresses, - int? addressId) - { - if (!routeAddresses.Any() || addressId == null) - { - return; - } - - routeAddresses = routeAddresses.Where(ra => ra.AddressId == addressId); - } - } - - public async Task<(bool isSucceed, IActionResult? actionResult, ExpandoObject routeAddress)> GetRouteAddress(int id, string? fields) - { - if (!await IsRouteAddressExists(id)) - { - return (false, new NotFoundResult(), null!); - } - - var dbRouteAddress = await _dbContext.RouteAddresses.Where(ra => ra.Id == id) - .Include(ra => ra.Route) - .Include(ra => ra.Address) - .ThenInclude(a => a.City).ThenInclude(c => c.State) - .ThenInclude(s => s.Country) - .FirstAsync(); - - if (String.IsNullOrWhiteSpace(fields)) - { - fields = RouteAddressParameters.DefaultFields; - } - - var routeAddressDto = _mapper.Map(dbRouteAddress); - var shapedData = _routeAddressDataShaper.ShapeData(routeAddressDto, fields); - - return (true, null, shapedData); - } - - public async Task<(bool isSucceed, IActionResult? actionResult, RouteAddressDto routeAddress)> UpdateRouteAddress(UpdateRouteAddressDto updateRouteAddressDto) - { - var routeAddress = _mapper.Map(updateRouteAddressDto); - _dbContext.Entry(routeAddress).State = EntityState.Modified; - - try - { - await _dbContext.SaveChangesAsync(); - } - catch (DbUpdateConcurrencyException) - { - if (!await IsRouteAddressExists(updateRouteAddressDto.Id)) - { - return (false, new NotFoundResult(), null!); - } - - throw; - } - - var dbRouteAddress = await _dbContext.RouteAddresses.FirstAsync(ra => ra.Id == routeAddress.Id); - - return (true, null, _mapper.Map(dbRouteAddress)); - } - - public async Task<(bool isSucceed, IActionResult? actionResult)> DeleteRouteAddress(int id) - { - var dbRouteAddress = await _dbContext.RouteAddresses.FirstOrDefaultAsync(ra => ra.Id == id); - - if (dbRouteAddress == null) - { - return (false, new NotFoundResult()); - } - - _dbContext.RouteAddresses.Remove(dbRouteAddress); - await _dbContext.SaveChangesAsync(); - - return (true, null); - } - - public async Task IsRouteAddressExists(int id) - { - return await _dbContext.RouteAddresses.AnyAsync(ra => ra.Id == id); - } -} \ No newline at end of file diff --git a/Server/Services/RouteManagementService.cs b/Server/Services/RouteManagementService.cs index b90c193..913c289 100644 --- a/Server/Services/RouteManagementService.cs +++ b/Server/Services/RouteManagementService.cs @@ -1,6 +1,5 @@ using System.Dynamic; using AutoMapper; -using AutoMapper.QueryableExtensions; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Server.Data; @@ -18,36 +17,23 @@ public class RouteManagementService : IRouteManagementService private readonly IMapper _mapper; private readonly ISortHelper _routeSortHelper; private readonly IDataShaper _routeDataShaper; - private readonly IDataShaper _routeWithAddressesDataShaper; private readonly IPager _pager; - public RouteManagementService(ApplicationDbContext dbContext, - IMapper mapper, ISortHelper routeSortHelper, - IDataShaper routeDataShaper, - IDataShaper routeWithAddressesDataShaper, + public RouteManagementService(ApplicationDbContext dbContext, IMapper mapper, + ISortHelper routeSortHelper, IDataShaper routeDataShaper, IPager pager) { _dbContext = dbContext; _mapper = mapper; _routeSortHelper = routeSortHelper; _routeDataShaper = routeDataShaper; - _routeWithAddressesDataShaper = routeWithAddressesDataShaper; _pager = pager; } - public async Task<(bool isSucceed, IActionResult? actionResult, RouteDto route)> AddRoute(CreateRouteDto createRouteDto) + public async Task<(bool isSucceed, IActionResult actionResult, RouteDto route)> + AddRoute(CreateRouteDto createRouteDto) { var route = _mapper.Map(createRouteDto); - - await _dbContext.Routes.AddAsync(route); - await _dbContext.SaveChangesAsync(); - - return (true, null, _mapper.Map(route)); - } - - public async Task<(bool isSucceed, IActionResult? actionResult, RouteWithAddressesDto route)> AddRouteWithAddresses(CreateRouteWithAddressesDto createRouteWithAddressesDto) - { - var route = _mapper.Map(createRouteWithAddressesDto); await _dbContext.Routes.AddAsync(route); await _dbContext.SaveChangesAsync(); @@ -57,61 +43,11 @@ public class RouteManagementService : IRouteManagementService .ThenInclude(a => a.City).ThenInclude(c => c.State) .ThenInclude(s => s.Country).FirstAsync(r => r.Id == route.Id); - return (true, null, _mapper.Map(route)); + return (true, null!, _mapper.Map(route)); } - public async Task<(bool isSucceed, IActionResult? actionResult, IEnumerable routes, - PagingMetadata pagingMetadata)> GetRoutes(RouteParameters parameters) - { - var dbRoutes = _dbContext.Routes - .AsQueryable(); - - SearchByAllRouteFields(ref dbRoutes, parameters.Search); - FilterByRouteType(ref dbRoutes, parameters.Type); - - var routeDtos = _mapper.ProjectTo(dbRoutes); - var shapedData = _routeDataShaper.ShapeData(routeDtos, parameters.Fields).AsQueryable(); - - try - { - shapedData = _routeSortHelper.ApplySort(shapedData, parameters.Sort); - } - catch (Exception) - { - return (false, new BadRequestObjectResult("Invalid sorting string"), null!, null!); - } - - var pagingMetadata = _pager.ApplyPaging(ref shapedData, parameters.PageNumber, - parameters.PageSize); - - return (true, null, shapedData, pagingMetadata); - - void SearchByAllRouteFields(ref IQueryable route, - string? search) - { - if (!route.Any() || String.IsNullOrWhiteSpace(search)) - { - return; - } - - route = route.Where(c => - c.Type.ToLower().Contains(search.ToLower())); - } - - void FilterByRouteType(ref IQueryable routes, - string? type) - { - if (!routes.Any() || String.IsNullOrWhiteSpace(type)) - { - return; - } - - routes = routes.Where(r => r.Type == type); - } - } - - public async Task<(bool isSucceed, IActionResult? actionResult, IEnumerable routes, - PagingMetadata pagingMetadata)> GetRoutesWithAddresses(RouteWithAddressesParameters parameters) + public async Task<(bool isSucceed, IActionResult actionResult, IEnumerable routes, PagingMetadata pagingMetadata)> + GetRoutes(RouteParameters parameters) { var dbRoutes = _dbContext.Routes .Include(r => r.RouteAddresses.OrderBy(ra => ra.Order)) @@ -121,11 +57,9 @@ public class RouteManagementService : IRouteManagementService SearchByAllRouteFields(ref dbRoutes, parameters.Search); FilterByRouteType(ref dbRoutes, parameters.Type); - FilterByFromAddressName(ref dbRoutes, parameters.FromAddressName); - FilterByToAddressName(ref dbRoutes, parameters.ToAddressName); - var routeDtos = _mapper.ProjectTo(dbRoutes); - var shapedData = _routeWithAddressesDataShaper.ShapeData(routeDtos, parameters.Fields).AsQueryable(); + var routeDtos = _mapper.ProjectTo(dbRoutes); + var shapedData = _routeDataShaper.ShapeData(routeDtos, parameters.Fields).AsQueryable(); try { @@ -139,10 +73,9 @@ public class RouteManagementService : IRouteManagementService var pagingMetadata = _pager.ApplyPaging(ref shapedData, parameters.PageNumber, parameters.PageSize); - return (true, null, shapedData, pagingMetadata); + return (true, null!, shapedData, pagingMetadata); - void SearchByAllRouteFields(ref IQueryable route, - string? search) + void SearchByAllRouteFields(ref IQueryable route, string? search) { if (!route.Any() || String.IsNullOrWhiteSpace(search)) { @@ -152,15 +85,11 @@ public class RouteManagementService : IRouteManagementService // TODO Optimize (remove client evaluation) route = route.ToArray().Where(r => r.Type.ToLower().Contains(search.ToLower()) || - r.RouteAddresses.OrderBy(ra => ra.Order).First().Address - .GetFullName().ToLower().Contains(search.ToLower()) || - r.RouteAddresses.OrderBy(ra => ra.Order).Last().Address - .GetFullName().ToLower().Contains(search.ToLower())) + r.RouteAddresses.Any(ra => ra.Address.GetFullName().ToLower().Contains(search.ToLower()))) .AsQueryable(); } - void FilterByRouteType(ref IQueryable routes, - string? type) + void FilterByRouteType(ref IQueryable routes, string? type) { if (!routes.Any() || String.IsNullOrWhiteSpace(type)) { @@ -169,60 +98,10 @@ public class RouteManagementService : IRouteManagementService routes = routes.Where(r => r.Type.ToLower().Contains(type.ToLower())); } - - void FilterByFromAddressName(ref IQueryable routes, - string? addressName) - { - if (!routes.Any() || String.IsNullOrWhiteSpace(addressName)) - { - return; - } - - // TODO Optimize (remove client evaluation) - routes = routes.ToArray().Where(r => - r.RouteAddresses.First().Address - .GetFullName().ToLower().Contains(addressName.ToLower())) - .AsQueryable(); - } - - void FilterByToAddressName(ref IQueryable routes, - string? addressName) - { - if (!routes.Any() || String.IsNullOrWhiteSpace(addressName)) - { - return; - } - - // TODO Optimize (remove client evaluation) - routes = routes.ToArray().Where(r => - r.RouteAddresses.Last().Address. - GetFullName().ToLower().Contains(addressName.ToLower())) - .AsQueryable(); - } } - public async Task<(bool isSucceed, IActionResult? actionResult, ExpandoObject route)> GetRoute(int id, string? fields) - { - if (!await IsRouteExists(id)) - { - return (false, new NotFoundResult(), null)!; - } - - var dbRoute = await _dbContext.Routes.Where(r => r.Id == id) - .FirstAsync(); - - if (String.IsNullOrWhiteSpace(fields)) - { - fields = RouteParameters.DefaultFields; - } - - var routeDto = _mapper.Map(dbRoute); - var shapedRouteData = _routeDataShaper.ShapeData(routeDto, fields); - - return (true, null, shapedRouteData); - } - - public async Task<(bool isSucceed, IActionResult? actionResult, ExpandoObject route)> GetRouteWithAddresses(int id, string? fields) + public async Task<(bool isSucceed, IActionResult actionResult, ExpandoObject route)> + GetRoute(int id, string? fields) { if (!await IsRouteExists(id)) { @@ -236,19 +115,25 @@ public class RouteManagementService : IRouteManagementService if (String.IsNullOrWhiteSpace(fields)) { - fields = RouteWithAddressesParameters.DefaultFields; + fields = RouteParameters.DefaultFields; } - var routeDto = _mapper.Map(dbRoute); - var shapedData = _routeWithAddressesDataShaper.ShapeData(routeDto, fields); + var routeDto = _mapper.Map(dbRoute); + var shapedData = _routeDataShaper.ShapeData(routeDto, fields); - return (true, null, shapedData); + return (true, null!, shapedData); } - public async Task<(bool isSucceed, IActionResult? actionResult, UpdateRouteDto route)> UpdateRoute(UpdateRouteDto updateRouteDto) + public async Task<(bool isSucceed, IActionResult actionResult, UpdateRouteDto route)> + UpdateRoute(int id, UpdateRouteDto updateRouteDto) { + if (id != updateRouteDto.Id) + { + return (false, new BadRequestObjectResult("Query id must match object id"), null!); + } + var route = _mapper.Map(updateRouteDto); - _dbContext.Entry(route).State = EntityState.Modified; + _dbContext.Routes.Update(route); try { @@ -262,12 +147,15 @@ public class RouteManagementService : IRouteManagementService } } - var dbRoute = await _dbContext.Routes.FirstAsync(r => r.Id == route.Id); + var dbRoute = await _dbContext.Routes + .Include(r => r.RouteAddresses).ThenInclude(ra => ra.Address) + .ThenInclude(a => a.City).ThenInclude(c => c.State) + .ThenInclude(s => s.Country).FirstAsync(r => r.Id == route.Id); - return (true, null, _mapper.Map(dbRoute)); + return (true, null!, _mapper.Map(dbRoute)); } - public async Task<(bool isSucceed, IActionResult? actionResult)> DeleteRoute(int id) + public async Task<(bool isSucceed, IActionResult actionResult)> DeleteRoute(int id) { var dbRoute = await _dbContext.Routes.FirstOrDefaultAsync(r => r.Id == id); @@ -279,10 +167,10 @@ public class RouteManagementService : IRouteManagementService _dbContext.Routes.Remove(dbRoute); await _dbContext.SaveChangesAsync(); - return (true, null); + return (true, null!); } - public async Task IsRouteExists(int id) + private async Task IsRouteExists(int id) { return await _dbContext.Routes.AnyAsync(r => r.Id == id); } diff --git a/Server/Services/TicketGroupManagementService.cs b/Server/Services/TicketGroupManagementService.cs index 47016d9..56752df 100644 --- a/Server/Services/TicketGroupManagementService.cs +++ b/Server/Services/TicketGroupManagementService.cs @@ -212,7 +212,7 @@ public class TicketGroupManagementService : ITicketGroupManagementService return ticketGroupDto; } - public async Task IsTicketGroupExist(int id) + private async Task IsTicketGroupExist(int id) { return await _dbContext.TicketGroups.AnyAsync(tg => tg.Id == id); } diff --git a/SharedModels/DataTransferObjects/DatabaseModels/RouteAddressDetailsDto.cs b/SharedModels/DataTransferObjects/DatabaseModels/RouteAddressDetailsDto.cs index 88f0723..e0c52a3 100644 --- a/SharedModels/DataTransferObjects/DatabaseModels/RouteAddressDetailsDto.cs +++ b/SharedModels/DataTransferObjects/DatabaseModels/RouteAddressDetailsDto.cs @@ -2,35 +2,6 @@ using System.ComponentModel.DataAnnotations; namespace SharedModels.DataTransferObjects.Model; -public class RouteAddressDetailsDto : CreateRouteAddressDetailsDto -{ - public int Id { get; set; } -} - -public class CreateRouteAddressDetailsDto -{ - [Required] - public int VehicleEnrollmentId { get; set; } - - [Required] - public int RouteAddressId { get; set; } - - [Required] - public TimeSpan TimeSpanToNextCity { get; set; } - - [Required] - public TimeSpan WaitTimeSpan { get; set; } - - [Required] - public double CostToNextCity { get; set; } -} - -public class UpdateRouteAddressDetailsDto : CreateRouteAddressDetailsDto -{ - [Required] - public int Id { get; set; } -} - public class CreateRouteAddressDetailsInVehicleEnrollmentDto { [Required] diff --git a/SharedModels/DataTransferObjects/DatabaseModels/RouteAddressDto.cs b/SharedModels/DataTransferObjects/DatabaseModels/RouteAddressDto.cs index 464e43b..de36649 100644 --- a/SharedModels/DataTransferObjects/DatabaseModels/RouteAddressDto.cs +++ b/SharedModels/DataTransferObjects/DatabaseModels/RouteAddressDto.cs @@ -5,17 +5,19 @@ namespace SharedModels.DataTransferObjects.Model; public class RouteAddressDto : CreateRouteAddressDto { public int Id { get; set; } + + public string AddressName { get; set; } = null!; + public string CityName { get; set; } = null!; + public string StateName { get; set; } = null!; + public string CountryName { get; set; } = null!; + public string FullName { get; set; } = null!; - public RouteDto Route { get; set; } = null!; - - public AddressDto Address { get; set; } = null!; + public double Latitude { get; set; } + public double Longitude { get; set; } } public class CreateRouteAddressDto { - [Required] - public int RouteId { get; set; } - [Required] public int AddressId { get; set; } @@ -24,29 +26,8 @@ public class CreateRouteAddressDto public int Order { get; set; } } -public class UpdateRouteAddressDto : CreateRouteAddressDto +public class UpdateRouteAddressDto : CreateRouteDto { [Required] public int Id { get; set; } -} - -public class CreateRouteAddressWithAddressDto -{ - [Range(0, Int32.MaxValue)] - public int Order { get; set; } - - public CreateAddressInRouteAddress? Address { get; set; } - - public int? AddressId { get; set; } -} - -public class RouteAddressWithAddressDto -{ - public int Id { get; set; } - - public int Order { get; set; } - - public AddressInRouteAddress Address { get; set; } = null!; - - public int AddressId { get; set; } } \ No newline at end of file diff --git a/SharedModels/DataTransferObjects/DatabaseModels/RouteDto.cs b/SharedModels/DataTransferObjects/DatabaseModels/RouteDto.cs index 00d5d25..09343db 100644 --- a/SharedModels/DataTransferObjects/DatabaseModels/RouteDto.cs +++ b/SharedModels/DataTransferObjects/DatabaseModels/RouteDto.cs @@ -4,29 +4,23 @@ namespace SharedModels.DataTransferObjects.Model; public class RouteDto : CreateRouteDto { + [Required] public int Id { get; set; } + + public new IList RouteAddresses { get; set; } = null!; } public class CreateRouteDto { [Required] public string Type { get; set; } = null!; -} - -public class UpdateRouteDto : CreateRouteDto -{ - [Required] - public int Id { get; set; } -} - -public class CreateRouteWithAddressesDto : CreateRouteDto -{ + [Required] [MinLength(2)] - public IList RouteAddresses { get; set; } = null!; + public IList RouteAddresses { get; set; } = null!; } -public class RouteWithAddressesDto : RouteDto +public class UpdateRouteDto : RouteDto { - public IList RouteAddresses { get; set; } = null!; + public new IList RouteAddresses { get; set; } = null!; } \ No newline at end of file diff --git a/SharedModels/QueryParameters/Objects/RouteAddressParameters.cs b/SharedModels/QueryParameters/Objects/RouteAddressParameters.cs deleted file mode 100644 index 08441a2..0000000 --- a/SharedModels/QueryParameters/Objects/RouteAddressParameters.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace SharedModels.QueryParameters.Objects; - -public class RouteAddressParameters : ParametersBase -{ - public const string DefaultFields = "id,routeId,route,addressId,address,order" + - ",timeSpanToNextCity,waitTimeSpan,costToNextCity"; - - public RouteAddressParameters() - { - Fields = DefaultFields; - } - - public int? RouteId { get; set; } - public int? AddressId { get; set; } -} \ No newline at end of file diff --git a/SharedModels/QueryParameters/Objects/RouteParameters.cs b/SharedModels/QueryParameters/Objects/RouteParameters.cs index caea91d..1a85349 100644 --- a/SharedModels/QueryParameters/Objects/RouteParameters.cs +++ b/SharedModels/QueryParameters/Objects/RouteParameters.cs @@ -2,7 +2,7 @@ namespace SharedModels.QueryParameters.Objects; public class RouteParameters : ParametersBase { - public const string DefaultFields = "id,type"; + public const string DefaultFields = "id,type,routeAddresses"; public RouteParameters() { diff --git a/SharedModels/QueryParameters/Objects/RouteWithAddressesParameters.cs b/SharedModels/QueryParameters/Objects/RouteWithAddressesParameters.cs deleted file mode 100644 index 2ece76a..0000000 --- a/SharedModels/QueryParameters/Objects/RouteWithAddressesParameters.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace SharedModels.QueryParameters.Objects; - -public class RouteWithAddressesParameters : ParametersBase -{ - public const string DefaultFields = "id,type,routeAddresses"; - - public RouteWithAddressesParameters() - { - Fields = DefaultFields; - } - - public string? Type { get; set; } - public string? FromAddressName { get; set; } - public string? ToAddressName { get; set; } -} \ No newline at end of file