using Distribution.Infra.UoW; using Distribution.Models; namespace Distribution.Features.Claims; public class ClaimService(IClaimRepository repo, IUnitOfWork uow) { private static ClaimResponse Map(Claim c) => new(c.Id, c.FK_AgencyUserId, c.Details, c.Status, c.SettlementAmount, c.SettledAt, c.IsActive, c.CreatedAt); public async Task GetByIdAsync(Guid id) { var c = await repo.GetByIdAsync(id); if (c is null || !c.IsActive) return null; return Map(c); } public async Task> GetAllAsync() => (await repo.GetAllAsync()).Select(Map).ToList(); public async Task> GetByAgencyUserIdAsync(Guid agencyUserId) => (await repo.GetByAgencyUserIdAsync(agencyUserId)).Select(Map).ToList(); public async Task CreateAsync(CreateClaimRequest request, CancellationToken ct = default) { if (string.IsNullOrWhiteSpace(request.Details)) throw new InvalidOperationException("Claim details are required."); var claim = new Claim { FK_AgencyUserId = request.AgencyUserId, Details = request.Details }; await uow.BeginAsync(ct); try { await repo.AddAsync(claim); await uow.CommitAsync(ct); } catch { await uow.RollbackAsync(ct); throw; } return Map(claim); } public async Task UpdateAsync(Guid id, UpdateClaimRequest request, CancellationToken ct = default) { var claim = await repo.GetByIdAsync(id); if (claim is null || !claim.IsActive) throw new InvalidOperationException("Claim not found."); if (claim.Status == ClaimStatus.Settled) throw new InvalidOperationException("Cannot edit a claim that has already been settled."); if (string.IsNullOrWhiteSpace(request.Details)) throw new InvalidOperationException("Claim details are required."); claim.FK_AgencyUserId = request.AgencyUserId; claim.Details = request.Details; await uow.BeginAsync(ct); try { repo.Update(claim); await uow.CommitAsync(ct); } catch { await uow.RollbackAsync(ct); throw; } return Map(claim); } public async Task SettleAsync(Guid id, SettleClaimRequest request, Guid approverId, CancellationToken ct = default) { var claim = await repo.GetByIdAsync(id); if (claim is null || !claim.IsActive) throw new KeyNotFoundException("Claim not found."); if (claim.Status == ClaimStatus.Settled) throw new InvalidOperationException("Claim is already settled."); if (request.SettlementAmount < 0) throw new InvalidOperationException("Settlement amount cannot be negative."); claim.Status = ClaimStatus.Settled; claim.SettlementAmount = request.SettlementAmount; claim.SettledByUserId = approverId; claim.SettledAt = DateTime.Now; await uow.BeginAsync(ct); try { repo.Update(claim); await uow.CommitAsync(ct); } catch { await uow.RollbackAsync(ct); throw; } return Map(claim); } }