using Data.SeaHavenIndustries; using Microsoft.EntityFrameworkCore; using SeaHaven.DataServices.Interfaces; using SeaHaven.DataServices.Models; namespace SeaHaven.DataServices.Implementation { public class QuotesDataService : IQuotesDataService { private readonly ApplicationDbContext _context; public QuotesDataService(ApplicationDbContext context) { _context = context; } public async Task GetByIdAsync(int id) { return await _context.Quotes.FindAsync(id); } public async Task> GetAllAsync() { return await _context.Quotes.ToListAsync(); } public async Task> GetByWorkOrderIdAsync(int workOrderId) { return await _context.Quotes .Where(q => q.WorkorderId == workOrderId) .ToListAsync(); } public async Task AddAsync(Quotes quote) { await _context.Quotes.AddAsync(quote); await _context.SaveChangesAsync(); return quote; } public async Task UpdateAsync(Quotes quote) { _context.Quotes.Update(quote); await _context.SaveChangesAsync(); } public async Task DeleteAsync(int id) { var entity = await GetByIdAsync(id); if (entity != null) { _context.Quotes.Remove(entity); await _context.SaveChangesAsync(); } } public async Task ExistsAsync(int id) { return await _context.Quotes.AnyAsync(q => q.Id == id); } public async Task UnlinkFromWorkOrderAsync(int workOrderId) { var quotes = await _context.Quotes .Where(q => q.WorkorderId == workOrderId) .ToListAsync(); foreach (var quote in quotes) { quote.WorkorderId = null; } await _context.SaveChangesAsync(); } public async Task<(IReadOnlyList Items, int TotalCount)> GetQuotesPagedAsync( int page, int pageSize, string search, CancellationToken cancellationToken) { var normalizedSearch = search.Trim(); var query = _context.Quotes .AsNoTracking() .Where(w => normalizedSearch.Length == 0 || (w.QuotId != null && w.QuotId.Contains(normalizedSearch)) || (w.SiteName != null && w.SiteName.Contains(normalizedSearch)) || (w.WorkOrder != null && w.WorkOrder.WorkerOrderTitle != null && w.WorkOrder.WorkerOrderTitle.Contains(normalizedSearch))); var totalCount = await query.CountAsync(cancellationToken); var data = await query .OrderByDescending(s => s.Id) .Skip((page - 1) * pageSize) .Take(pageSize) .Select(s => new QuoteListItemReadModel { Id = s.Id, QuoteId = "QO-" + s.QuotId, WorkOrder = s.WorkOrder != null ? s.WorkOrder.WorkerOrderNumber : "", ProjectName = s.ProjectName, TotalAmount = s.LineItems!.Sum(l => l.Lineitem ?? 0), SiteName = s.SiteName, SiteId = s.SiteId, PO = s.PO, TT = s.TT, BillingAddress = s.BillingAddress, Status = s.Status, ContactId = s.ContactId, Date = s.Date, Lineitems = s.LineItems!.Select(q => new QuoteLineItemReadModel { Descriptions = q.Descriptions, Lineitem = q.Lineitem, LineitemNumber = q.LineitemNumber }).ToList(), }) .ToListAsync(cancellationToken); return (data, totalCount); } public async Task GetQuoteDetailsByIdAsync( int id, CancellationToken cancellationToken) { return await _context.Quotes .Where(s => s.Id == id) .AsNoTracking() .Select(s => new QuoteDetailReadModel { Id = s.Id, QuotId = s.QuotId, Date = s.Date, Name = s.Contacts != null ? (s.Contacts.FirstName + " " + s.Contacts.LastName).Trim() : "", PO = s.PO, TT = s.TT, SiteName = s.SiteName, ProjectName = s.ProjectName, SiteId = s.SiteId, BillingAddress = s.BillingAddress, ShippingAddress = s.ShippingAddress, Lineitems = s.LineItems!.Select(q => new QuoteLineItemReadModel { Descriptions = q.Descriptions, Lineitem = q.Lineitem }).ToList(), TotalAmount = s.LineItems!.Sum(l => l.Lineitem ?? 0) }) .FirstOrDefaultAsync(cancellationToken); } public async Task> GetWorkOrderQuoteDetailsAsync( int woId, CancellationToken cancellationToken) { return await _context.workOrders .AsNoTracking() .Where(w => w.Id == woId) .Select(s => new WorkOrderQuoteDetailReadModel { Id = s.Id, PO = s.PO, TT = s.TT, Title = s.Locations != null ? s.Locations.Title : "", Name = s.Locations != null ? s.Locations.Name : "" }) .ToListAsync(cancellationToken); } public async Task DeleteLineItemsByQuoteIdAsync(int quoteId, CancellationToken cancellationToken) { var items = await _context.QuotesLines .Where(w => w.QuoteId == quoteId) .ToListAsync(cancellationToken); if (items.Any()) { _context.QuotesLines.RemoveRange(items); await _context.SaveChangesAsync(cancellationToken); } } } }