Spaces:
Running
Running
File size: 6,271 Bytes
3418204 01be06d 3418204 47e77e5 e40d850 ecb51fa 3418204 ecb51fa 3418204 ecb51fa 01be06d ecb51fa 01be06d fa69bf0 01be06d 47e77e5 3418204 ecb51fa 3418204 ecb51fa 3418204 47e77e5 3418204 47e77e5 3418204 ecb51fa 3418204 ecb51fa 3418204 7f6afc2 3418204 e40d850 3418204 ecb51fa 01be06d 7f6afc2 01be06d ecb51fa 01be06d ecb51fa fa69bf0 01be06d ecb51fa 01be06d ecb51fa 01be06d 3418204 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TaskTrackingSystem.Database.AppDbContextModels;
using TaskTrackingSystem.Shared;
using TaskTrackingSystem.Shared.Enums;
using TaskTrackingSystem.Shared.Models.Dashboard;
using TaskTrackingSystem.WebApi.Infrastructure;
namespace TaskTrackingSystem.WebApi.Features.Dashboard
{
public class DashboardService
{
private readonly AppDbContext _db;
public DashboardService(AppDbContext db)
{
_db = db;
}
public async Task<Result<DashboardSummaryDto>> GetSummaryAsync(long roleId, long currentUserId)
{
var isAdmin = await DataScopeAuthorization.IsAdminScopeAsync(_db, roleId);
var isManager = await DataScopeAuthorization.IsManagerScopeAsync(_db, roleId);
var projects = BuildAccessibleProjectQuery(isAdmin, currentUserId);
var tasks = BuildAccessibleTaskQuery(isAdmin, isManager, currentUserId);
var totalUsers = isAdmin
? await _db.Users.CountAsync(u => !u.IsDeleted)
: await _db.Users
.Where(u => !u.IsDeleted &&
projects.SelectMany(p => p.ProjectMembers.Select(pm => pm.UserId))
.Distinct()
.Contains(u.Id))
.CountAsync();
var activeProjectsCount = await projects.CountAsync();
var pendingTasksCount = await tasks.CountAsync(t => t.StatusId != AppTaskStatus.Done);
var summary = new DashboardSummaryDto
{
TotalUsers = totalUsers,
ActiveProjectsCount = activeProjectsCount,
PendingTasksCount = pendingTasksCount
};
return Result<DashboardSummaryDto>.Success(summary);
}
public async Task<Result<IEnumerable<TaskStatusOverviewDto>>> GetTasksOverviewAsync(long roleId, long currentUserId)
{
var isAdmin = await DataScopeAuthorization.IsAdminScopeAsync(_db, roleId);
var isManager = await DataScopeAuthorization.IsManagerScopeAsync(_db, roleId);
var groupedTasks = await BuildAccessibleTaskQuery(isAdmin, isManager, currentUserId)
.GroupBy(t => t.StatusId)
.Select(g => new
{
StatusId = g.Key,
Count = g.Count()
})
.ToListAsync();
var statusMap = new Dictionary<AppTaskStatus, string>
{
{ AppTaskStatus.Todo, "To Do" },
{ AppTaskStatus.InProgress, "In Progress" },
{ AppTaskStatus.Done, "Done" }
};
var overview = groupedTasks.Select(gt => new TaskStatusOverviewDto
{
StatusId = gt.StatusId,
StatusName = statusMap.TryGetValue(gt.StatusId, out var name) ? name : $"Status {gt.StatusId}",
TaskCount = gt.Count
}).ToList();
foreach (var status in statusMap)
{
if (!overview.Any(o => o.StatusId == status.Key))
{
overview.Add(new TaskStatusOverviewDto
{
StatusId = status.Key,
StatusName = status.Value,
TaskCount = 0
});
}
}
return Result<IEnumerable<TaskStatusOverviewDto>>.Success(overview.OrderBy(o => o.StatusId));
}
public async Task<Result<IEnumerable<ProjectProgressDto>>> GetProjectProgressAsync(long roleId, long currentUserId)
{
var isAdmin = await DataScopeAuthorization.IsAdminScopeAsync(_db, roleId);
var activeProjects = await BuildAccessibleProjectQuery(isAdmin, currentUserId).ToListAsync();
var progressList = new List<ProjectProgressDto>();
foreach (var project in activeProjects)
{
var tasks = await _db.Tasks
.Where(t => t.ProjectId == project.Id && t.IsDeleted != true && !t.IsArchived)
.ToListAsync();
int totalTasks = tasks.Count;
int completedTasks = tasks.Count(t => t.StatusId == AppTaskStatus.Done);
double percentage = totalTasks > 0 ? Math.Round(((double)completedTasks / totalTasks) * 100, 2) : 0;
progressList.Add(new ProjectProgressDto
{
ProjectId = project.Id,
ProjectName = project.Name,
TotalTasksCount = totalTasks,
CompletedTasksCount = completedTasks,
CompletionPercentage = percentage
});
}
return Result<IEnumerable<ProjectProgressDto>>.Success(progressList);
}
private IQueryable<TaskTrackingSystem.Database.AppDbContextModels.Task> BuildAccessibleTaskQuery(bool isAdmin, bool isManager, long currentUserId)
{
var query = _db.Tasks.Where(t => t.IsDeleted != true && !t.IsArchived);
if (isAdmin)
{
return query;
}
if (isManager)
{
return query.Where(t =>
t.AssignedTo == currentUserId ||
t.CreatedBy == currentUserId ||
t.Project.ProjectMembers.Any(pm => pm.UserId == currentUserId));
}
return query.Where(t =>
t.AssignedTo == currentUserId ||
t.CreatedBy == currentUserId);
}
private IQueryable<TaskTrackingSystem.Database.AppDbContextModels.Project> BuildAccessibleProjectQuery(bool isAdmin, long currentUserId)
{
var query = _db.Projects.Where(p => p.IsDeleted != true);
if (isAdmin)
{
return query;
}
return query.Where(p =>
p.CreatedById == currentUserId ||
p.ProjectMembers.Any(pm => pm.UserId == currentUserId));
}
}
}
|