Files
SIFINANCE/SIFinance.Modules.Finance/Endpoints/AvoirsEndpoints.cs
T
2026-09-11 14:55:41 +02:00

79 lines
3.1 KiB
C#

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using SIFinance.Modules.Finance.Dtos;
using SIFinance.Shared;
using SIFinance.Shared.Entities;
namespace SIFinance.Modules.Finance.Endpoints;
public static class AvoirsEndpoints
{
public static IEndpointRouteBuilder MapAvoirsEndpoints(this IEndpointRouteBuilder app)
{
var group = app.MapGroup("/api/avoirs").WithTags("Avoirs").RequireAuthorization();
group.MapGet("", async (SIFinanceDbContext db, CancellationToken ct) =>
// Projection directe en DTO : EF ne récupère que les colonnes utiles et
// ne remonte qu'une seule affectation, au lieu de charger toute la collection.
await db.Avoirs
.AsNoTracking()
.OrderByDescending(a => a.DateCreation)
.Select(a => new AvoirDto(
a.Id,
a.NumeroAvoir,
a.FournisseurId,
a.Fournisseur.RaisonSociale,
a.MontantInitial,
a.SoldeDisponible,
a.DateAvoir,
a.AffectationsAvoirs.Select(af => (int?)af.FactureId).FirstOrDefault(),
a.AffectationsAvoirs.Select(af => af.Facture.NumeroFacture).FirstOrDefault()))
.ToListAsync(ct));
group.MapPost("", async (CreateAvoirDto input, SIFinanceDbContext db, CurrentUserService currentUser, CancellationToken ct) =>
{
if (string.IsNullOrWhiteSpace(input.Numero))
return Results.BadRequest(new { error = "Le numéro d'avoir est requis." });
if (input.Montant <= 0)
return Results.BadRequest(new { error = "Le montant doit être supérieur à 0." });
var avoir = new Avoir
{
FournisseurId = input.FournisseurId,
NumeroAvoir = input.Numero.Trim(),
DateAvoir = input.Date,
MontantInitial = input.Montant,
SoldeDisponible = input.Montant,
SaisieParId = await currentUser.GetOrCreateCurrentUserIdAsync(ct),
DateCreation = DateTime.UtcNow,
};
db.Avoirs.Add(avoir);
try
{
await db.SaveChangesAsync(ct);
}
catch (DbUpdateException ex)
{
return Results.BadRequest(new { error = "Impossible d'enregistrer l'avoir — vérifiez le fournisseur.", detail = ex.InnerException?.Message ?? ex.Message });
}
await db.Entry(avoir).Reference(a => a.Fournisseur).LoadAsync(ct);
return Results.Created($"/api/avoirs/{avoir.Id}", ToDto(avoir));
});
return app;
}
private static AvoirDto ToDto(Avoir a)
{
var affectation = a.AffectationsAvoirs.FirstOrDefault();
return new AvoirDto(
a.Id, a.NumeroAvoir, a.FournisseurId, a.Fournisseur.RaisonSociale,
a.MontantInitial, a.SoldeDisponible, a.DateAvoir,
affectation?.FactureId, affectation?.Facture.NumeroFacture);
}
}