Rename WebApi project to Vegasco.Server.Api
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
And update all references including comments etc.
This commit is contained in:
52
src/Vegasco.Server.Api/Consumptions/Consumption.cs
Normal file
52
src/Vegasco.Server.Api/Consumptions/Consumption.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Vegasco.Server.Api.Cars;
|
||||
|
||||
namespace Vegasco.Server.Api.Consumptions;
|
||||
|
||||
public class Consumption
|
||||
{
|
||||
public ConsumptionId Id { get; set; } = ConsumptionId.New();
|
||||
|
||||
public DateTimeOffset DateTime { get; set; }
|
||||
|
||||
public double Distance { get; set; }
|
||||
|
||||
public double Amount { get; set; }
|
||||
|
||||
public bool IgnoreInCalculation { get; set; }
|
||||
|
||||
public CarId CarId { get; set; }
|
||||
|
||||
public virtual Car Car { get; set; } = null!;
|
||||
}
|
||||
|
||||
public class ConsumptionTableConfiguration : IEntityTypeConfiguration<Consumption>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Consumption> builder)
|
||||
{
|
||||
builder.HasKey(x => x.Id);
|
||||
|
||||
builder.Property(x => x.Id)
|
||||
.HasConversion<ConsumptionId.EfCoreValueConverter>();
|
||||
|
||||
builder.Property(x => x.DateTime)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.Distance)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.Amount)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.IgnoreInCalculation)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.CarId)
|
||||
.IsRequired()
|
||||
.HasConversion<CarId.EfCoreValueConverter>();
|
||||
|
||||
builder.HasOne(x => x.Car)
|
||||
.WithMany(x => x.Consumptions);
|
||||
}
|
||||
}
|
||||
7
src/Vegasco.Server.Api/Consumptions/ConsumptionId.cs
Normal file
7
src/Vegasco.Server.Api/Consumptions/ConsumptionId.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
using StronglyTypedIds;
|
||||
|
||||
namespace Vegasco.Server.Api.Consumptions;
|
||||
|
||||
|
||||
[StronglyTypedId]
|
||||
public partial struct ConsumptionId;
|
||||
74
src/Vegasco.Server.Api/Consumptions/CreateConsumption.cs
Normal file
74
src/Vegasco.Server.Api/Consumptions/CreateConsumption.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using Vegasco.Server.Api.Cars;
|
||||
using Vegasco.Server.Api.Common;
|
||||
using Vegasco.Server.Api.Persistence;
|
||||
|
||||
namespace Vegasco.Server.Api.Consumptions;
|
||||
|
||||
public static class CreateConsumption
|
||||
{
|
||||
public record Request(DateTimeOffset DateTime, double Distance, double Amount, bool IgnoreInCalculation, Guid CarId);
|
||||
|
||||
public record Response(Guid Id, DateTimeOffset DateTime, double Distance, double Amount, bool IgnoreInCalculation, Guid CarId);
|
||||
|
||||
public static RouteHandlerBuilder MapEndpoint(IEndpointRouteBuilder builder)
|
||||
{
|
||||
return builder
|
||||
.MapPost("consumptions", Endpoint)
|
||||
.WithTags("Consumptions");
|
||||
}
|
||||
|
||||
public class Validator : AbstractValidator<Request>
|
||||
{
|
||||
public Validator(TimeProvider timeProvider)
|
||||
{
|
||||
RuleFor(x => x.DateTime.ToUniversalTime())
|
||||
.LessThanOrEqualTo(timeProvider.GetUtcNow())
|
||||
.WithName(nameof(Request.DateTime));
|
||||
|
||||
RuleFor(x => x.Distance)
|
||||
.GreaterThan(0);
|
||||
|
||||
RuleFor(x => x.Amount)
|
||||
.GreaterThan(0);
|
||||
|
||||
RuleFor(x => x.CarId)
|
||||
.NotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<IResult> Endpoint(
|
||||
ApplicationDbContext dbContext,
|
||||
Request request,
|
||||
IEnumerable<IValidator<Request>> validators,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
List<ValidationResult> failedValidations = await validators.ValidateAllAsync(request, cancellationToken);
|
||||
if (failedValidations.Count > 0)
|
||||
{
|
||||
return TypedResults.BadRequest(new HttpValidationProblemDetails(failedValidations.ToCombinedDictionary()));
|
||||
}
|
||||
|
||||
Car? car = await dbContext.Cars.FindAsync([new CarId(request.CarId)], cancellationToken);
|
||||
if (car is null)
|
||||
{
|
||||
return TypedResults.NotFound();
|
||||
}
|
||||
|
||||
var consumption = new Consumption
|
||||
{
|
||||
DateTime = request.DateTime.ToUniversalTime(),
|
||||
Distance = request.Distance,
|
||||
Amount = request.Amount,
|
||||
IgnoreInCalculation = request.IgnoreInCalculation,
|
||||
CarId = new CarId(request.CarId)
|
||||
};
|
||||
|
||||
dbContext.Consumptions.Add(consumption);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return TypedResults.Created($"consumptions/{consumption.Id.Value}",
|
||||
new Response(consumption.Id.Value, consumption.DateTime, consumption.Distance, consumption.Amount, consumption.IgnoreInCalculation, consumption.CarId.Value));
|
||||
}
|
||||
}
|
||||
30
src/Vegasco.Server.Api/Consumptions/DeleteConsumptions.cs
Normal file
30
src/Vegasco.Server.Api/Consumptions/DeleteConsumptions.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Vegasco.Server.Api.Persistence;
|
||||
|
||||
namespace Vegasco.Server.Api.Consumptions;
|
||||
|
||||
public static class DeleteConsumption
|
||||
{
|
||||
public static RouteHandlerBuilder MapEndpoint(IEndpointRouteBuilder builder)
|
||||
{
|
||||
return builder
|
||||
.MapDelete("consumptions/{id:guid}", Endpoint)
|
||||
.WithTags("Consumptions");
|
||||
}
|
||||
|
||||
private static async Task<IResult> Endpoint(
|
||||
ApplicationDbContext dbContext,
|
||||
Guid id,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Consumption? consumption = await dbContext.Consumptions.FindAsync([new ConsumptionId(id)], cancellationToken);
|
||||
if (consumption is null)
|
||||
{
|
||||
return TypedResults.NotFound();
|
||||
}
|
||||
|
||||
dbContext.Consumptions.Remove(consumption);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return TypedResults.NoContent();
|
||||
}
|
||||
}
|
||||
32
src/Vegasco.Server.Api/Consumptions/GetConsumption.cs
Normal file
32
src/Vegasco.Server.Api/Consumptions/GetConsumption.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Vegasco.Server.Api.Persistence;
|
||||
|
||||
namespace Vegasco.Server.Api.Consumptions;
|
||||
|
||||
public static class GetConsumption
|
||||
{
|
||||
public record Response(Guid Id, DateTimeOffset DateTime, double Distance, double Amount, bool IgnoreInCalculation, Guid CarId);
|
||||
|
||||
public static RouteHandlerBuilder MapEndpoint(IEndpointRouteBuilder builder)
|
||||
{
|
||||
return builder
|
||||
.MapGet("consumptions/{id:guid}", Endpoint)
|
||||
.WithTags("Consumptions");
|
||||
}
|
||||
|
||||
private static async Task<IResult> Endpoint(
|
||||
ApplicationDbContext dbContext,
|
||||
Guid id,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Consumption? consumption = await dbContext.Consumptions.FindAsync([new ConsumptionId(id)], cancellationToken);
|
||||
|
||||
if (consumption is null)
|
||||
{
|
||||
return TypedResults.NotFound();
|
||||
}
|
||||
|
||||
var response = new Response(consumption.Id.Value, consumption.DateTime, consumption.Distance,
|
||||
consumption.Amount, consumption.IgnoreInCalculation, consumption.CarId.Value);
|
||||
return TypedResults.Ok(response);
|
||||
}
|
||||
}
|
||||
53
src/Vegasco.Server.Api/Consumptions/GetConsumptions.cs
Normal file
53
src/Vegasco.Server.Api/Consumptions/GetConsumptions.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
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,
|
||||
bool IgnoreInCalculation,
|
||||
Guid CarId);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
private static async Task<Ok<ApiResponse>> Endpoint(
|
||||
[AsParameters] Request request,
|
||||
ApplicationDbContext dbContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
List<ResponseDto> consumptions = await dbContext.Consumptions
|
||||
.Select(x =>
|
||||
new ResponseDto(x.Id.Value, x.DateTime, x.Distance, x.Amount, x.IgnoreInCalculation, x.CarId.Value))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
var apiResponse = new ApiResponse
|
||||
{
|
||||
Consumptions = consumptions
|
||||
};
|
||||
return TypedResults.Ok(apiResponse);
|
||||
}
|
||||
}
|
||||
65
src/Vegasco.Server.Api/Consumptions/UpdateConsumption.cs
Normal file
65
src/Vegasco.Server.Api/Consumptions/UpdateConsumption.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using Vegasco.Server.Api.Common;
|
||||
using Vegasco.Server.Api.Persistence;
|
||||
|
||||
namespace Vegasco.Server.Api.Consumptions;
|
||||
|
||||
public static class UpdateConsumption
|
||||
{
|
||||
public record Request(DateTimeOffset DateTime, double Distance, double Amount, bool IgnoreInCalculation);
|
||||
|
||||
public record Response(Guid Id, DateTimeOffset DateTime, double Distance, double Amount, bool IgnoreInCalculation, Guid CarId);
|
||||
|
||||
public static RouteHandlerBuilder MapEndpoint(IEndpointRouteBuilder builder)
|
||||
{
|
||||
return builder
|
||||
.MapPut("consumptions/{id:guid}", Endpoint)
|
||||
.WithTags("Consumptions");
|
||||
}
|
||||
|
||||
public class Validator : AbstractValidator<Request>
|
||||
{
|
||||
public Validator(TimeProvider timeProvider)
|
||||
{
|
||||
RuleFor(x => x.DateTime.ToUniversalTime())
|
||||
.LessThanOrEqualTo(timeProvider.GetUtcNow())
|
||||
.WithName(nameof(Request.DateTime));
|
||||
|
||||
RuleFor(x => x.Distance)
|
||||
.GreaterThan(0);
|
||||
|
||||
RuleFor(x => x.Amount)
|
||||
.GreaterThan(0);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<IResult> Endpoint(
|
||||
ApplicationDbContext dbContext,
|
||||
Guid id,
|
||||
Request request,
|
||||
IEnumerable<IValidator<Request>> validators,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
List<ValidationResult> failedValidations = await validators.ValidateAllAsync(request, cancellationToken);
|
||||
if (failedValidations.Count > 0)
|
||||
{
|
||||
return TypedResults.BadRequest(new HttpValidationProblemDetails(failedValidations.ToCombinedDictionary()));
|
||||
}
|
||||
|
||||
Consumption? consumption = await dbContext.Consumptions.FindAsync([new ConsumptionId(id)], cancellationToken);
|
||||
if (consumption is null)
|
||||
{
|
||||
return TypedResults.NotFound();
|
||||
}
|
||||
|
||||
consumption.DateTime = request.DateTime.ToUniversalTime();
|
||||
consumption.Distance = request.Distance;
|
||||
consumption.Amount = request.Amount;
|
||||
consumption.IgnoreInCalculation = request.IgnoreInCalculation;
|
||||
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return TypedResults.Ok(new Response(consumption.Id.Value, consumption.DateTime, consumption.Distance, consumption.Amount, consumption.IgnoreInCalculation, consumption.CarId.Value));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user