Phase 2: Eliminate ApplicationDbContext from domain controllers
Migrated InvoicesController, QuotesController, JobsController, BillsController, PurchaseOrdersController, and CustomersController to route all data access through IUnitOfWork typed/generic repositories instead of injecting ApplicationDbContext directly. New typed repositories added: IJobRepository (GetScheduledJobsForDateAsync, GetActiveJobsForMobileAsync, LoadForCostingAsync), INotificationLogRepository (GetLatestForJobAsync, GetAllForJobAsync), IQuoteRepository (GetItemsWithCoatsAsync with CatalogItem eager load + AsNoTracking), and IJobRepository.GetOrphanedConversionJobAsync. All EF complex include chains relocated into repository methods; controllers now call named query methods rather than composing raw IQueryable chains. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -67,4 +67,45 @@ public class QuoteRepository : Repository<Quote>, IQuoteRepository
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<QuoteIndexStats> GetIndexStatsAsync(List<int> openStatusIds, List<int> approvedConvertedStatusIds)
|
||||
{
|
||||
var stats = await _context.Quotes
|
||||
.Where(q => !q.IsDeleted)
|
||||
.Select(q => new { q.QuoteStatusId, q.Total })
|
||||
.ToListAsync();
|
||||
|
||||
return new QuoteIndexStats(
|
||||
OpenCount: stats.Count(q => openStatusIds.Contains(q.QuoteStatusId)),
|
||||
ApprovedConvertedCount: stats.Count(q => approvedConvertedStatusIds.Contains(q.QuoteStatusId)),
|
||||
TotalValue: stats.Sum(q => q.Total));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<QuoteItem>> GetItemsWithCoatsAsync(int quoteId)
|
||||
{
|
||||
return await _context.QuoteItems
|
||||
.Where(qi => qi.QuoteId == quoteId && !qi.IsDeleted)
|
||||
.Include(qi => qi.Coats)
|
||||
.ThenInclude(c => c.InventoryItem)
|
||||
.Include(qi => qi.Coats)
|
||||
.ThenInclude(c => c.Vendor)
|
||||
.Include(qi => qi.CatalogItem)
|
||||
.Include(qi => qi.PrepServices)
|
||||
.ThenInclude(ps => ps.PrepService)
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<string?> GetLastQuoteNumberByPrefixAsync(int companyId, string prefix)
|
||||
{
|
||||
return await _context.Quotes
|
||||
.IgnoreQueryFilters()
|
||||
.Where(q => q.CompanyId == companyId && q.QuoteNumber.StartsWith(prefix))
|
||||
.OrderByDescending(q => q.QuoteNumber)
|
||||
.Select(q => q.QuoteNumber)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user