diff --git a/src/Purrse.Api/Services/LoanService.cs b/src/Purrse.Api/Services/LoanService.cs index df2bb96..149713b 100644 --- a/src/Purrse.Api/Services/LoanService.cs +++ b/src/Purrse.Api/Services/LoanService.cs @@ -64,13 +64,14 @@ public class LoanService : ILoanService public async Task UpdateLoanDetailAsync(Guid userId, Guid accountId, CreateLoanDetailRequest request) { - var account = await _db.Accounts.Include(a => a.LoanDetail).ThenInclude(l => l!.AmortizationEntries) + var account = await _db.Accounts.Include(a => a.LoanDetail) .FirstOrDefaultAsync(a => a.Id == accountId && a.UserId == userId) ?? throw new KeyNotFoundException("Account not found"); var l = account.LoanDetail ?? throw new KeyNotFoundException("No loan detail found"); - l.AmortizationEntries.Clear(); + // Delete old entries directly in DB, bypassing change tracker + await _db.AmortizationEntries.Where(e => e.LoanDetailId == l.Id).ExecuteDeleteAsync(); l.OriginalBalance = request.OriginalBalance; l.InterestRate = request.InterestRate; @@ -83,7 +84,10 @@ public class LoanService : ILoanService var entries = GenerateAmortizationSchedule(l); foreach (var entry in entries) - l.AmortizationEntries.Add(entry); + { + entry.LoanDetailId = l.Id; + _db.AmortizationEntries.Add(entry); + } await _db.SaveChangesAsync(); var schedule = entries.Select(e => new AmortizationEntryResponse(e.PaymentNumber, e.PaymentDate, e.PaymentAmount, e.PrincipalAmount, e.InterestAmount, e.EscrowAmount, e.RemainingBalance)).ToList();