using System.Security.AccessControl; using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using Microsoft.EntityFrameworkCore; namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardDetail; public record ProjectDeployBoardDetailsResponse( ProjectDeployBoardDetailPhaseItem Phase, List Tasks); public record ProjectDeployBoardDetailPhaseItem( string Name, TimeSpan TotalTimeSpan, TimeSpan DoneTimeSpan); public record ProjectDeployBoardDetailTaskItem( string Name, TimeSpan TotalTimeSpan, TimeSpan DoneTimeSpan, List Skills) : ProjectDeployBoardDetailPhaseItem(Name, TotalTimeSpan, DoneTimeSpan); public record ProjectDeployBoardDetailItemSkill(string OriginalUserFullName, string SkillName, int TimePercentage); public record ProjectDeployBoardDetailsQuery(Guid PhaseId) : IBaseQuery; public class ProjectDeployBoardDetailsQueryHandler : IBaseQueryHandler { private readonly IProgramManagerDbContext _dbContext; public ProjectDeployBoardDetailsQueryHandler(IProgramManagerDbContext dbContext) { _dbContext = dbContext; } public async Task> Handle(ProjectDeployBoardDetailsQuery request, CancellationToken cancellationToken) { var phase = await _dbContext.ProjectPhases .Include(x => x.Tasks) .ThenInclude(x => x.Sections) .ThenInclude(x => x.Activities) .Include(x => x.Tasks) .ThenInclude(x => x.Sections) .ThenInclude(x => x.AdditionalTimes) .Include(x => x.Tasks) .ThenInclude(x => x.Sections) .ThenInclude(x => x.Skill) .FirstOrDefaultAsync(x => x.Id == request.PhaseId, cancellationToken); if (phase == null) return OperationResult.NotFound("بخش اصلی مورد نظر یافت نشد"); var userIds = phase.Tasks .SelectMany(t => t.Sections) .Select(s => s.OriginalAssignedUserId) .Distinct() .ToList(); var usersDict = await _dbContext.Users .Where(x => userIds.Contains(x.Id)) .ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken); var tasksRes = phase.Tasks.Select(t => { var totalTime = t.Sections.Select(s => s.FinalEstimatedHours) .Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next)); var doneTime = t.Sections.Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next.GetTotalTimeSpent())); var skills = t.Sections .Select(s => new ProjectDeployBoardDetailItemSkill( usersDict.GetValueOrDefault(s.OriginalAssignedUserId, "کاربر ناشناس"), s.Skill?.Name ?? "بدون مهارت", totalTime.TotalSeconds > 0 ? (int)((doneTime.TotalSeconds / totalTime.TotalSeconds) * 100) : 0)).ToList(); return new ProjectDeployBoardDetailTaskItem( t.Name, totalTime, doneTime, skills); }).ToList(); var totalTimeSpan = tasksRes.Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next.TotalTimeSpan)); var doneTimeSpan = tasksRes.Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next.DoneTimeSpan)); var phaseRes = new ProjectDeployBoardDetailPhaseItem(phase.Name, totalTimeSpan, doneTimeSpan); var res = new ProjectDeployBoardDetailsResponse(phaseRes, tasksRes); return OperationResult.Success(res); } }