using DNTPersianUtils.Core; using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; using GozareshgirProgramManager.Application.Modules.Projects.DTOs; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using Microsoft.EntityFrameworkCore; namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails; public class ProjectSetTimeDetailsQueryHandler : IBaseQueryHandler { private readonly IProgramManagerDbContext _context; public ProjectSetTimeDetailsQueryHandler(IProgramManagerDbContext context) { _context = context; } public async Task> Handle(ProjectSetTimeDetailsQuery request, CancellationToken cancellationToken) { return request.Level switch { ProjectHierarchyLevel.Task => await GetTaskSetTimeDetails(request.Id, request.Level, cancellationToken), ProjectHierarchyLevel.Phase => await GetPhaseSetTimeDetails(request.Id, request.Level, cancellationToken), ProjectHierarchyLevel.Project => await GetProjectSetTimeDetails(request.Id, request.Level, cancellationToken), _ => OperationResult.Failure("سطح معادل نامعتبر است") }; } private async Task> GetTaskSetTimeDetails(Guid id, ProjectHierarchyLevel level, CancellationToken cancellationToken) { var task = await _context.ProjectTasks .Where(p => p.Id == id) .Include(x => x.Sections) .ThenInclude(x => x.AdditionalTimes).AsNoTracking() .FirstOrDefaultAsync(cancellationToken); if (task == null) { return OperationResult.NotFound("تسک یافت نشد"); } var userIds = task.Sections.Select(x => x.OriginalAssignedUserId) .Distinct().ToList(); var users = await _context.Users .Where(x => userIds.Contains(x.Id)) .AsNoTracking() .ToListAsync(cancellationToken); var skills = await _context.Skills .AsNoTracking() .ToListAsync(cancellationToken); var res = new ProjectSetTimeResponse( skills.Select(skill => { var section = task.Sections .FirstOrDefault(x => x.SkillId == skill.Id); var user = users.FirstOrDefault(x => x.Id == section?.OriginalAssignedUserId); return new ProjectSetTimeResponseSkill { AdditionalTimes = section?.AdditionalTimes .Select(x => new ProjectSetTimeResponseSectionAdditionalTime { Description = x.Reason ?? "", Hours = (int)x.Hours.TotalHours, Minutes = x.Hours.Minutes, CreationDate = x.CreationDate.ToFarsi() }).OrderBy(x => x.CreationDate).ToList() ?? [], InitCreationTime = section?.CreationDate.ToFarsi() ?? "", SkillName = skill.Name ?? "", UserFullName = user?.FullName ?? "", SectionId = section?.Id ?? Guid.Empty, InitialDescription = section?.InitialDescription ?? "", InitialHours = (int)(section?.InitialEstimatedHours.TotalHours ?? 0), InitialMinutes = section?.InitialEstimatedHours.Minutes ?? 0, UserId = section?.OriginalAssignedUserId ?? 0, SkillId = skill.Id, }; }).OrderBy(x => x.SkillId).ToList(), task.Id, level); return OperationResult.Success(res); } private async Task> GetPhaseSetTimeDetails(Guid id, ProjectHierarchyLevel level, CancellationToken cancellationToken) { var phase = await _context.ProjectPhases .Where(p => p.Id == id) .Include(x => x.PhaseSections).AsNoTracking() .FirstOrDefaultAsync(cancellationToken); if (phase == null) { return OperationResult.NotFound("فاز یافت نشد"); } var userIds = phase.PhaseSections.Select(x => x.UserId) .Distinct().ToList(); var users = await _context.Users .Where(x => userIds.Contains(x.Id)) .AsNoTracking() .ToListAsync(cancellationToken); var skills = await _context.Skills .AsNoTracking() .ToListAsync(cancellationToken); var res = new ProjectSetTimeResponse( skills.Select(skill => { var section = phase.PhaseSections .FirstOrDefault(x => x.SkillId == skill.Id); var user = users.FirstOrDefault(x => x.Id == section?.UserId); return new ProjectSetTimeResponseSkill { AdditionalTimes = [], InitCreationTime = "", SkillName = skill.Name ?? "", UserFullName = user?.FullName ?? "", SectionId = section?.Id ?? Guid.Empty, InitialDescription = "", InitialHours = 0, InitialMinutes = 0, UserId = section?.UserId ?? 0, SkillId = skill.Id, }; }).OrderBy(x => x.SkillId).ToList(), phase.Id, level); return OperationResult.Success(res); } private async Task> GetProjectSetTimeDetails(Guid id, ProjectHierarchyLevel level, CancellationToken cancellationToken) { var project = await _context.Projects .Where(p => p.Id == id) .Include(x => x.ProjectSections).AsNoTracking() .FirstOrDefaultAsync(cancellationToken); if (project == null) { return OperationResult.NotFound("پروژه یافت نشد"); } var userIds = project.ProjectSections.Select(x => x.UserId) .Distinct().ToList(); var users = await _context.Users .Where(x => userIds.Contains(x.Id)) .AsNoTracking() .ToListAsync(cancellationToken); var skills = await _context.Skills .AsNoTracking() .ToListAsync(cancellationToken); var res = new ProjectSetTimeResponse( skills.Select(skill => { var section = project.ProjectSections .FirstOrDefault(x => x.SkillId == skill.Id); var user = users.FirstOrDefault(x => x.Id == section?.UserId); return new ProjectSetTimeResponseSkill { AdditionalTimes = [], InitCreationTime = "", SkillName = skill.Name ?? "", UserFullName = user?.FullName ?? "", SectionId = section?.Id ?? Guid.Empty, InitialDescription = "", InitialHours = 0, InitialMinutes = 0, UserId = section?.UserId ?? 0, SkillId = skill.Id, }; }).OrderBy(x => x.SkillId).ToList(), project.Id, level); return OperationResult.Success(res); } }