mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 06:03:12 +00:00
222 lines
9.2 KiB
C#
222 lines
9.2 KiB
C#
using Data.SeaHavenIndustries;
|
|
using Data.SeaHavenIndustries.Enums;
|
|
using Microsoft.EntityFrameworkCore;
|
|
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<WorkOrderBoardQueryResult> 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 && !IsTerminalExpression(w));
|
|
|
|
var scheduledTotal = await scheduledBase.CountAsync();
|
|
|
|
if (!string.IsNullOrWhiteSpace(query.Search))
|
|
{
|
|
scheduledBase = ApplySearchFilter(scheduledBase, query.Search);
|
|
unscheduledBase = ApplySearchFilter(unscheduledBase, query.Search);
|
|
}
|
|
|
|
var scheduledRows = await ProjectRows(scheduledBase, isUnscheduled: false);
|
|
var unscheduledRows = await ProjectRows(unscheduledBase, isUnscheduled: true);
|
|
|
|
return new WorkOrderBoardQueryResult(scheduledRows, unscheduledRows, scheduledTotal);
|
|
}
|
|
|
|
public async Task<IReadOnlyList<DispatcherLookupRow>> 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();
|
|
}
|
|
|
|
private static IQueryable<WorkOrder> ApplyDispatcherFilter(IQueryable<WorkOrder> 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<WorkOrder> ApplyTypeFilter(IQueryable<WorkOrder> 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<WorkOrder> ApplySearchFilter(IQueryable<WorkOrder> 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));
|
|
}
|
|
|
|
private static System.Linq.Expressions.Expression<Func<WorkOrder, bool>> IsTerminalExpression(WorkOrder w)
|
|
=> w => w.LifecycleStatus == LifecycleStatus.Complete
|
|
|| w.LifecycleStatus == LifecycleStatus.Canceled
|
|
|| w.LifecycleStatus == LifecycleStatus.Closed;
|
|
|
|
private async Task<IReadOnlyList<WorkOrderBoardRawRow>> ProjectRows(
|
|
IQueryable<WorkOrder> query,
|
|
bool isUnscheduled)
|
|
{
|
|
var rows = await query
|
|
.Include(w => w.AssignToUser)
|
|
.Include(w => w.Locations)
|
|
.Include(w => w.PrimaryDispatch!)
|
|
.ThenInclude(d => d!.Vendor)
|
|
.Include(w => w.WorkOrderContacts!)
|
|
.ThenInclude(c => c.POC)
|
|
.OrderBy(w => w.ScheduledDate)
|
|
.ThenBy(w => w.InternalWONumber)
|
|
.Select(w => new
|
|
{
|
|
w.Id,
|
|
w.InternalWONumber,
|
|
w.RescheduleCount,
|
|
w.CarriedOver,
|
|
w.WorkOrderType,
|
|
w.SiteCode,
|
|
LocationName = w.Locations != null ? w.Locations.Name : null,
|
|
Poc = w.WorkOrderContacts!
|
|
.OrderBy(c => c.Id)
|
|
.Select(c => new
|
|
{
|
|
Name = c.POC != null
|
|
? ((c.POC.FirstName ?? "") + " " + (c.POC.LastName ?? "")).Trim()
|
|
: null,
|
|
c.POC!.PhoneNumber,
|
|
c.Notes
|
|
})
|
|
.FirstOrDefault(),
|
|
w.LifecycleStatus,
|
|
w.LegacyStatus,
|
|
w.Status,
|
|
w.AssignTo,
|
|
w.AssignToUser!.FirstName,
|
|
w.AssignToUser!.LastName,
|
|
w.AssignToUser!.Initials,
|
|
w.AssignToUser!.Color,
|
|
w.DueDate,
|
|
w.ScheduledDate,
|
|
w.ScheduledStart,
|
|
w.ScheduledEnd,
|
|
w.TargetWeek,
|
|
w.ScheduleWeekOnly,
|
|
VendorId = w.PrimaryDispatch != null ? (int?)w.PrimaryDispatch.VendorId : null,
|
|
VendorName = w.PrimaryDispatch != null && w.PrimaryDispatch.Vendor != null
|
|
? w.PrimaryDispatch.Vendor.CompanyName
|
|
: null,
|
|
TechName = w.PrimaryDispatch != null && w.PrimaryDispatch.Vendor != null
|
|
? w.PrimaryDispatch.Vendor.ContactName
|
|
: null,
|
|
TechPhone = w.PrimaryDispatch != null && w.PrimaryDispatch.Vendor != null
|
|
? w.PrimaryDispatch.Vendor.Phone
|
|
: null,
|
|
DispatchApptDate = w.PrimaryDispatch != null ? w.PrimaryDispatch.ScheduledDate : null,
|
|
w.Trade,
|
|
w.Problem,
|
|
w.DocStatus,
|
|
w.RowVersion
|
|
})
|
|
.ToListAsync();
|
|
|
|
return rows.Select(w => new WorkOrderBoardRawRow(
|
|
w.Id,
|
|
w.InternalWONumber,
|
|
w.RescheduleCount,
|
|
w.CarriedOver,
|
|
w.WorkOrderType,
|
|
w.SiteCode,
|
|
w.LocationName,
|
|
w.Poc?.Name,
|
|
w.Poc?.PhoneNumber,
|
|
w.Poc?.Notes,
|
|
w.LifecycleStatus,
|
|
w.LegacyStatus ?? w.Status,
|
|
w.AssignTo,
|
|
w.FirstName,
|
|
w.LastName,
|
|
w.Initials,
|
|
w.Color,
|
|
w.DueDate,
|
|
w.ScheduledDate,
|
|
w.ScheduledStart,
|
|
w.ScheduledEnd,
|
|
w.TargetWeek,
|
|
w.ScheduleWeekOnly,
|
|
w.VendorId,
|
|
w.VendorName,
|
|
w.TechName,
|
|
w.TechPhone,
|
|
w.DispatchApptDate,
|
|
w.Trade ?? w.Problem,
|
|
w.Problem,
|
|
w.DocStatus,
|
|
w.RowVersion,
|
|
isUnscheduled)).ToList();
|
|
}
|
|
}
|
|
}
|