using Data.SeaHavenIndustries; using Data.SeaHavenIndustries.Enums; using Microsoft.EntityFrameworkCore; using SeaHaven.DataServices.Helpers; using SeaHaven.DataServices.Interfaces; namespace SeaHaven.DataServices.Implementation { public class WorkOrderBoardDataService : IWorkOrderBoardDataService { private readonly ApplicationDbContext _context; public WorkOrderBoardDataService(ApplicationDbContext context) { _context = context; } public async Task GetBoardRowsAsync(WorkOrderBoardQuery query) { var weekStartDate = query.WeekStart.ToDateTime(TimeOnly.MinValue); var weekEndDate = query.WeekEnd.ToDateTime(TimeOnly.MinValue); var baseQuery = _context.workOrders .AsNoTracking() .Where(w => w.istemplate != true && (w.IsDeleted != true || w.IsDeleted == null)); baseQuery = ApplyDispatcherFilter(baseQuery, query); baseQuery = ApplyTypeFilter(baseQuery, query); var scheduledBase = baseQuery.Where(w => (w.ScheduledDate != null && w.ScheduledDate.Value.Date >= weekStartDate.Date && w.ScheduledDate.Value.Date <= weekEndDate.Date) || (w.ScheduleWeekOnly == true && w.TargetWeek == query.WeekStart)); var unscheduledBase = baseQuery.Where(w => w.ScheduledDate == null && w.LifecycleStatus != LifecycleStatus.Completed && w.LifecycleStatus != LifecycleStatus.Canceled); var scheduledTotal = await scheduledBase.CountAsync(); if (!string.IsNullOrWhiteSpace(query.Search)) { scheduledBase = ApplySearchFilter(scheduledBase, query.Search); unscheduledBase = ApplySearchFilter(unscheduledBase, query.Search); } var scheduledRows = await WorkOrderBoardProjection.ProjectRowsAsync(scheduledBase, isUnscheduled: false); var unscheduledRows = await WorkOrderBoardProjection.ProjectRowsAsync(unscheduledBase, isUnscheduled: true); return new WorkOrderBoardQueryResult(scheduledRows, unscheduledRows, scheduledTotal); } public async Task> GetDispatcherLookupsAsync() { return await _context.Users .AsNoTracking() .Where(u => u.IsDeleted != true) .OrderBy(u => u.FirstName) .ThenBy(u => u.LastName) .Select(u => new DispatcherLookupRow( u.Id, u.FirstName ?? "", u.LastName, u.Initials, u.Color)) .ToListAsync(); } public async Task GetBoardRowByIdAsync(int workOrderId) { var query = _context.workOrders .AsNoTracking() .Where(w => w.Id == workOrderId && w.istemplate != true && (w.IsDeleted != true || w.IsDeleted == null)); var rows = await WorkOrderBoardProjection.ProjectRowsAsync(query, isUnscheduled: false); return rows.FirstOrDefault(); } public async Task InternalWoNumberExistsAsync(string normalizedWoNumber, int excludeWorkOrderId) { return await _context.workOrders .AsNoTracking() .AnyAsync(w => w.Id != excludeWorkOrderId && w.istemplate != true && (w.IsDeleted != true || w.IsDeleted == null) && w.InternalWONumber == normalizedWoNumber); } private static IQueryable ApplyDispatcherFilter(IQueryable query, WorkOrderBoardQuery boardQuery) { if (boardQuery.MyWorkOrders && !string.IsNullOrEmpty(boardQuery.CurrentUserId)) return query.Where(w => w.AssignTo == boardQuery.CurrentUserId); if (boardQuery.Dispatchers == null || boardQuery.Dispatchers.Count == 0) return query; var ids = boardQuery.Dispatchers .Where(d => d != "__unassigned__") .ToList(); var includeUnassigned = boardQuery.Dispatchers.Contains("__unassigned__"); if (includeUnassigned && ids.Count == 0) return query.Where(w => w.AssignTo == null || w.AssignTo == ""); if (includeUnassigned && ids.Count > 0) { return query.Where(w => w.AssignTo == null || w.AssignTo == "" || ids.Contains(w.AssignTo)); } return query.Where(w => w.AssignTo != null && ids.Contains(w.AssignTo)); } private static IQueryable ApplyTypeFilter(IQueryable query, WorkOrderBoardQuery boardQuery) { if (boardQuery.Types == null || boardQuery.Types.Count == 0) return query; return query.Where(w => w.WorkOrderType != null && boardQuery.Types.Contains(w.WorkOrderType.Value)); } private static IQueryable ApplySearchFilter(IQueryable query, string search) { var s = search.Trim().ToLower(); return query.Where(w => (w.SiteCode ?? "").ToLower().Contains(s) || (w.InternalWONumber ?? "").ToLower().Contains(s) || (w.WorkerOrderNumber ?? "").ToLower().Contains(s) || (w.Locations != null && (w.Locations.Name ?? "").ToLower().Contains(s)) || (w.AssignToUser != null && ((w.AssignToUser.FirstName ?? "") + " " + (w.AssignToUser.LastName ?? "")).ToLower().Contains(s)) || (w.Trade ?? "").ToLower().Contains(s) || (w.Problem ?? "").ToLower().Contains(s) || (w.PrimaryDispatch != null && w.PrimaryDispatch.Vendor != null && (w.PrimaryDispatch.Vendor.CompanyName ?? "").ToLower().Contains(s)) || (w.Status ?? "").ToLower().Contains(s)); } } }