refactor GetProjectsListQueryHandler to improve task and phase status aggregation logic
This commit is contained in:
@@ -228,28 +228,30 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler<GetProjectsListQuer
|
||||
// For projects: gather all phases, then tasks, then sections
|
||||
var phases = await _context.ProjectPhases
|
||||
.Where(ph => projectIds.Contains(ph.ProjectId))
|
||||
.Select(ph => ph.Id)
|
||||
.Select(ph => new { ph.Id, ph.ProjectId })
|
||||
.ToListAsync(cancellationToken);
|
||||
var phaseIds = phases.Select(ph => ph.Id).ToList();
|
||||
var tasks = await _context.ProjectTasks
|
||||
.Where(t => phases.Contains(t.PhaseId))
|
||||
.Select(t => t.Id)
|
||||
.Where(t => phaseIds.Contains(t.PhaseId))
|
||||
.Select(t => new { t.Id, t.PhaseId })
|
||||
.ToListAsync(cancellationToken);
|
||||
var taskIds = tasks.Select(t => t.Id).ToList();
|
||||
var sections = await _context.TaskSections
|
||||
.Include(s => s.Skill)
|
||||
.Where(s => tasks.Contains(s.TaskId))
|
||||
.Where(s => taskIds.Contains(s.TaskId))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
// Convert to tuple list for AggregatePhaseStatuses
|
||||
var tasksList = tasks.Select(t => (t.Id, t.PhaseId)).ToList();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
var relatedPhases = phases; // used for filtering tasks by project
|
||||
var relatedTasks = await _context.ProjectTasks
|
||||
.Where(t => t.PhaseId != Guid.Empty && relatedPhases.Contains(t.PhaseId))
|
||||
.Select(t => t.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
var itemSections = sections.Where(s => relatedTasks.Contains(s.TaskId));
|
||||
item.Backend = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "Backend"));
|
||||
item.Front = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "Frontend"));
|
||||
item.Design = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "UI/UX Design"));
|
||||
var projectPhaseIds = phases.Where(ph => ph.ProjectId == item.Id).Select(ph => ph.Id).ToList();
|
||||
|
||||
// برای هر Skill، وضعیتهای تمام Phases را تجمیع کنیم
|
||||
item.Backend = AggregatePhaseStatuses(projectPhaseIds, tasksList, sections, "Backend");
|
||||
item.Front = AggregatePhaseStatuses(projectPhaseIds, tasksList, sections, "Frontend");
|
||||
item.Design = AggregatePhaseStatuses(projectPhaseIds, tasksList, sections, "UI/UX Design");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,24 +261,22 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler<GetProjectsListQuer
|
||||
// For phases: gather tasks, then sections
|
||||
var tasks = await _context.ProjectTasks
|
||||
.Where(t => phaseIds.Contains(t.PhaseId))
|
||||
.Select(t => t.Id)
|
||||
.Select(t => new { t.Id, t.PhaseId })
|
||||
.ToListAsync(cancellationToken);
|
||||
var taskIds = tasks.Select(t => t.Id).ToList();
|
||||
var sections = await _context.TaskSections
|
||||
.Include(s => s.Skill)
|
||||
.Where(s => tasks.Contains(s.TaskId))
|
||||
.Where(s => taskIds.Contains(s.TaskId))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
// Filter tasks for this phase
|
||||
var phaseTaskIds = await _context.ProjectTasks
|
||||
.Where(t => t.PhaseId == item.Id)
|
||||
.Select(t => t.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
var phaseTaskIds = tasks.Where(t => t.PhaseId == item.Id).Select(t => t.Id).ToList();
|
||||
var itemSections = sections.Where(s => phaseTaskIds.Contains(s.TaskId));
|
||||
item.Backend = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "Backend"));
|
||||
item.Front = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "Frontend"));
|
||||
item.Design = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "UI/UX Design"));
|
||||
|
||||
item.Backend = AggregateAssignmentStatus(itemSections.Where(x => x.Skill?.Name == "Backend"));
|
||||
item.Front = AggregateAssignmentStatus(itemSections.Where(x => x.Skill?.Name == "Frontend"));
|
||||
item.Design = AggregateAssignmentStatus(itemSections.Where(x => x.Skill?.Name == "UI/UX Design"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,4 +380,57 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler<GetProjectsListQuer
|
||||
// تعیین تکلیف نشده: نه user دارد نه time
|
||||
return AssignmentStatus.Unassigned;
|
||||
}
|
||||
|
||||
private static AssignmentStatus AggregatePhaseStatuses(
|
||||
List<Guid> phaseIds,
|
||||
List<(Guid Id, Guid PhaseId)> tasks,
|
||||
List<TaskSection> sections,
|
||||
string skillName)
|
||||
{
|
||||
var phaseStatuses = new List<AssignmentStatus>();
|
||||
|
||||
foreach (var phaseId in phaseIds)
|
||||
{
|
||||
var phaseTaskIds = tasks.Where(t => t.PhaseId == phaseId).Select(t => t.Id).ToList();
|
||||
var phaseSections = sections.Where(s => phaseTaskIds.Contains(s.TaskId) && s.Skill?.Name == skillName);
|
||||
var phaseStatus = AggregateAssignmentStatus(phaseSections);
|
||||
phaseStatuses.Add(phaseStatus);
|
||||
}
|
||||
|
||||
// الآن تجمیع وضعیتهای Phases
|
||||
if (!phaseStatuses.Any())
|
||||
return AssignmentStatus.Unassigned;
|
||||
|
||||
// اگر هر یکی Unassigned باشد → Unassigned
|
||||
if (phaseStatuses.Any(s => s == AssignmentStatus.Unassigned))
|
||||
return AssignmentStatus.Unassigned;
|
||||
|
||||
// اگر Unassigned نیست و هر یکی UserOnly باشد → UserOnly
|
||||
if (phaseStatuses.Any(s => s == AssignmentStatus.UserOnly))
|
||||
return AssignmentStatus.UserOnly;
|
||||
|
||||
// فقط اگر همه Assigned باشند → Assigned
|
||||
return AssignmentStatus.Assigned;
|
||||
}
|
||||
|
||||
private static AssignmentStatus AggregateAssignmentStatus(IEnumerable<TaskSection> sections)
|
||||
{
|
||||
var sectionList = sections.ToList();
|
||||
if (!sectionList.Any())
|
||||
return AssignmentStatus.Unassigned;
|
||||
|
||||
var statuses = sectionList.Select(GetAssignmentStatus).ToList();
|
||||
|
||||
// اگر هر یکی Unassigned باشد → Unassigned (بدترین وضعیت)
|
||||
if (statuses.Any(s => s == AssignmentStatus.Unassigned))
|
||||
return AssignmentStatus.Unassigned;
|
||||
|
||||
// اگر Unassigned نیست و هر یکی UserOnly باشد → UserOnly (وضعیت متوسط)
|
||||
if (statuses.Any(s => s == AssignmentStatus.UserOnly))
|
||||
return AssignmentStatus.UserOnly;
|
||||
|
||||
// فقط اگر همه Assigned باشند → Assigned (بهترین وضعیت)
|
||||
return AssignmentStatus.Assigned;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user