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:
@@ -1,5 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PowderCoating.Core.Entities;
|
||||
using PowderCoating.Core.Enums;
|
||||
using PowderCoating.Core.Interfaces.Repositories;
|
||||
using PowderCoating.Infrastructure.Data;
|
||||
|
||||
@@ -37,4 +38,55 @@ public class BillRepository : Repository<Bill>, IBillRepository
|
||||
.Include(b => b.LineItems.Where(li => !li.IsDeleted))
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<Bill>> GetForIndexAsync(string? statusFilter, string? searchTerm, decimal? searchAmount)
|
||||
{
|
||||
var query = _context.Bills
|
||||
.Include(b => b.Vendor)
|
||||
.Include(b => b.LineItems.Where(li => !li.IsDeleted))
|
||||
.Where(b => !b.IsDeleted);
|
||||
|
||||
if (statusFilter == "Unpaid")
|
||||
query = query.Where(b => b.Status == BillStatus.Open || b.Status == BillStatus.PartiallyPaid);
|
||||
else if (statusFilter == "Overdue")
|
||||
query = query.Where(b => b.Status != BillStatus.Paid && b.Status != BillStatus.Voided &&
|
||||
b.DueDate.HasValue && b.DueDate.Value.Date < DateTime.Today);
|
||||
|
||||
if (!string.IsNullOrEmpty(searchTerm))
|
||||
{
|
||||
var term = searchTerm;
|
||||
query = query.Where(b =>
|
||||
b.BillNumber.Contains(term) ||
|
||||
b.Vendor.CompanyName.Contains(term) ||
|
||||
(b.VendorInvoiceNumber != null && b.VendorInvoiceNumber.Contains(term)) ||
|
||||
(b.Memo != null && b.Memo.Contains(term)) ||
|
||||
b.LineItems.Any(li => li.Description.Contains(term)) ||
|
||||
(searchAmount.HasValue && (b.Total == searchAmount.Value || b.AmountPaid == searchAmount.Value)));
|
||||
}
|
||||
|
||||
return await query.OrderByDescending(b => b.BillDate).ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<string?> GetLastBillNumberAsync(string prefix)
|
||||
{
|
||||
return await _context.Bills
|
||||
.IgnoreQueryFilters()
|
||||
.Where(b => b.BillNumber.StartsWith(prefix))
|
||||
.OrderByDescending(b => b.BillNumber)
|
||||
.Select(b => b.BillNumber)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<string?> GetLastPaymentNumberAsync(string prefix)
|
||||
{
|
||||
return await _context.BillPayments
|
||||
.IgnoreQueryFilters()
|
||||
.Where(p => p.PaymentNumber.StartsWith(prefix))
|
||||
.OrderByDescending(p => p.PaymentNumber)
|
||||
.Select(p => p.PaymentNumber)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user