mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 11:53:12 +00:00
feat(dashboard): expose KPI counts (SH-353)
This commit is contained in:
parent
9d7efa34a6
commit
7947e2e77d
4 changed files with 86 additions and 0 deletions
|
|
@ -88,6 +88,70 @@ namespace SeaHaven.DataServices.Implementation
|
|||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<DashboardKpiCounts> GetKpiCountsAsync(
|
||||
int? accountId,
|
||||
string? dispatcherId,
|
||||
DateOnly today,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var tomorrow = today.AddDays(1);
|
||||
var dayAfterTomorrow = tomorrow.AddDays(1);
|
||||
var workOrders = WorkOrderBoardQueryFilters.ApplyBaseScope(_context.workOrders.AsNoTracking());
|
||||
if (accountId is int scopedAccountId)
|
||||
workOrders = WorkOrderBoardQueryFilters.ApplyAccountScope(workOrders, scopedAccountId);
|
||||
if (dispatcherId != null)
|
||||
workOrders = workOrders.Where(w => w.AssignTo == dispatcherId);
|
||||
|
||||
var scheduledTomorrow = await workOrders
|
||||
.Where(w => w.ScheduledDate >= tomorrow.ToDateTime(TimeOnly.MinValue)
|
||||
&& w.ScheduledDate < dayAfterTomorrow.ToDateTime(TimeOnly.MinValue))
|
||||
.CountAsync(cancellationToken);
|
||||
|
||||
var avetaPending = await workOrders
|
||||
.Where(w => w.ScheduledDate >= today.ToDateTime(TimeOnly.MinValue)
|
||||
&& w.ScheduledDate < dayAfterTomorrow.ToDateTime(TimeOnly.MinValue)
|
||||
&& w.AvetaRequired
|
||||
&& 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"))
|
||||
&& !w.workOrderAttachments!.Any(attachment =>
|
||||
(attachment.IsDeleted == null || attachment.IsDeleted == false)
|
||||
&& attachment.Category == WorkOrderMediaCategory.Aveta))
|
||||
.CountAsync(cancellationToken);
|
||||
|
||||
var pendingUplifts = _context.DispatchUpliftRequests
|
||||
.AsNoTracking()
|
||||
.Where(request => request.Status == "Pending"
|
||||
&& (request.IsDeleted == null || request.IsDeleted == false)
|
||||
&& request.Dispatch != null
|
||||
&& (request.Dispatch.IsDeleted == null || request.Dispatch.IsDeleted == false));
|
||||
if (accountId is int account)
|
||||
{
|
||||
pendingUplifts = pendingUplifts.Where(request =>
|
||||
(request.Dispatch!.WorkOrder != null && request.Dispatch.WorkOrder.AccountId == account)
|
||||
|| request.Dispatch.DispatchWorkOrders!.Any(link =>
|
||||
link.WorkOrder != null && link.WorkOrder.AccountId == account));
|
||||
}
|
||||
if (dispatcherId != null)
|
||||
{
|
||||
pendingUplifts = pendingUplifts.Where(request =>
|
||||
(request.Dispatch!.WorkOrder != null && request.Dispatch.WorkOrder.AssignTo == dispatcherId)
|
||||
|| request.Dispatch.DispatchWorkOrders!.Any(link =>
|
||||
link.WorkOrder != null && link.WorkOrder.AssignTo == dispatcherId));
|
||||
}
|
||||
|
||||
return new DashboardKpiCounts(
|
||||
scheduledTomorrow,
|
||||
await pendingUplifts.CountAsync(cancellationToken),
|
||||
avetaPending);
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<DashboardDispatcherWorkload>> GetDispatcherWorkloadAsync(
|
||||
int? accountId,
|
||||
string? dispatcherId,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ namespace SeaHaven.DataServices.Interfaces
|
|||
int? accountId,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
Task<DashboardKpiCounts> GetKpiCountsAsync(
|
||||
int? accountId,
|
||||
string? dispatcherId,
|
||||
DateOnly today,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
Task<IReadOnlyList<DashboardWorkOrder>> GetDashboardWorkOrdersAsync(
|
||||
int? accountId,
|
||||
string? dispatcherId,
|
||||
|
|
@ -53,4 +59,9 @@ namespace SeaHaven.DataServices.Interfaces
|
|||
public int NotDispatched { get; set; }
|
||||
public int Completed { get; set; }
|
||||
}
|
||||
|
||||
public sealed record DashboardKpiCounts(
|
||||
int ScheduledTomorrow,
|
||||
int PendingUplifts,
|
||||
int AvetaPending);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@ namespace SeaHaven.Services.DTOs
|
|||
public int Open { get; set; }
|
||||
public int NotDispatched { get; set; }
|
||||
public int Completed { get; set; }
|
||||
public int ScheduledTomorrow { get; set; }
|
||||
public int PendingUplifts { get; set; }
|
||||
public int AvetaPending { get; set; }
|
||||
public DashboardBreakdownDTO Breakdown { get; set; } = new();
|
||||
public int DueCount { get; set; }
|
||||
public int CompletedDueCount { get; set; }
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ namespace SeaHaven.Services.Implementation
|
|||
throw new WorkOrderBoardValidationException("Forbidden", "Dispatcher identity is required.");
|
||||
|
||||
var counts = await _dataService.GetWorkOrderCountsAsync(accountId, cancellationToken);
|
||||
var kpis = await _dataService.GetKpiCountsAsync(
|
||||
accountId,
|
||||
dispatcherId,
|
||||
DashboardBusinessTime.Today(),
|
||||
cancellationToken);
|
||||
var workOrders = await _dataService.GetDashboardWorkOrdersAsync(
|
||||
accountId,
|
||||
dispatcherId,
|
||||
|
|
@ -51,6 +56,9 @@ namespace SeaHaven.Services.Implementation
|
|||
Open = useMetrics ? metrics.Open : counts.Open,
|
||||
NotDispatched = useMetrics ? metrics.NotDispatched : counts.NotDispatched,
|
||||
Completed = useMetrics ? metrics.Completed : counts.Completed,
|
||||
ScheduledTomorrow = kpis.ScheduledTomorrow,
|
||||
PendingUplifts = kpis.PendingUplifts,
|
||||
AvetaPending = kpis.AvetaPending,
|
||||
Breakdown = metrics.Breakdown,
|
||||
DueCount = metrics.DueCount,
|
||||
CompletedDueCount = metrics.CompletedDueCount,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue