using GerbilManagerWebAPI.Dtos; using GerbilManagerWebAPI.Models; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.EntityFrameworkCore; namespace GerbilManagerWebAPI.Endpoints { /// /// ERWERB: acquisition data per animal (purchase date/price/note). /// GET /acquisitions?gerbilId=… -> records for one animal (or all), newest date first. /// GET /acquisitions/{id} -> a single record. /// POST /acquisitions -> create, returns 201. /// PUT /acquisitions/{id} -> update, returns 204. /// DELETE /acquisitions/{id} -> delete, returns 204. /// Decoupled from gerbils/contacts (loose nullable Guid columns, no FK), so rows survive /// the import re-ingest wipe (mirrors Feedback). /// public static class AcquisitionEndpoints { public static IEndpointRouteBuilder MapAcquisitionEndpoints(this IEndpointRouteBuilder app) { var group = app.MapGroup("/acquisitions").WithTags("Acquisitions"); group.MapGet("/", async (ApplicationContext db, Guid? gerbilId) => { var rows = await db.AcquisitionRecords.AsNoTracking() .Where(a => gerbilId == null || a.GerbilId == gerbilId) .ToListAsync(); // Order in memory: SQLite (test host) cannot ORDER BY a DateTimeOffset column, // and DateOnly ordering stays consistent across providers this way. return TypedResults.Ok(rows .OrderByDescending(a => a.Date ?? DateOnly.MinValue) .ThenByDescending(a => a.CreatedAt) .Select(ToDto) .ToList()); }); group.MapGet("/{id:guid}", async Task, NotFound>> (Guid id, ApplicationContext db) => { var a = await db.AcquisitionRecords.AsNoTracking().FirstOrDefaultAsync(x => x.Id == id); return a is null ? TypedResults.NotFound() : TypedResults.Ok(ToDto(a)); }); group.MapPost("/", async (AcquisitionInput input, ApplicationContext db) => { var a = new AcquisitionRecord { Id = Guid.NewGuid(), GerbilId = input.GerbilId, SourceContactId = input.SourceContactId, Date = input.Date, Price = input.Price, Note = string.IsNullOrWhiteSpace(input.Note) ? null : input.Note.Trim(), CreatedAt = DateTimeOffset.UtcNow, }; db.AcquisitionRecords.Add(a); await db.SaveChangesAsync(); return TypedResults.Created($"/acquisitions/{a.Id}", ToDto(a)); }); group.MapPut("/{id:guid}", async Task> (Guid id, AcquisitionInput input, ApplicationContext db) => { var a = await db.AcquisitionRecords.FirstOrDefaultAsync(x => x.Id == id); if (a is null) return TypedResults.NotFound(); a.GerbilId = input.GerbilId; a.SourceContactId = input.SourceContactId; a.Date = input.Date; a.Price = input.Price; a.Note = string.IsNullOrWhiteSpace(input.Note) ? null : input.Note.Trim(); await db.SaveChangesAsync(); return TypedResults.NoContent(); }); group.MapDelete("/{id:guid}", async Task> (Guid id, ApplicationContext db) => { var a = await db.AcquisitionRecords.FirstOrDefaultAsync(x => x.Id == id); if (a is null) return TypedResults.NotFound(); db.AcquisitionRecords.Remove(a); await db.SaveChangesAsync(); return TypedResults.NoContent(); }); return app; } private static AcquisitionDto ToDto(AcquisitionRecord a) => new(a.Id, a.GerbilId, a.SourceContactId, a.Date, a.Price, a.Note, a.CreatedAt); } }