shoc-backend/SeaHaven.Services/DTOs/DashboardDTOs.cs
Alexandre Brandizzi 4876fa2717 feat(dashboard): count open unassigned work orders for the period (SH-392)
GET /dashboard/stats now returns unassigned: open (not Completed or
Canceled) work orders with no dispatcher in the selected period, within the
caller's server-derived account scope. It uses the same filters as the
Unassigned board search, so the Dashboard number equals the list it drills
into. A dispatcher-scoped Dashboard has no unassigned work and returns 0.
2026-09-24 21:11:31 -03:00

133 lines
4.6 KiB
C#

namespace SeaHaven.Services.DTOs
{
public class DashboardStatsQueryDTO
{
public DateOnly? DateFrom { get; set; }
public DateOnly? DateTo { get; set; }
public string? DispatcherId { get; set; }
}
public sealed class DashboardTrendQueryDTO : DashboardStatsQueryDTO
{
public string? Range { get; set; }
public int? Year { get; set; }
}
public sealed class DashboardTrendResponseDTO
{
public string Granularity { get; init; } = "day";
public DateOnly Today { get; init; }
public IReadOnlyList<DashboardTrendBucketDTO> Buckets { get; init; } = [];
}
public sealed class DashboardTrendBucketDTO
{
public DateOnly Date { get; init; }
public string Label { get; init; } = string.Empty;
public int Total { get; init; }
public int Open { get; init; }
public int Completed { get; init; }
public int Canceled { get; init; }
public int Overdue { get; init; }
public bool IsCurrent { get; init; }
}
public sealed class DashboardWorkloadResponseDTO
{
public IReadOnlyList<DashboardWorkloadRowDTO> Items { get; init; } = [];
public int Page { get; init; }
public int PageSize { get; init; }
public int TotalDispatchers { get; init; }
}
public sealed class DashboardWorkloadRowDTO
{
public string DispatcherId { get; init; } = string.Empty;
public string DispatcherName { get; init; } = string.Empty;
public string? Color { get; init; }
public int TotalCount { get; init; }
public int OpenCount { get; init; }
}
public sealed class DashboardPerformanceResponseDTO
{
public IReadOnlyList<DashboardPerformanceRowDTO> Items { get; init; } = [];
public int Page { get; init; }
public int PageSize { get; init; }
public int TotalDispatchers { get; init; }
}
public sealed class DashboardPerformanceRowDTO
{
public string DispatcherId { get; init; } = string.Empty;
public string DispatcherName { get; init; } = string.Empty;
public string? Color { get; init; }
public decimal CompletionRate { get; init; }
public decimal? AverageResolutionDays { get; init; }
public int AssignedCount { get; init; }
public int CompletedCount { get; init; }
}
public sealed class DashboardRegionResponseDTO
{
public IReadOnlyList<DashboardRegionRowDTO> Items { get; init; } = [];
}
public sealed class DashboardRegionRowDTO
{
public string Region { get; init; } = string.Empty;
public int WorkOrderCount { get; init; }
}
public sealed class DashboardVendorInsightsResponseDTO
{
public IReadOnlyList<DashboardVendorInsightsRowDTO> Items { get; init; } = [];
public int Page { get; init; }
public int PageSize { get; init; }
public int TotalVendors { get; init; }
}
public sealed class DashboardVendorInsightsRowDTO
{
public int VendorCompanyId { get; init; }
public string VendorCompanyName { get; init; } = string.Empty;
public decimal CompletionRate { get; init; }
public decimal RescheduleRate { get; init; }
public decimal? AverageResolutionDays { get; init; }
public int TotalJobs { get; init; }
}
public class DashboardStatsDTO
{
public int Total { get; set; }
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; }
/// <summary>Open work orders with no dispatcher in the selected period (SH-392).</summary>
public int Unassigned { get; set; }
public DashboardBreakdownDTO Breakdown { get; set; } = new();
public int DueCount { get; set; }
public int CompletedDueCount { get; set; }
public decimal CompletionRate { get; set; }
public decimal? AverageResolutionDays { get; set; }
public IReadOnlyList<DashboardStatusBucketDTO> StatusDistribution { get; set; } = [];
}
public sealed class DashboardStatusBucketDTO
{
public string Status { get; init; } = string.Empty;
public int Count { get; init; }
}
public sealed class DashboardBreakdownDTO
{
public int PM { get; set; }
public int Emergency { get; set; }
public int Reactive { get; set; }
public int Overdue { get; set; }
public int Other { get; set; }
}
}