mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 09:33:13 +00:00
153 lines
6.5 KiB
C#
153 lines
6.5 KiB
C#
using Data.SeaHavenIndustries;
|
|
using Data.SeaHavenIndustries.Enums;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using SeaHaven.DataServices.Helpers;
|
|
using SeaHaven.DataServices.Interfaces;
|
|
|
|
namespace SeaHaven.DataServices.Implementation
|
|
{
|
|
public class DashboardDataService : IDashboardDataService
|
|
{
|
|
private readonly ApplicationDbContext _context;
|
|
|
|
public DashboardDataService(ApplicationDbContext context)
|
|
{
|
|
_context = context;
|
|
}
|
|
|
|
public async Task<DashboardCounts> GetWorkOrderCountsAsync(
|
|
int? accountId,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var query = _context.workOrders.Where(w => w.istemplate != true);
|
|
if (accountId is int scopedAccountId)
|
|
{
|
|
query = query.Where(w => w.AccountId == scopedAccountId);
|
|
}
|
|
|
|
var total = await query.CountAsync(cancellationToken);
|
|
var open = await query.CountAsync(w => w.Status == "Open" || w.Status == "In Progress" || w.Status == "On Hold", cancellationToken);
|
|
var notDispatched = await query.CountAsync(w => (w.Status == "Open") && (w.AssignTo == null || w.AssignTo == ""), cancellationToken);
|
|
var completed = await query.CountAsync(w => w.Status == "Done", cancellationToken);
|
|
|
|
return new DashboardCounts
|
|
{
|
|
Total = total,
|
|
Open = open,
|
|
NotDispatched = notDispatched,
|
|
Completed = completed
|
|
};
|
|
}
|
|
|
|
public async Task<IReadOnlyList<DashboardWorkOrder>> GetDashboardWorkOrdersAsync(
|
|
int? accountId,
|
|
string? dispatcherId,
|
|
DateOnly? dateFrom,
|
|
DateOnly? dateTo,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var query = WorkOrderBoardQueryFilters.ApplyBaseScope(_context.workOrders.AsNoTracking());
|
|
if (accountId is int scopedAccountId)
|
|
query = WorkOrderBoardQueryFilters.ApplyAccountScope(query, scopedAccountId);
|
|
|
|
if (dispatcherId != null)
|
|
query = query.Where(w => w.AssignTo == dispatcherId);
|
|
|
|
if (dateFrom is DateOnly from && dateTo is DateOnly to)
|
|
{
|
|
var fromDate = from.ToDateTime(TimeOnly.MinValue);
|
|
var toDateExclusive = to.AddDays(1).ToDateTime(TimeOnly.MinValue);
|
|
query = query.Where(w =>
|
|
w.ScheduledDate >= fromDate && w.ScheduledDate < toDateExclusive);
|
|
}
|
|
|
|
return await query
|
|
.Select(w => new DashboardWorkOrder(
|
|
w.Id,
|
|
w.AssignTo,
|
|
w.WorkOrderType,
|
|
w.LifecycleStatus,
|
|
w.LegacyStatus ?? w.Status,
|
|
w.ScheduledDate,
|
|
w.OriginalDate,
|
|
w.CompletedDate))
|
|
.ToListAsync(cancellationToken);
|
|
}
|
|
|
|
public async Task<IReadOnlyList<DashboardDispatcherWorkload>> GetDispatcherWorkloadAsync(
|
|
int? accountId,
|
|
string? dispatcherId,
|
|
DateOnly? dateFrom,
|
|
DateOnly? dateTo,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var dispatcherUsers = from user in _context.Users.AsNoTracking()
|
|
join userRole in _context.UserRoles
|
|
on user.Id equals userRole.UserId
|
|
join role in _context.Roles
|
|
on userRole.RoleId equals role.Id
|
|
where user.IsDeleted != true
|
|
&& (role.Name == "Dispatcher" || role.Name == "DISPATCHER")
|
|
&& (dispatcherId == null || user.Id == dispatcherId)
|
|
select new
|
|
{
|
|
user.Id,
|
|
Name = ((user.FirstName ?? "") + " " + (user.LastName ?? "")).Trim(),
|
|
user.Color
|
|
};
|
|
|
|
var workOrders = WorkOrderBoardQueryFilters.ApplyBaseScope(_context.workOrders.AsNoTracking());
|
|
if (accountId is int scopedAccountId)
|
|
workOrders = WorkOrderBoardQueryFilters.ApplyAccountScope(workOrders, scopedAccountId);
|
|
|
|
if (dateFrom is DateOnly from && dateTo is DateOnly to)
|
|
{
|
|
var fromDate = from.ToDateTime(TimeOnly.MinValue);
|
|
var toDateExclusive = to.AddDays(1).ToDateTime(TimeOnly.MinValue);
|
|
workOrders = workOrders.Where(w =>
|
|
w.ScheduledDate >= fromDate && w.ScheduledDate < toDateExclusive);
|
|
}
|
|
|
|
var counts = await workOrders
|
|
.Where(w => w.AssignTo != null)
|
|
.GroupBy(w => w.AssignTo!)
|
|
.Select(group => new
|
|
{
|
|
DispatcherId = group.Key,
|
|
TotalCount = group.Count(),
|
|
OpenCount = group.Count(w =>
|
|
w.LifecycleStatus != LifecycleStatus.Completed
|
|
&& w.LifecycleStatus != LifecycleStatus.Canceled
|
|
&& (w.LifecycleStatus != null
|
|
|| (w.LegacyStatus ?? w.Status) != "Done"
|
|
&& (w.LegacyStatus ?? w.Status) != "Completed"
|
|
&& (w.LegacyStatus ?? w.Status) != "Complete"
|
|
&& (w.LegacyStatus ?? w.Status) != "Closed"
|
|
&& (w.LegacyStatus ?? w.Status) != "Canceled"
|
|
&& (w.LegacyStatus ?? w.Status) != "Cancelled"))
|
|
})
|
|
.ToListAsync(cancellationToken);
|
|
|
|
var dispatcherList = await dispatcherUsers
|
|
.Distinct()
|
|
.ToListAsync(cancellationToken);
|
|
|
|
return dispatcherList
|
|
.GroupJoin(
|
|
counts,
|
|
user => user.Id,
|
|
count => count.DispatcherId,
|
|
(user, matchingCounts) =>
|
|
{
|
|
var count = matchingCounts.SingleOrDefault();
|
|
return new DashboardDispatcherWorkload(
|
|
user.Id,
|
|
user.Name,
|
|
user.Color,
|
|
count?.TotalCount ?? 0,
|
|
count?.OpenCount ?? 0);
|
|
})
|
|
.ToList();
|
|
}
|
|
}
|
|
}
|