Files
vegasco/src/Vegasco.Server.Api/Consumptions/GetConsumptions.cs
ThompsonNye 84a72a8557
Some checks failed
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
Add more logging and trace parameters
2025-07-21 20:58:45 +02:00

102 lines
2.6 KiB
C#

using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Diagnostics;
using Vegasco.Server.Api.Cars;
using Vegasco.Server.Api.Persistence;
namespace Vegasco.Server.Api.Consumptions;
public static class GetConsumptions
{
public class ApiResponse
{
public IEnumerable<ResponseDto> Consumptions { get; set; } = [];
}
public record ResponseDto(
Guid Id,
DateTimeOffset DateTime,
double Distance,
double Amount,
CarDto Car,
double? LiterPer100Km);
public record CarDto(
Guid Id,
string Name)
{
public static CarDto FromCar(Car car)
{
return new CarDto(car.Id.Value, car.Name);
}
}
public class Request
{
[FromQuery(Name = "page")] public int? Page { get; set; }
[FromQuery(Name = "pageSize")] public int? PageSize { get; set; }
}
public static RouteHandlerBuilder MapEndpoint(IEndpointRouteBuilder builder)
{
return builder
.MapGet("consumptions", Endpoint)
.WithDescription("Returns all consumption entries")
.WithTags("Consumptions")
.Produces<ApiResponse>();
}
private static async Task<Ok<ApiResponse>> Endpoint(
[AsParameters] Request request,
ApplicationDbContext dbContext,
ILoggerFactory loggerFactory,
CancellationToken cancellationToken)
{
ILogger logger = loggerFactory.CreateLogger(nameof(GetConsumptions));
logger.LogTrace("Received request to get consumptions with parameters: {@Request}", request);
Activity? activity = Activity.Current;
Dictionary<CarId, List<Consumption>> consumptionsByCar = await dbContext.Consumptions
.Include(x => x.Car)
.GroupBy(x => x.CarId)
.ToDictionaryAsync(x => x.Key, x => x.OrderByDescending(x => x.DateTime).ToList(), cancellationToken);
List<ResponseDto> responses = [];
foreach (List<Consumption> consumptions in consumptionsByCar.Select(x => x.Value))
{
for (int i = 0; i < consumptions.Count; i++)
{
Consumption consumption = consumptions[i];
double? literPer100Km = null;
bool isLast = i == consumptions.Count - 1;
if (!isLast)
{
Consumption previousConsumption = consumptions[i + 1];
double distanceDiff = consumption.Distance - previousConsumption.Distance;
literPer100Km = consumption.Amount / (distanceDiff / 100);
}
responses.Add(new ResponseDto(
consumption.Id.Value,
consumption.DateTime,
consumption.Distance,
consumption.Amount,
CarDto.FromCar(consumption.Car),
literPer100Km));
}
}
activity?.SetTag("consumptionCount", responses.Count);
ApiResponse apiResponse = new()
{
Consumptions = responses
};
return TypedResults.Ok(apiResponse);
}
}