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
This commit is contained in:
parent
39fddff553
commit
7cf3f34f28
@ -36,22 +36,50 @@ public class MapperInitializer : Profile
|
||||
CreateMap<Address, CreateAddressInRouteAddress>().ReverseMap();
|
||||
CreateMap<Address, AddressInRouteAddress>().ReverseMap();
|
||||
|
||||
CreateMap<RouteAddress, RouteAddressDto>().ReverseMap();
|
||||
CreateMap<RouteAddress, RouteAddressDto>()
|
||||
.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<RouteAddressDto, RouteAddress>();
|
||||
CreateMap<RouteAddress, CreateRouteAddressDto>().ReverseMap();
|
||||
CreateMap<RouteAddress, UpdateRouteAddressDto>().ReverseMap();
|
||||
CreateMap<RouteAddress, CreateRouteAddressWithAddressDto>().ReverseMap();
|
||||
CreateMap<RouteAddress, RouteAddressWithAddressDto>().ReverseMap();
|
||||
|
||||
CreateMap<Route, RouteDto>().ReverseMap();
|
||||
CreateMap<Route, CreateRouteDto>().ReverseMap();
|
||||
CreateMap<Route, UpdateRouteDto>().ReverseMap();
|
||||
CreateMap<Route, CreateRouteWithAddressesDto>().ReverseMap();
|
||||
CreateMap<Route, RouteWithAddressesDto>().ReverseMap();
|
||||
|
||||
CreateMap<Ticket, TicketDto>().ReverseMap();
|
||||
CreateMap<TicketGroup, TicketDto>();
|
||||
CreateMap<Ticket, TicketDto>()
|
||||
.ForMember(d => d.Addresses,
|
||||
opt => opt.MapFrom(src => src.VehicleEnrollment.Route.RouteAddresses.Select(ra => ra.Address)));
|
||||
|
||||
CreateMap<TicketGroup, TicketGroupDto>().ReverseMap();
|
||||
CreateMap<TicketGroup, TicketGroupDto>()
|
||||
.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<Review, ReviewDto>().ReverseMap();
|
||||
CreateMap<Review, CreateReviewDto>().ReverseMap();
|
||||
@ -83,9 +111,6 @@ public class MapperInitializer : Profile
|
||||
CreateMap<CreateUserDto, CreateDriverDto>().ReverseMap();
|
||||
CreateMap<CreateDriverDto, UpdateDriverDto>().ReverseMap();
|
||||
|
||||
CreateMap<RouteAddressDetails, RouteAddressDetailsDto>().ReverseMap();
|
||||
CreateMap<RouteAddressDetails, CreateRouteAddressDetailsDto>().ReverseMap();
|
||||
CreateMap<RouteAddressDetails, UpdateRouteAddressDetailsDto>().ReverseMap();
|
||||
CreateMap<RouteAddressDetails, RouteAddressDetailsInVehicleEnrollmentDto>().ReverseMap();
|
||||
CreateMap<RouteAddressDetails, CreateRouteAddressDetailsInVehicleEnrollmentDto>().ReverseMap();
|
||||
}
|
||||
|
@ -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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> DeleteRouteAddress(int id)
|
||||
{
|
||||
var result = await _routeAddressManagementService.DeleteRouteAddress(id);
|
||||
|
||||
if (!result.isSucceed)
|
||||
{
|
||||
return result.actionResult;
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
@ -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<IActionResult> 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<IActionResult> GetRoutes([FromQuery] RouteParameters parameters)
|
||||
@ -63,31 +49,10 @@ public class RouteController : ControllerBase
|
||||
return Ok(result.routes);
|
||||
}
|
||||
|
||||
[Authorize(Policy = "DriverAccess")]
|
||||
[HttpGet("withAddresses")]
|
||||
public async Task<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> DeleteRoute(int id)
|
||||
{
|
||||
if (!await _routeManagementService.IsRouteExists(id))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var result = await _routeManagementService.DeleteRoute(id);
|
||||
|
||||
if (!result.isSucceed)
|
||||
|
@ -120,7 +120,6 @@ services.AddScoped<ICompanyManagementService, CompanyManagementService>();
|
||||
services.AddScoped<IVehicleManagementService, VehicleManagementService>();
|
||||
services.AddScoped<IVehicleEnrollmentManagementService, VehicleEnrollmentManagementService>();
|
||||
services.AddScoped<IRouteManagementService, RouteManagementService>();
|
||||
services.AddScoped<IRouteAddressManagementService, RouteAddressManagementService>();
|
||||
services.AddScoped<IUserManagementService, UserManagementService>();
|
||||
services.AddScoped<IDriverManagementService, DriverManagementService>();
|
||||
|
||||
@ -135,7 +134,7 @@ services.AddScoped<IDataShaper<CompanyDto>, DataShaper<CompanyDto>>();
|
||||
services.AddScoped<IDataShaper<VehicleDto>, DataShaper<VehicleDto>>();
|
||||
services.AddScoped<IDataShaper<VehicleEnrollmentDto>, DataShaper<VehicleEnrollmentDto>>();
|
||||
services.AddScoped<IDataShaper<RouteDto>, DataShaper<RouteDto>>();
|
||||
services.AddScoped<IDataShaper<RouteWithAddressesDto>, DataShaper<RouteWithAddressesDto>>();
|
||||
services.AddScoped<IDataShaper<RouteDto>, DataShaper<RouteDto>>();
|
||||
services.AddScoped<IDataShaper<RouteAddressDto>, DataShaper<RouteAddressDto>>();
|
||||
services.AddScoped<IDataShaper<UserDto>, DataShaper<UserDto>>();
|
||||
services.AddScoped<IDataShaper<DriverDto>, DataShaper<DriverDto>>();
|
||||
|
@ -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<ExpandoObject> routeAddresses,
|
||||
PagingMetadata<ExpandoObject> 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<bool> IsRouteAddressExists(int id);
|
||||
}
|
@ -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<ExpandoObject> routes,
|
||||
PagingMetadata<ExpandoObject> pagingMetadata)> GetRoutes(RouteParameters parameters);
|
||||
Task<(bool isSucceed, IActionResult? actionResult, IEnumerable<ExpandoObject> routes,
|
||||
PagingMetadata<ExpandoObject> 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<bool> IsRouteExists(int id);
|
||||
Task<(bool isSucceed, IActionResult actionResult, RouteDto route)>
|
||||
AddRoute(CreateRouteDto createRouteDto);
|
||||
|
||||
Task<(bool isSucceed, IActionResult actionResult, IEnumerable<ExpandoObject> routes, PagingMetadata<ExpandoObject> 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);
|
||||
}
|
||||
|
@ -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<ExpandoObject> _routeAddressSortHelper;
|
||||
private readonly IDataShaper<RouteAddressDto> _routeAddressDataShaper;
|
||||
private readonly IPager<ExpandoObject> _pager;
|
||||
|
||||
public RouteAddressManagementService(ApplicationDbContext dbContext,
|
||||
IMapper mapper, ISortHelper<ExpandoObject> routeAddressSortHelper,
|
||||
IDataShaper<RouteAddressDto> routeAddressDataShaper, IPager<ExpandoObject> 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<RouteAddress>(createRouteAddressDto);
|
||||
|
||||
await _dbContext.RouteAddresses.AddAsync(routeAddress);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return (true, null, _mapper.Map<RouteAddressDto>(routeAddress));
|
||||
}
|
||||
|
||||
public async Task<(bool isSucceed, IActionResult? actionResult, IEnumerable<ExpandoObject> routeAddresses,
|
||||
PagingMetadata<ExpandoObject> 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<RouteAddressDto>(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<RouteAddress> routeAddresses,
|
||||
int? routeId)
|
||||
{
|
||||
if (!routeAddresses.Any() || routeId == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
routeAddresses = routeAddresses.Where(ra => ra.RouteId == routeId);
|
||||
}
|
||||
|
||||
void FilterByRouteAddressAddressId(ref IQueryable<RouteAddress> 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<RouteAddressDto>(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<RouteAddress>(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<RouteAddressDto>(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<bool> IsRouteAddressExists(int id)
|
||||
{
|
||||
return await _dbContext.RouteAddresses.AnyAsync(ra => ra.Id == id);
|
||||
}
|
||||
}
|
@ -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<ExpandoObject> _routeSortHelper;
|
||||
private readonly IDataShaper<RouteDto> _routeDataShaper;
|
||||
private readonly IDataShaper<RouteWithAddressesDto> _routeWithAddressesDataShaper;
|
||||
private readonly IPager<ExpandoObject> _pager;
|
||||
|
||||
public RouteManagementService(ApplicationDbContext dbContext,
|
||||
IMapper mapper, ISortHelper<ExpandoObject> routeSortHelper,
|
||||
IDataShaper<RouteDto> routeDataShaper,
|
||||
IDataShaper<RouteWithAddressesDto> routeWithAddressesDataShaper,
|
||||
public RouteManagementService(ApplicationDbContext dbContext, IMapper mapper,
|
||||
ISortHelper<ExpandoObject> routeSortHelper, IDataShaper<RouteDto> routeDataShaper,
|
||||
IPager<ExpandoObject> 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<Route>(createRouteDto);
|
||||
|
||||
await _dbContext.Routes.AddAsync(route);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return (true, null, _mapper.Map<RouteDto>(route));
|
||||
}
|
||||
|
||||
public async Task<(bool isSucceed, IActionResult? actionResult, RouteWithAddressesDto route)> AddRouteWithAddresses(CreateRouteWithAddressesDto createRouteWithAddressesDto)
|
||||
{
|
||||
var route = _mapper.Map<Route>(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<RouteWithAddressesDto>(route));
|
||||
return (true, null!, _mapper.Map<RouteDto>(route));
|
||||
}
|
||||
|
||||
public async Task<(bool isSucceed, IActionResult? actionResult, IEnumerable<ExpandoObject> routes,
|
||||
PagingMetadata<ExpandoObject> pagingMetadata)> GetRoutes(RouteParameters parameters)
|
||||
{
|
||||
var dbRoutes = _dbContext.Routes
|
||||
.AsQueryable();
|
||||
|
||||
SearchByAllRouteFields(ref dbRoutes, parameters.Search);
|
||||
FilterByRouteType(ref dbRoutes, parameters.Type);
|
||||
|
||||
var routeDtos = _mapper.ProjectTo<RouteDto>(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> route,
|
||||
string? search)
|
||||
{
|
||||
if (!route.Any() || String.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
route = route.Where(c =>
|
||||
c.Type.ToLower().Contains(search.ToLower()));
|
||||
}
|
||||
|
||||
void FilterByRouteType(ref IQueryable<Route> 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<ExpandoObject> routes,
|
||||
PagingMetadata<ExpandoObject> pagingMetadata)> GetRoutesWithAddresses(RouteWithAddressesParameters parameters)
|
||||
public async Task<(bool isSucceed, IActionResult actionResult, IEnumerable<ExpandoObject> routes, PagingMetadata<ExpandoObject> 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<RouteWithAddressesDto>(dbRoutes);
|
||||
var shapedData = _routeWithAddressesDataShaper.ShapeData(routeDtos, parameters.Fields).AsQueryable();
|
||||
var routeDtos = _mapper.ProjectTo<RouteDto>(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> route,
|
||||
string? search)
|
||||
void SearchByAllRouteFields(ref IQueryable<Route> 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<Route> routes,
|
||||
string? type)
|
||||
void FilterByRouteType(ref IQueryable<Route> 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<Route> 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<Route> 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<RouteDto>(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<RouteWithAddressesDto>(dbRoute);
|
||||
var shapedData = _routeWithAddressesDataShaper.ShapeData(routeDto, fields);
|
||||
var routeDto = _mapper.Map<RouteDto>(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<Route>(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<UpdateRouteDto>(dbRoute));
|
||||
return (true, null!, _mapper.Map<UpdateRouteDto>(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<bool> IsRouteExists(int id)
|
||||
private async Task<bool> IsRouteExists(int id)
|
||||
{
|
||||
return await _dbContext.Routes.AnyAsync(r => r.Id == id);
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ public class TicketGroupManagementService : ITicketGroupManagementService
|
||||
return ticketGroupDto;
|
||||
}
|
||||
|
||||
public async Task<bool> IsTicketGroupExist(int id)
|
||||
private async Task<bool> IsTicketGroupExist(int id)
|
||||
{
|
||||
return await _dbContext.TicketGroups.AnyAsync(tg => tg.Id == id);
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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; }
|
||||
}
|
@ -4,29 +4,23 @@ namespace SharedModels.DataTransferObjects.Model;
|
||||
|
||||
public class RouteDto : CreateRouteDto
|
||||
{
|
||||
[Required]
|
||||
public int Id { get; set; }
|
||||
|
||||
public new IList<RouteAddressDto> 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<CreateRouteAddressWithAddressDto> RouteAddresses { get; set; } = null!;
|
||||
public IList<CreateRouteAddressDto> RouteAddresses { get; set; } = null!;
|
||||
}
|
||||
|
||||
public class RouteWithAddressesDto : RouteDto
|
||||
public class UpdateRouteDto : RouteDto
|
||||
{
|
||||
public IList<RouteAddressWithAddressDto> RouteAddresses { get; set; } = null!;
|
||||
public new IList<RouteAddressDto> RouteAddresses { get; set; } = 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; }
|
||||
}
|
@ -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()
|
||||
{
|
||||
|
@ -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; }
|
||||
}
|
Loading…
Reference in New Issue
Block a user