Added endpoints to update verspakketten and add beoordeling. Added some validations and other tweaks
This commit is contained in:
@@ -6,6 +6,8 @@ public interface ILutraDbContext
|
||||
{
|
||||
DbSet<Supermarkt> Supermarkten { get; }
|
||||
|
||||
DbSet<Beoordeling> Beoordelingen { get; }
|
||||
|
||||
DbSet<Verspakket> Verspaketten { get; }
|
||||
|
||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
|
||||
|
||||
@@ -10,6 +10,12 @@ namespace Lutra.Application.Models.Verspakketten
|
||||
|
||||
public int? PrijsInCenten { get; init; }
|
||||
|
||||
public int AantalPersonen { get; init; }
|
||||
|
||||
public double? AverageCijferSmaak { get; init; }
|
||||
|
||||
public double? AverageCijferBereiden { get; init; }
|
||||
|
||||
public Beoordeling[]? Beoordelingen { get; init; }
|
||||
|
||||
public Supermarkt? Supermarkt { get; init; }
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using Cortex.Mediator.Commands;
|
||||
|
||||
namespace Lutra.Application.Verspakketten;
|
||||
|
||||
public sealed partial class AddBeoordeling
|
||||
{
|
||||
public sealed record Command(
|
||||
Guid VerspakketId,
|
||||
int CijferSmaak,
|
||||
int CijferBereiden,
|
||||
bool Aanbevolen,
|
||||
string? Tekst) : ICommand<Response>;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Cortex.Mediator.Commands;
|
||||
using Lutra.Application.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Lutra.Application.Verspakketten;
|
||||
|
||||
public sealed partial class AddBeoordeling
|
||||
{
|
||||
public sealed class Handler(ILutraDbContext context) : ICommandHandler<Command, Response>
|
||||
{
|
||||
public async Task<Response> Handle(Command request, CancellationToken cancellationToken)
|
||||
{
|
||||
var verspakketExists = await context.Verspaketten
|
||||
.AsNoTracking()
|
||||
.AnyAsync(v => v.Id == request.VerspakketId && v.DeletedAt == null, cancellationToken);
|
||||
|
||||
if (!verspakketExists)
|
||||
{
|
||||
throw new InvalidOperationException($"Verspakket with id '{request.VerspakketId}' was not found.");
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var beoordeling = new Domain.Entities.Beoordeling
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
CijferSmaak = request.CijferSmaak,
|
||||
CijferBereiden = request.CijferBereiden,
|
||||
Aanbevolen = request.Aanbevolen,
|
||||
Tekst = request.Tekst,
|
||||
VerspakketId = request.VerspakketId,
|
||||
CreatedAt = now,
|
||||
ModifiedAt = now
|
||||
};
|
||||
|
||||
await context.Beoordelingen.AddAsync(beoordeling, cancellationToken);
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new Response { Id = beoordeling.Id };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Lutra.Application.Verspakketten;
|
||||
|
||||
public sealed partial class AddBeoordeling
|
||||
{
|
||||
public sealed class Response
|
||||
{
|
||||
public required Guid Id { get; set; }
|
||||
}
|
||||
}
|
||||
3
Lutra/Lutra.Application/Verspakketten/AddBeoordeling.cs
Normal file
3
Lutra/Lutra.Application/Verspakketten/AddBeoordeling.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace Lutra.Application.Verspakketten;
|
||||
|
||||
public sealed partial class AddBeoordeling { }
|
||||
@@ -1,4 +1,5 @@
|
||||
using Cortex.Mediator.Commands;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Lutra.Application.Verspakketten;
|
||||
|
||||
@@ -7,6 +8,6 @@ public sealed partial class CreateVerspakket
|
||||
public sealed record Command(
|
||||
string Naam,
|
||||
int? PrijsInCenten,
|
||||
int AantalPersonen,
|
||||
[Range(1, 10)] int AantalPersonen,
|
||||
Guid SupermarktId) : ICommand<Response>;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ namespace Lutra.Application.Verspakketten
|
||||
Id = v.Id,
|
||||
Naam = v.Naam,
|
||||
PrijsInCenten = v.PrijsInCenten,
|
||||
AantalPersonen = v.AantalPersonen,
|
||||
AverageCijferSmaak = v.Beoordelingen.Any() ? v.Beoordelingen.Average(b => (double)b.CijferSmaak) : null,
|
||||
AverageCijferBereiden = v.Beoordelingen.Any() ? v.Beoordelingen.Average(b => (double)b.CijferBereiden) : null,
|
||||
Beoordelingen = v.Beoordelingen
|
||||
.Select(b => new Beoordeling
|
||||
{
|
||||
|
||||
@@ -45,6 +45,9 @@ namespace Lutra.Application.Verspakketten
|
||||
Id = v.Id,
|
||||
Naam = v.Naam,
|
||||
PrijsInCenten = v.PrijsInCenten,
|
||||
AantalPersonen = v.AantalPersonen,
|
||||
AverageCijferSmaak = v.Beoordelingen.Any() ? v.Beoordelingen.Average(b => (double)b.CijferSmaak) : null,
|
||||
AverageCijferBereiden = v.Beoordelingen.Any() ? v.Beoordelingen.Average(b => (double)b.CijferBereiden) : null,
|
||||
Beoordelingen = v.Beoordelingen
|
||||
.Select(b => new Beoordeling
|
||||
{
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using Cortex.Mediator.Commands;
|
||||
|
||||
namespace Lutra.Application.Verspakketten;
|
||||
|
||||
public sealed partial class UpdateVerspakket
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates an existing verspakket.
|
||||
/// </summary>
|
||||
public sealed record Command(Guid Id, string Naam, int PrijsInCenten, int AantalPersonen, Guid SupermarktId) : ICommand<Response>;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Cortex.Mediator.Commands;
|
||||
using Lutra.Application.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Lutra.Application.Verspakketten;
|
||||
|
||||
public sealed partial class UpdateVerspakket
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles update requests for verspakketten.
|
||||
/// </summary>
|
||||
public sealed class Handler(ILutraDbContext context) : ICommandHandler<Command, Response>
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates an existing verspakket.
|
||||
/// </summary>
|
||||
/// <param name="request">The update command.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>An empty response.</returns>
|
||||
public async Task<Response> Handle(Command request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(request.Naam))
|
||||
throw new ArgumentException("Naam mag niet leeg zijn.", nameof(request.Naam));
|
||||
|
||||
if (request.Naam.Length > 50)
|
||||
throw new ArgumentException("Naam mag maximaal 50 tekens bevatten.", nameof(request.Naam));
|
||||
|
||||
if (request.PrijsInCenten < 0)
|
||||
throw new ArgumentException("PrijsInCenten mag niet negatief zijn.", nameof(request.PrijsInCenten));
|
||||
|
||||
if (request.AantalPersonen is < 1 or > 10)
|
||||
throw new ArgumentException("AantalPersonen moet tussen 1 en 10 liggen.", nameof(request.AantalPersonen));
|
||||
|
||||
var verspakket = await context.Verspaketten
|
||||
.FirstOrDefaultAsync(v => v.Id == request.Id && v.DeletedAt == null, cancellationToken);
|
||||
|
||||
if (verspakket is null)
|
||||
{
|
||||
throw new InvalidOperationException($"Verspakket with id '{request.Id}' was not found.");
|
||||
}
|
||||
|
||||
var supermarktExists = await context.Supermarkten
|
||||
.AsNoTracking()
|
||||
.AnyAsync(s => s.Id == request.SupermarktId && s.DeletedAt == null, cancellationToken);
|
||||
|
||||
if (!supermarktExists)
|
||||
{
|
||||
throw new InvalidOperationException($"Supermarkt with id '{request.SupermarktId}' was not found.");
|
||||
}
|
||||
|
||||
verspakket.Naam = request.Naam;
|
||||
verspakket.PrijsInCenten = request.PrijsInCenten;
|
||||
verspakket.AantalPersonen = request.AantalPersonen;
|
||||
verspakket.SupermarktId = request.SupermarktId;
|
||||
verspakket.ModifiedAt = DateTime.UtcNow;
|
||||
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new Response();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Lutra.Application.Verspakketten;
|
||||
|
||||
public sealed partial class UpdateVerspakket
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the result of an update verspakket operation.
|
||||
/// </summary>
|
||||
public sealed record Response;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Lutra.Application.Verspakketten;
|
||||
|
||||
public sealed partial class UpdateVerspakket;
|
||||
Reference in New Issue
Block a user