add all vehicle enrollment with transfers search
This commit is contained in:
parent
d5ffedbdb9
commit
e3dd2dd582
@ -0,0 +1,39 @@
|
||||
using cuqmbr.TravelGuide.Domain.Enums;
|
||||
using MediatR;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application
|
||||
.VehicleEnrollmentSearch.Queries.SearchAll;
|
||||
|
||||
public record SearchAllQuery :
|
||||
IRequest<IEnumerable<VehicleEnrollmentSearchDto>>
|
||||
{
|
||||
public Guid DepartureAddressGuid { get; set; }
|
||||
|
||||
public Guid ArrivalAddressGuid { get; set; }
|
||||
|
||||
public DateOnly DepartureDate { get; set; }
|
||||
|
||||
public HashSet<VehicleType> VehicleTypes { get; set; }
|
||||
|
||||
public string Sort { get; set; } = String.Empty;
|
||||
|
||||
public TimeSpan? TravelTimeGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public TimeSpan? TravelTimeLessThanOrEqualTo { get; set; }
|
||||
|
||||
public decimal? CostGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public decimal? CostLessThanOrEqualTo { get; set; }
|
||||
|
||||
public short? NumberOfTransfersGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public short? NumberOfTransfersLessThanOrEqualTo { get; set; }
|
||||
|
||||
public DateTimeOffset? DepartureTimeGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public DateTimeOffset? DepartureTimeLessThanOrEqualTo { get; set; }
|
||||
|
||||
public DateTimeOffset? ArrivalTimeGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public DateTimeOffset? ArrivalTimeLessThanOrEqualTo { get; set; }
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||
using MediatR.Behaviors.Authorization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application
|
||||
.VehicleEnrollmentSearch.Queries.SearchAll;
|
||||
|
||||
public class SearchAllQueryAuthorizer :
|
||||
AbstractRequestAuthorizer<SearchAllQuery>
|
||||
{
|
||||
private readonly SessionUserService _sessionUserService;
|
||||
|
||||
public SearchAllQueryAuthorizer(
|
||||
SessionUserService sessionUserService)
|
||||
{
|
||||
_sessionUserService = sessionUserService;
|
||||
}
|
||||
|
||||
public override void BuildPolicy(SearchAllQuery request)
|
||||
{
|
||||
UseRequirement(new MustBeAuthenticatedRequirement
|
||||
{
|
||||
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||
});
|
||||
|
||||
UseRequirement(new MustBeInRolesRequirement
|
||||
{
|
||||
RequiredRoles = [IdentityRole.Administrator],
|
||||
UserRoles = _sessionUserService.Roles
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,522 @@
|
||||
using MediatR;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||
using cuqmbr.TravelGuide.Application.Common.Exceptions;
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
using AutoMapper;
|
||||
using QuikGraph;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using cuqmbr.TravelGuide.Domain.Enums;
|
||||
using cuqmbr.TravelGuide.Application.Common.Extensions;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application
|
||||
.VehicleEnrollmentSearch.Queries.SearchAll;
|
||||
|
||||
// TODO: Add configurable time between transfers.
|
||||
public class SearchAllQueryHandler :
|
||||
IRequestHandler<SearchAllQuery, IEnumerable<VehicleEnrollmentSearchDto>>
|
||||
{
|
||||
private readonly UnitOfWork _unitOfWork;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
private readonly SessionCurrencyService _sessionCurrencyService;
|
||||
private readonly CurrencyConverterService _currencyConverterService;
|
||||
|
||||
private readonly SessionTimeZoneService _sessionTimeZoneService;
|
||||
|
||||
public SearchAllQueryHandler(
|
||||
UnitOfWork unitOfWork,
|
||||
IMapper mapper,
|
||||
SessionCurrencyService sessionCurrencyService,
|
||||
CurrencyConverterService currencyConverterService,
|
||||
SessionTimeZoneService sessionTimeZoneService)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_mapper = mapper;
|
||||
_sessionCurrencyService = sessionCurrencyService;
|
||||
_currencyConverterService = currencyConverterService;
|
||||
_sessionTimeZoneService = sessionTimeZoneService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<VehicleEnrollmentSearchDto>> Handle(
|
||||
SearchAllQuery request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// Get related data
|
||||
|
||||
var zeroTime = TimeOnly.FromTimeSpan(TimeSpan.Zero);
|
||||
var departureDate =
|
||||
new DateTimeOffset(request.DepartureDate, zeroTime, TimeSpan.Zero);
|
||||
|
||||
var range = TimeSpan.FromDays(3);
|
||||
var vehicleEnrollments = (await _unitOfWork.VehicleEnrollmentRepository
|
||||
.GetPageAsync(
|
||||
e =>
|
||||
e.DepartureTime >= departureDate.Subtract(range) &&
|
||||
e.DepartureTime <= departureDate.Add(range) &&
|
||||
request.VehicleTypes.Contains(e.Vehicle.VehicleType),
|
||||
e => e.Route,
|
||||
1, int.MaxValue, cancellationToken))
|
||||
.Items;
|
||||
|
||||
if (vehicleEnrollments.Count == 0)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var vehicleEnrollmentIds = vehicleEnrollments.Select(e => e.Id);
|
||||
var routeAddressDetails = (await _unitOfWork.RouteAddressDetailRepository
|
||||
.GetPageAsync(
|
||||
e => vehicleEnrollmentIds.Contains(e.VehicleEnrollmentId),
|
||||
e => e.RouteAddress.Address.City.Region.Country,
|
||||
1, int.MaxValue, cancellationToken))
|
||||
.Items;
|
||||
|
||||
|
||||
// Hydrate vehicle enrollments with route address details
|
||||
|
||||
foreach (var vehicleEnrollment in vehicleEnrollments)
|
||||
{
|
||||
vehicleEnrollment.RouteAddressDetails = routeAddressDetails
|
||||
.Where(e => e.VehicleEnrollmentId == vehicleEnrollment.Id)
|
||||
.OrderBy(e => e.RouteAddress.Order)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
||||
// Creat and fill graph data structure
|
||||
|
||||
var graph = new AdjacencyGraph<
|
||||
Address, TaggedEdge<Address, RouteAddressDetail>>();
|
||||
|
||||
foreach (var vehicleEnrollment in vehicleEnrollments)
|
||||
{
|
||||
var vehicleEnrollmentRouteAddressDetails = routeAddressDetails
|
||||
.Where(e => e.VehicleEnrollmentId == vehicleEnrollment.Id)
|
||||
.OrderBy(e => e.RouteAddress.Order);
|
||||
|
||||
for (int i = 1; i < vehicleEnrollmentRouteAddressDetails.Count(); i++)
|
||||
{
|
||||
var sourceRouteAddressDetail =
|
||||
vehicleEnrollmentRouteAddressDetails.ElementAt(i - 1);
|
||||
var targetRouteAddressDetail =
|
||||
vehicleEnrollmentRouteAddressDetails.ElementAt(i);
|
||||
|
||||
var sourceAddress =
|
||||
sourceRouteAddressDetail.RouteAddress.Address;
|
||||
var targetAddress =
|
||||
targetRouteAddressDetail.RouteAddress.Address;
|
||||
|
||||
var weight = sourceRouteAddressDetail.CostToNextAddress;
|
||||
|
||||
graph.AddVerticesAndEdge(
|
||||
new TaggedEdge<Address, RouteAddressDetail>(
|
||||
sourceAddress, targetAddress, sourceRouteAddressDetail));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find paths
|
||||
|
||||
var departureAddress = routeAddressDetails
|
||||
.First(e => e.RouteAddress.Address.Guid == request.DepartureAddressGuid)
|
||||
.RouteAddress.Address;
|
||||
var arrivalAddress = routeAddressDetails
|
||||
.First(e => e.RouteAddress.Address.Guid == request.ArrivalAddressGuid)
|
||||
.RouteAddress.Address;
|
||||
|
||||
|
||||
var paths = new List<List<TaggedEdge<Address, RouteAddressDetail>>>();
|
||||
var queue = new Queue<(TaggedEdge<Address, RouteAddressDetail> edge, List<TaggedEdge<Address, RouteAddressDetail>> path)>();
|
||||
|
||||
foreach (var edge in graph.OutEdges(departureAddress))
|
||||
{
|
||||
queue.Enqueue((edge, new List<TaggedEdge<Address, RouteAddressDetail>>() { edge }));
|
||||
}
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var current = queue.Dequeue();
|
||||
|
||||
if (current.edge.Target.Equals(arrivalAddress))
|
||||
{
|
||||
paths.Add(current.path);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var edge in graph.OutEdges(current.edge.Target))
|
||||
{
|
||||
var neighbor = edge;
|
||||
if (!current.path.Contains(neighbor))
|
||||
{
|
||||
var newPath = new List<TaggedEdge<Address, RouteAddressDetail>>(current.path) { neighbor };
|
||||
queue.Enqueue((neighbor, newPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create DTO object
|
||||
|
||||
var result = new List<VehicleEnrollmentSearchDto>();
|
||||
|
||||
foreach (var path in paths)
|
||||
{
|
||||
var vehicleEnrollmentDtos =
|
||||
new List<VehicleEnrollmentSearchVehicleEnrollmentDto>();
|
||||
|
||||
var addressDtos = new List<VehicleEnrollmentSearchAddressDto>();
|
||||
|
||||
var firstRouteAddressId = path.First().Tag.RouteAddressId;
|
||||
|
||||
Guid lastRouteAddressGuid;
|
||||
long lastRouteAddressId;
|
||||
|
||||
decimal vehicleEnrollmentCost;
|
||||
Currency vehicleEnrollmentCurrency;
|
||||
|
||||
decimal costToNextAddress;
|
||||
|
||||
short addressOrder = 1;
|
||||
short enrollmentOrder = 1;
|
||||
|
||||
Address source;
|
||||
Address nextSource;
|
||||
|
||||
Address target;
|
||||
Address nextTarget;
|
||||
|
||||
RouteAddressDetail tag;
|
||||
RouteAddressDetail nextTag;
|
||||
|
||||
for (int i = 0; i < path.Count - 1; i++)
|
||||
{
|
||||
var edge = path[i];
|
||||
var nextEdge = path[i+1];
|
||||
|
||||
source = edge.Source;
|
||||
nextSource = nextEdge.Source;
|
||||
|
||||
tag = edge.Tag;
|
||||
nextTag = nextEdge.Tag;
|
||||
|
||||
|
||||
costToNextAddress = await _currencyConverterService
|
||||
.ConvertAsync(tag.CostToNextAddress,
|
||||
tag.VehicleEnrollment.Currency,
|
||||
_sessionCurrencyService.Currency, cancellationToken);
|
||||
|
||||
addressDtos.Add(new VehicleEnrollmentSearchAddressDto()
|
||||
{
|
||||
Uuid = source.Guid,
|
||||
Name = source.Name,
|
||||
Longitude = source.Latitude,
|
||||
Latitude = source.Longitude,
|
||||
CountryUuid = source.City.Region.Country.Guid,
|
||||
CountryName = source.City.Region.Country.Name,
|
||||
RegionUuid = source.City.Region.Guid,
|
||||
RegionName = source.City.Region.Name,
|
||||
CityUuid = source.City.Guid,
|
||||
CityName = source.City.Name,
|
||||
TimeToNextAddress = tag.TimeToNextAddress,
|
||||
CostToNextAddress = costToNextAddress,
|
||||
CurrentAddressStopTime = tag.CurrentAddressStopTime,
|
||||
Order = addressOrder,
|
||||
RouteAddressUuid = tag.RouteAddress.Guid
|
||||
});
|
||||
|
||||
addressOrder++;
|
||||
|
||||
|
||||
if (tag.VehicleEnrollmentId != nextTag.VehicleEnrollmentId)
|
||||
{
|
||||
target = edge.Target;
|
||||
lastRouteAddressGuid = vehicleEnrollments
|
||||
.Single(e => e.Id == tag.VehicleEnrollmentId)
|
||||
.RouteAddressDetails
|
||||
.Select(e => e.RouteAddress)
|
||||
.OrderBy(e => e.Order)
|
||||
.SkipWhile(e => e.Order != tag.RouteAddress.Order)
|
||||
.Take(2)
|
||||
.ElementAt(1)
|
||||
.Guid;
|
||||
|
||||
addressDtos.Add(new VehicleEnrollmentSearchAddressDto()
|
||||
{
|
||||
Uuid = target.Guid,
|
||||
Name = target.Name,
|
||||
Longitude = target.Latitude,
|
||||
Latitude = target.Longitude,
|
||||
CountryUuid = target.City.Region.Country.Guid,
|
||||
CountryName = target.City.Region.Country.Name,
|
||||
RegionUuid = target.City.Region.Guid,
|
||||
RegionName = target.City.Region.Name,
|
||||
CityUuid = target.City.Guid,
|
||||
CityName = target.City.Name,
|
||||
TimeToNextAddress = TimeSpan.Zero,
|
||||
CostToNextAddress = 0,
|
||||
CurrentAddressStopTime = TimeSpan.Zero,
|
||||
Order = addressOrder,
|
||||
RouteAddressUuid = lastRouteAddressGuid
|
||||
});
|
||||
|
||||
|
||||
lastRouteAddressId = vehicleEnrollments
|
||||
.Single(e => e.Id == tag.VehicleEnrollmentId)
|
||||
.RouteAddressDetails
|
||||
.Select(e => e.RouteAddress)
|
||||
.OrderBy(e => e.Order)
|
||||
.SkipWhile(e => e.Order != tag.RouteAddress.Order)
|
||||
.Take(2)
|
||||
.ElementAt(1)
|
||||
.Id;
|
||||
|
||||
vehicleEnrollmentCost = await _currencyConverterService
|
||||
.ConvertAsync(
|
||||
tag.VehicleEnrollment
|
||||
.GetCost(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
tag.VehicleEnrollment.Currency,
|
||||
_sessionCurrencyService.Currency,
|
||||
cancellationToken);
|
||||
|
||||
vehicleEnrollmentCurrency =
|
||||
_sessionCurrencyService.Currency.Equals(Currency.Default) ?
|
||||
tag.VehicleEnrollment.Currency :
|
||||
_sessionCurrencyService.Currency;
|
||||
|
||||
vehicleEnrollmentDtos.Add(
|
||||
new VehicleEnrollmentSearchVehicleEnrollmentDto()
|
||||
{
|
||||
DepartureTime = tag.VehicleEnrollment
|
||||
.GetDepartureTime(firstRouteAddressId)
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
ArrivalTime = tag.VehicleEnrollment
|
||||
.GetArrivalTime(lastRouteAddressId)
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
TravelTime = tag.VehicleEnrollment
|
||||
.GetTravelTime(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
TimeMoving = tag.VehicleEnrollment
|
||||
.GetTimeMoving(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
TimeInStops = tag.VehicleEnrollment
|
||||
.GetTimeInStops(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
NumberOfStops = tag.VehicleEnrollment
|
||||
.GetNumberOfStops(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
Currency = vehicleEnrollmentCurrency.Name,
|
||||
Cost = vehicleEnrollmentCost,
|
||||
VehicleType = source.VehicleType.Name,
|
||||
Uuid = tag.VehicleEnrollment.Guid,
|
||||
Order = enrollmentOrder,
|
||||
Addresses = addressDtos
|
||||
});
|
||||
|
||||
|
||||
firstRouteAddressId = nextTag.RouteAddressId;
|
||||
addressDtos = new List<VehicleEnrollmentSearchAddressDto>();
|
||||
addressOrder = 1;
|
||||
enrollmentOrder++;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------
|
||||
|
||||
source = path.Select(e => e.Source).Last();
|
||||
target = path.Select(e => e.Target).Last();
|
||||
tag = path.Select(e => e.Tag).Last();
|
||||
|
||||
|
||||
lastRouteAddressGuid = vehicleEnrollments
|
||||
.Single(e => e.Id == tag.VehicleEnrollmentId)
|
||||
.RouteAddressDetails
|
||||
.Select(e => e.RouteAddress)
|
||||
.OrderBy(e => e.Order)
|
||||
.SkipWhile(e => e.Order != tag.RouteAddress.Order)
|
||||
.Take(2)
|
||||
.ElementAt(1)
|
||||
.Guid;
|
||||
|
||||
costToNextAddress = await _currencyConverterService
|
||||
.ConvertAsync(tag.CostToNextAddress,
|
||||
tag.VehicleEnrollment.Currency,
|
||||
_sessionCurrencyService.Currency, cancellationToken);
|
||||
|
||||
addressDtos.Add(new VehicleEnrollmentSearchAddressDto()
|
||||
{
|
||||
Uuid = source.Guid,
|
||||
Name = source.Name,
|
||||
Longitude = source.Latitude,
|
||||
Latitude = source.Longitude,
|
||||
CountryUuid = source.City.Region.Country.Guid,
|
||||
CountryName = source.City.Region.Country.Name,
|
||||
RegionUuid = source.City.Region.Guid,
|
||||
RegionName = source.City.Region.Name,
|
||||
CityUuid = source.City.Guid,
|
||||
CityName = source.City.Name,
|
||||
TimeToNextAddress = tag.TimeToNextAddress,
|
||||
CostToNextAddress = 0,
|
||||
CurrentAddressStopTime = tag.CurrentAddressStopTime,
|
||||
Order = addressOrder,
|
||||
RouteAddressUuid = lastRouteAddressGuid
|
||||
});
|
||||
|
||||
|
||||
lastRouteAddressGuid = vehicleEnrollments
|
||||
.Single(e => e.Id == tag.VehicleEnrollmentId)
|
||||
.RouteAddressDetails
|
||||
.Select(e => e.RouteAddress)
|
||||
.OrderBy(e => e.Order)
|
||||
.SkipWhile(e => e.Order != tag.RouteAddress.Order)
|
||||
.Take(2)
|
||||
.ElementAt(1)
|
||||
.Guid;
|
||||
|
||||
addressDtos.Add(new VehicleEnrollmentSearchAddressDto()
|
||||
{
|
||||
Uuid = target.Guid,
|
||||
Name = target.Name,
|
||||
Longitude = target.Latitude,
|
||||
Latitude = target.Longitude,
|
||||
CountryUuid = target.City.Region.Country.Guid,
|
||||
CountryName = target.City.Region.Country.Name,
|
||||
RegionUuid = target.City.Region.Guid,
|
||||
RegionName = target.City.Region.Name,
|
||||
CityUuid = target.City.Guid,
|
||||
CityName = target.City.Name,
|
||||
TimeToNextAddress = TimeSpan.Zero,
|
||||
CostToNextAddress = 0,
|
||||
CurrentAddressStopTime = TimeSpan.Zero,
|
||||
Order = addressOrder,
|
||||
RouteAddressUuid = lastRouteAddressGuid
|
||||
});
|
||||
|
||||
|
||||
lastRouteAddressId = vehicleEnrollments
|
||||
.Single(e => e.Id == tag.VehicleEnrollmentId)
|
||||
.RouteAddressDetails
|
||||
.Select(e => e.RouteAddress)
|
||||
.OrderBy(e => e.Order)
|
||||
.SkipWhile(e => e.Order != tag.RouteAddress.Order)
|
||||
.Take(2)
|
||||
.ElementAt(1)
|
||||
.Id;
|
||||
|
||||
vehicleEnrollmentCost = await _currencyConverterService
|
||||
.ConvertAsync(
|
||||
tag.VehicleEnrollment
|
||||
.GetCost(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
tag.VehicleEnrollment.Currency,
|
||||
_sessionCurrencyService.Currency,
|
||||
cancellationToken);
|
||||
|
||||
vehicleEnrollmentCurrency =
|
||||
_sessionCurrencyService.Currency.Equals(Currency.Default) ?
|
||||
tag.VehicleEnrollment.Currency :
|
||||
_sessionCurrencyService.Currency;
|
||||
|
||||
vehicleEnrollmentDtos.Add(
|
||||
new VehicleEnrollmentSearchVehicleEnrollmentDto()
|
||||
{
|
||||
DepartureTime = tag.VehicleEnrollment
|
||||
.GetDepartureTime(firstRouteAddressId)
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
ArrivalTime = tag.VehicleEnrollment
|
||||
.GetArrivalTime(lastRouteAddressId)
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
TravelTime = tag.VehicleEnrollment
|
||||
.GetTravelTime(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
TimeMoving = tag.VehicleEnrollment
|
||||
.GetTimeMoving(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
TimeInStops = tag.VehicleEnrollment
|
||||
.GetTimeInStops(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
NumberOfStops = tag.VehicleEnrollment
|
||||
.GetNumberOfStops(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
Currency = vehicleEnrollmentCurrency.Name,
|
||||
Cost = vehicleEnrollmentCost,
|
||||
VehicleType = source.VehicleType.Name,
|
||||
Uuid = tag.VehicleEnrollment.Guid,
|
||||
Order = enrollmentOrder,
|
||||
Addresses = addressDtos
|
||||
});
|
||||
|
||||
// ---------------
|
||||
|
||||
|
||||
var departureTime = vehicleEnrollmentDtos
|
||||
.OrderBy(e => e.Order).First().DepartureTime;
|
||||
var arrivalTime = vehicleEnrollmentDtos
|
||||
.OrderBy(e => e.Order).Last().ArrivalTime;
|
||||
var timeInStops = vehicleEnrollmentDtos
|
||||
.Aggregate(TimeSpan.Zero, (sum, next) => sum += next.TimeInStops);
|
||||
var numberOfTransfers = vehicleEnrollmentDtos.Count() - 1;
|
||||
var cost = vehicleEnrollmentDtos
|
||||
.Aggregate((decimal)0, (sum, next) => sum += next.Cost);
|
||||
|
||||
result.Add(new VehicleEnrollmentSearchDto()
|
||||
{
|
||||
DepartureTime = departureTime
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
ArrivalTime = arrivalTime
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
TravelTime = arrivalTime - departureTime,
|
||||
TimeInStops = timeInStops,
|
||||
NumberOfTransfers = numberOfTransfers,
|
||||
Currency = _sessionCurrencyService.Currency.Name,
|
||||
Cost = cost,
|
||||
Enrollments = vehicleEnrollmentDtos
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (result.Count == 0)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
|
||||
var filteredResult = result.Where(e =>
|
||||
(request.TravelTimeGreaterThanOrEqualTo != null
|
||||
? e.TravelTime >= request.TravelTimeGreaterThanOrEqualTo
|
||||
: true) &&
|
||||
(request.TravelTimeLessThanOrEqualTo != null
|
||||
? e.TravelTime <= request.TravelTimeLessThanOrEqualTo
|
||||
: true) &&
|
||||
(request.CostGreaterThanOrEqualTo != null
|
||||
? e.Cost >= request.CostGreaterThanOrEqualTo
|
||||
: true) &&
|
||||
(request.CostLessThanOrEqualTo != null
|
||||
? e.Cost <= request.CostLessThanOrEqualTo
|
||||
: true) &&
|
||||
(request.NumberOfTransfersGreaterThanOrEqualTo != null
|
||||
? e.NumberOfTransfers >= request.NumberOfTransfersGreaterThanOrEqualTo
|
||||
: true) &&
|
||||
(request.NumberOfTransfersLessThanOrEqualTo != null
|
||||
? e.NumberOfTransfers <= request.NumberOfTransfersLessThanOrEqualTo
|
||||
: true) &&
|
||||
(request.DepartureTimeGreaterThanOrEqualTo != null
|
||||
? e.DepartureTime >= request.DepartureTimeGreaterThanOrEqualTo
|
||||
: true) &&
|
||||
(request.DepartureTimeLessThanOrEqualTo != null
|
||||
? e.DepartureTime <= request.DepartureTimeLessThanOrEqualTo
|
||||
: true) &&
|
||||
(request.ArrivalTimeGreaterThanOrEqualTo != null
|
||||
? e.ArrivalTime >= request.ArrivalTimeGreaterThanOrEqualTo
|
||||
: true) &&
|
||||
(request.ArrivalTimeLessThanOrEqualTo != null
|
||||
? e.ArrivalTime <= request.ArrivalTimeLessThanOrEqualTo
|
||||
: true));
|
||||
|
||||
var sortedResult = QueryableExtension<VehicleEnrollmentSearchDto>
|
||||
.ApplySort(filteredResult.AsQueryable(), request.Sort);
|
||||
|
||||
|
||||
return sortedResult;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using cuqmbr.TravelGuide.Domain.Enums;
|
||||
using FluentValidation;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application
|
||||
.VehicleEnrollmentSearch.Queries.SearchAll;
|
||||
|
||||
public class SearchAllQueryValidator :
|
||||
AbstractValidator<SearchAllQuery>
|
||||
{
|
||||
public SearchAllQueryValidator(
|
||||
IStringLocalizer localizer,
|
||||
SessionCultureService cultureService)
|
||||
{
|
||||
RuleFor(v => v.DepartureAddressGuid)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||
|
||||
RuleFor(v => v.ArrivalAddressGuid)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||
|
||||
RuleFor(v => v.DepartureDate)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||
.GreaterThanOrEqualTo(DateOnly.FromDateTime(DateTime.UtcNow))
|
||||
.WithMessage(
|
||||
String.Format(
|
||||
cultureService.Culture,
|
||||
localizer["FluentValidation.GreaterThanOrEqualTo"],
|
||||
DateOnly.FromDateTime(DateTime.UtcNow)));
|
||||
|
||||
RuleForEach(v => v.VehicleTypes)
|
||||
.Must((v, vt) => VehicleType.Enumerations.ContainsValue(vt))
|
||||
.WithMessage(
|
||||
String.Format(
|
||||
localizer["FluentValidation.MustBeInEnum"],
|
||||
String.Join(
|
||||
", ",
|
||||
VehicleType.Enumerations.Values.Select(e => e.Name))));
|
||||
}
|
||||
}
|
@ -6,11 +6,11 @@ using AutoMapper;
|
||||
using QuikGraph;
|
||||
using QuikGraph.Algorithms;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using cuqmbr.TravelGuide.Domain.Enums;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application
|
||||
.VehicleEnrollmentSearch.Queries.SearchShortest;
|
||||
|
||||
// TODO: Refactor.
|
||||
// TODO: Add configurable time between transfers.
|
||||
public class SearchShortestQueryHandler :
|
||||
IRequestHandler<SearchShortestQuery, VehicleEnrollmentSearchDto>
|
||||
@ -21,16 +21,20 @@ public class SearchShortestQueryHandler :
|
||||
private readonly SessionCurrencyService _sessionCurrencyService;
|
||||
private readonly CurrencyConverterService _currencyConverterService;
|
||||
|
||||
private readonly SessionTimeZoneService _sessionTimeZoneService;
|
||||
|
||||
public SearchShortestQueryHandler(
|
||||
UnitOfWork unitOfWork,
|
||||
IMapper mapper,
|
||||
SessionCurrencyService sessionCurrencyService,
|
||||
CurrencyConverterService currencyConverterService)
|
||||
CurrencyConverterService currencyConverterService,
|
||||
SessionTimeZoneService sessionTimeZoneService)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_mapper = mapper;
|
||||
_sessionCurrencyService = sessionCurrencyService;
|
||||
_currencyConverterService = currencyConverterService;
|
||||
_sessionTimeZoneService = sessionTimeZoneService;
|
||||
}
|
||||
|
||||
public async Task<VehicleEnrollmentSearchDto> Handle(
|
||||
@ -163,10 +167,14 @@ public class SearchShortestQueryHandler :
|
||||
long lastRouteAddressId;
|
||||
Guid lastRouteAddressGuid;
|
||||
|
||||
decimal vehicleEnrollmentCost;
|
||||
Currency vehicleEnrollmentCurrency;
|
||||
|
||||
decimal costToNextAddress;
|
||||
|
||||
var addressDtos = new List<VehicleEnrollmentSearchAddressDto>();
|
||||
|
||||
var addressOrder = (short)1;
|
||||
var enrollmentTravelTime = TimeSpan.Zero;
|
||||
var enrollmentCost = (decimal)0;
|
||||
var enrollmentOrder = (short)1;
|
||||
|
||||
Address source;
|
||||
@ -181,13 +189,10 @@ public class SearchShortestQueryHandler :
|
||||
nextTag = path.Select(e => e.Tag).ElementAt(i+1);
|
||||
|
||||
|
||||
totalTravelTime +=
|
||||
tag.TimeToNextAddress + tag.CurrentAddressStopTime;
|
||||
enrollmentTravelTime +=
|
||||
tag.TimeToNextAddress + tag.CurrentAddressStopTime;
|
||||
|
||||
totalCost += tag.CostToNextAddress;
|
||||
enrollmentCost += tag.CostToNextAddress;
|
||||
costToNextAddress = await _currencyConverterService
|
||||
.ConvertAsync(tag.CostToNextAddress,
|
||||
tag.VehicleEnrollment.Currency,
|
||||
_sessionCurrencyService.Currency, cancellationToken);
|
||||
|
||||
addressDtos.Add(new VehicleEnrollmentSearchAddressDto()
|
||||
{
|
||||
@ -202,7 +207,7 @@ public class SearchShortestQueryHandler :
|
||||
CityUuid = source.City.Guid,
|
||||
CityName = source.City.Name,
|
||||
TimeToNextAddress = tag.TimeToNextAddress,
|
||||
CostToNextAddress = tag.CostToNextAddress,
|
||||
CostToNextAddress = costToNextAddress,
|
||||
CurrentAddressStopTime = tag.CurrentAddressStopTime,
|
||||
Order = addressOrder,
|
||||
RouteAddressUuid = tag.RouteAddress.Guid
|
||||
@ -255,13 +260,29 @@ public class SearchShortestQueryHandler :
|
||||
.ElementAt(1)
|
||||
.Id;
|
||||
|
||||
vehicleEnrollmentCost = await _currencyConverterService
|
||||
.ConvertAsync(
|
||||
tag.VehicleEnrollment
|
||||
.GetCost(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
tag.VehicleEnrollment.Currency,
|
||||
_sessionCurrencyService.Currency,
|
||||
cancellationToken);
|
||||
|
||||
vehicleEnrollmentCurrency =
|
||||
_sessionCurrencyService.Currency.Equals(Currency.Default) ?
|
||||
tag.VehicleEnrollment.Currency :
|
||||
_sessionCurrencyService.Currency;
|
||||
|
||||
vehicleEnrollmentDtos.Add(
|
||||
new VehicleEnrollmentSearchVehicleEnrollmentDto()
|
||||
{
|
||||
DepartureTime = tag.VehicleEnrollment
|
||||
.GetDepartureTime(firstRouteAddressId),
|
||||
.GetDepartureTime(firstRouteAddressId)
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
ArrivalTime = tag.VehicleEnrollment
|
||||
.GetArrivalTime(lastRouteAddressId),
|
||||
.GetArrivalTime(lastRouteAddressId)
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
TravelTime = tag.VehicleEnrollment
|
||||
.GetTravelTime(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
@ -274,10 +295,8 @@ public class SearchShortestQueryHandler :
|
||||
NumberOfStops = tag.VehicleEnrollment
|
||||
.GetNumberOfStops(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
Currency = tag.VehicleEnrollment.Currency.Name,
|
||||
Cost = tag.VehicleEnrollment
|
||||
.GetCost(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
Currency = vehicleEnrollmentCurrency.Name,
|
||||
Cost = vehicleEnrollmentCost,
|
||||
VehicleType = source.VehicleType.Name,
|
||||
Uuid = tag.VehicleEnrollment.Guid,
|
||||
Order = enrollmentOrder,
|
||||
@ -288,8 +307,6 @@ public class SearchShortestQueryHandler :
|
||||
|
||||
addressDtos = new List<VehicleEnrollmentSearchAddressDto>();
|
||||
addressOrder = (short)1;
|
||||
enrollmentTravelTime = TimeSpan.Zero;
|
||||
enrollmentCost = (decimal)0;
|
||||
enrollmentOrder++;
|
||||
}
|
||||
}
|
||||
@ -299,6 +316,12 @@ public class SearchShortestQueryHandler :
|
||||
tag = path.Select(e => e.Tag).Last();
|
||||
nextTag = path.Select(e => e.Tag).Last();
|
||||
|
||||
|
||||
costToNextAddress = await _currencyConverterService
|
||||
.ConvertAsync(tag.CostToNextAddress,
|
||||
tag.VehicleEnrollment.Currency,
|
||||
_sessionCurrencyService.Currency, cancellationToken);
|
||||
|
||||
addressDtos.Add(new VehicleEnrollmentSearchAddressDto()
|
||||
{
|
||||
Uuid = source.Guid,
|
||||
@ -312,12 +335,14 @@ public class SearchShortestQueryHandler :
|
||||
CityUuid = source.City.Guid,
|
||||
CityName = source.City.Name,
|
||||
TimeToNextAddress = tag.TimeToNextAddress,
|
||||
CostToNextAddress = tag.CostToNextAddress,
|
||||
CostToNextAddress = costToNextAddress,
|
||||
CurrentAddressStopTime = tag.CurrentAddressStopTime,
|
||||
Order = addressOrder,
|
||||
RouteAddressUuid = tag.RouteAddress.Guid
|
||||
});
|
||||
|
||||
addressOrder++;
|
||||
|
||||
lastRouteAddressGuid = vehicleEnrollments
|
||||
.Single(e => e.Id == tag.VehicleEnrollmentId)
|
||||
.RouteAddressDetails
|
||||
@ -328,7 +353,6 @@ public class SearchShortestQueryHandler :
|
||||
.ElementAt(1)
|
||||
.Guid;
|
||||
|
||||
addressOrder++;
|
||||
addressDtos.Add(new VehicleEnrollmentSearchAddressDto()
|
||||
{
|
||||
Uuid = target.Guid,
|
||||
@ -358,13 +382,29 @@ public class SearchShortestQueryHandler :
|
||||
.ElementAt(1)
|
||||
.Id;
|
||||
|
||||
vehicleEnrollmentCost = await _currencyConverterService
|
||||
.ConvertAsync(
|
||||
tag.VehicleEnrollment
|
||||
.GetCost(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
tag.VehicleEnrollment.Currency,
|
||||
_sessionCurrencyService.Currency,
|
||||
cancellationToken);
|
||||
|
||||
vehicleEnrollmentCurrency =
|
||||
_sessionCurrencyService.Currency.Equals(Currency.Default) ?
|
||||
tag.VehicleEnrollment.Currency :
|
||||
_sessionCurrencyService.Currency;
|
||||
|
||||
vehicleEnrollmentDtos.Add(
|
||||
new VehicleEnrollmentSearchVehicleEnrollmentDto()
|
||||
{
|
||||
DepartureTime = tag.VehicleEnrollment
|
||||
.GetDepartureTime(firstRouteAddressId),
|
||||
.GetDepartureTime(firstRouteAddressId)
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
ArrivalTime = tag.VehicleEnrollment
|
||||
.GetArrivalTime(lastRouteAddressId),
|
||||
.GetArrivalTime(lastRouteAddressId)
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
TravelTime = tag.VehicleEnrollment
|
||||
.GetTravelTime(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
@ -377,10 +417,8 @@ public class SearchShortestQueryHandler :
|
||||
NumberOfStops = tag.VehicleEnrollment
|
||||
.GetNumberOfStops(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
Currency = tag.VehicleEnrollment.Currency.Name,
|
||||
Cost = tag.VehicleEnrollment
|
||||
.GetCost(firstRouteAddressId,
|
||||
lastRouteAddressId),
|
||||
Currency = vehicleEnrollmentCurrency.Name,
|
||||
Cost = vehicleEnrollmentCost,
|
||||
VehicleType = source.VehicleType.Name,
|
||||
Uuid = tag.VehicleEnrollment.Guid,
|
||||
Order = enrollmentOrder,
|
||||
@ -393,28 +431,6 @@ public class SearchShortestQueryHandler :
|
||||
}
|
||||
|
||||
|
||||
foreach (var vehicleEnrollmentDto in vehicleEnrollmentDtos)
|
||||
{
|
||||
foreach (var addressDto in vehicleEnrollmentDto.Addresses)
|
||||
{
|
||||
addressDto.CostToNextAddress = await _currencyConverterService
|
||||
.ConvertAsync(addressDto.CostToNextAddress,
|
||||
vehicleEnrollments
|
||||
.First(e => e.Guid == vehicleEnrollmentDto.Uuid)
|
||||
.Currency,
|
||||
_sessionCurrencyService.Currency, cancellationToken);
|
||||
}
|
||||
|
||||
vehicleEnrollmentDto.Currency = vehicleEnrollmentDto.Currency;
|
||||
vehicleEnrollmentDto.Cost = vehicleEnrollmentDto.Addresses
|
||||
.Aggregate((decimal)0,
|
||||
(sum, next) => sum += next.CostToNextAddress);
|
||||
}
|
||||
|
||||
var cost = vehicleEnrollmentDtos
|
||||
.Aggregate((decimal)0,
|
||||
(sum, next) => sum += next.Cost);
|
||||
|
||||
var departureTime = vehicleEnrollmentDtos
|
||||
.OrderBy(e => e.Order).First().DepartureTime;
|
||||
var arrivalTime = vehicleEnrollmentDtos
|
||||
@ -422,14 +438,20 @@ public class SearchShortestQueryHandler :
|
||||
var timeInStops = vehicleEnrollmentDtos
|
||||
.Aggregate(TimeSpan.Zero, (sum, next) => sum += next.TimeInStops);
|
||||
var numberOfTransfers = vehicleEnrollmentDtos.Count() - 1;
|
||||
var cost = vehicleEnrollmentDtos
|
||||
.Aggregate((decimal)0, (sum, next) => sum += next.Cost);
|
||||
|
||||
return new VehicleEnrollmentSearchDto()
|
||||
{
|
||||
DepartureTime = departureTime,
|
||||
ArrivalTime = arrivalTime,
|
||||
DepartureTime = departureTime
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
ArrivalTime = arrivalTime
|
||||
.ToOffset(_sessionTimeZoneService.TimeZone.BaseUtcOffset),
|
||||
TravelTime = arrivalTime - departureTime,
|
||||
TimeInStops = timeInStops,
|
||||
NumberOfTransfers = numberOfTransfers,
|
||||
Currency = _sessionCurrencyService.Currency.Name,
|
||||
Cost = cost,
|
||||
Enrollments = vehicleEnrollmentDtos
|
||||
};
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ public sealed class VehicleEnrollmentSearchDto
|
||||
|
||||
public int NumberOfTransfers { get; set; }
|
||||
|
||||
public string Currency { get; set; }
|
||||
|
||||
public decimal Cost { get; set; }
|
||||
|
||||
public ICollection<VehicleEnrollmentSearchVehicleEnrollmentDto>
|
||||
Enrollments { get; set; }
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
namespace cuqmbr.TravelGuide.Application.VehicleEnrollmentSearch.ViewModels;
|
||||
|
||||
public sealed class SearchAllViewModel
|
||||
{
|
||||
public Guid DepartureAddressUuid { get; set; }
|
||||
|
||||
public Guid ArrivalAddressUuid { get; set; }
|
||||
|
||||
public DateOnly DepartureDate { get; set; }
|
||||
|
||||
public HashSet<string> VehicleTypes { get; set; }
|
||||
|
||||
public TimeSpan? TravelTimeGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public TimeSpan? TravelTimeLessThanOrEqualTo { get; set; }
|
||||
|
||||
public decimal? CostGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public decimal? CostLessThanOrEqualTo { get; set; }
|
||||
|
||||
public short? NumberOfTransfersGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public short? NumberOfTransfersLessThanOrEqualTo { get; set; }
|
||||
|
||||
public DateTimeOffset? DepartureTimeGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public DateTimeOffset? DepartureTimeLessThanOrEqualTo { get; set; }
|
||||
|
||||
public DateTimeOffset? ArrivalTimeGreaterThanOrEqualTo { get; set; }
|
||||
|
||||
public DateTimeOffset? ArrivalTimeLessThanOrEqualTo { get; set; }
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
using cuqmbr.TravelGuide.Domain.Enums;
|
||||
using cuqmbr.TravelGuide.Application.Common.ViewModels;
|
||||
using cuqmbr.TravelGuide.Application.VehicleEnrollmentSearch;
|
||||
using cuqmbr.TravelGuide.Application.VehicleEnrollmentSearch
|
||||
.Queries.SearchShortest;
|
||||
using cuqmbr.TravelGuide.Application.VehicleEnrollmentSearch
|
||||
.Queries.SearchAll;
|
||||
using cuqmbr.TravelGuide.Application.VehicleEnrollmentSearch.ViewModels;
|
||||
|
||||
namespace cuqmbr.TravelGuide.HttpApi.Controllers;
|
||||
@ -11,8 +14,8 @@ namespace cuqmbr.TravelGuide.HttpApi.Controllers;
|
||||
[Route("vehicleEnrollmentSearch")]
|
||||
public class VehicleEnrollmentSearchController : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[SwaggerOperation("Search vehicle enrollments with transfers")]
|
||||
[HttpGet("shortest")]
|
||||
[SwaggerOperation("Search shortest vehicle enrollments with transfers")]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status200OK, "Search successful",
|
||||
typeof(VehicleEnrollmentSearchDto))]
|
||||
@ -32,7 +35,7 @@ public class VehicleEnrollmentSearchController : ControllerBase
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||
typeof(ProblemDetails))]
|
||||
public async Task<ActionResult<VehicleEnrollmentSearchDto>> Add(
|
||||
public async Task<ActionResult<VehicleEnrollmentSearchDto>> SearchShortest(
|
||||
[FromQuery] SearchShortestViewModel viewModel,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
@ -51,4 +54,66 @@ public class VehicleEnrollmentSearchController : ControllerBase
|
||||
},
|
||||
cancellationToken));
|
||||
}
|
||||
|
||||
[HttpGet("all")]
|
||||
[SwaggerOperation("Search all vehicle enrollments with transfers")]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status200OK, "Search successful",
|
||||
typeof(IEnumerable<VehicleEnrollmentSearchDto>))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||
typeof(HttpValidationProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status403Forbidden,
|
||||
"Not enough privileges to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status404NotFound, "No enrollments found",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||
typeof(ProblemDetails))]
|
||||
public async Task<ActionResult<IEnumerable<VehicleEnrollmentSearchDto>>>
|
||||
SearchAll(
|
||||
[FromQuery] SearchAllViewModel viewModel,
|
||||
[FromQuery] SortQuery sortQuery,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return StatusCode(
|
||||
StatusCodes.Status201Created,
|
||||
await Mediator.Send(
|
||||
new SearchAllQuery()
|
||||
{
|
||||
DepartureAddressGuid = viewModel.DepartureAddressUuid,
|
||||
ArrivalAddressGuid = viewModel.ArrivalAddressUuid,
|
||||
DepartureDate = viewModel.DepartureDate,
|
||||
VehicleTypes = viewModel.VehicleTypes
|
||||
.Select(e => VehicleType.FromName(e)).ToHashSet(),
|
||||
Sort = sortQuery.Sort,
|
||||
TravelTimeGreaterThanOrEqualTo =
|
||||
viewModel.TravelTimeGreaterThanOrEqualTo,
|
||||
TravelTimeLessThanOrEqualTo =
|
||||
viewModel.TravelTimeLessThanOrEqualTo,
|
||||
CostGreaterThanOrEqualTo =
|
||||
viewModel.CostGreaterThanOrEqualTo,
|
||||
CostLessThanOrEqualTo =
|
||||
viewModel.CostLessThanOrEqualTo,
|
||||
NumberOfTransfersGreaterThanOrEqualTo =
|
||||
viewModel.NumberOfTransfersGreaterThanOrEqualTo,
|
||||
NumberOfTransfersLessThanOrEqualTo =
|
||||
viewModel.NumberOfTransfersLessThanOrEqualTo,
|
||||
DepartureTimeGreaterThanOrEqualTo =
|
||||
viewModel.DepartureTimeGreaterThanOrEqualTo,
|
||||
DepartureTimeLessThanOrEqualTo =
|
||||
viewModel.DepartureTimeLessThanOrEqualTo,
|
||||
ArrivalTimeGreaterThanOrEqualTo =
|
||||
viewModel.ArrivalTimeGreaterThanOrEqualTo,
|
||||
ArrivalTimeLessThanOrEqualTo =
|
||||
viewModel.ArrivalTimeLessThanOrEqualTo
|
||||
},
|
||||
cancellationToken));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user