using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using Microsoft.EntityFrameworkCore; namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectHierarchySearch; /// /// Handler برای درخواست جستجوی سراسری در سلسله‌مراتب پروژه. /// این handler در تمام سطح‌های پروژه، فاز و تسک جستجو می‌کند و از تمام فیلدهای متنی (نام، توضیحات) استفاده می‌کند. /// همچنین در زیرمجموعه‌های هر سطح (ProjectSections، PhaseSections، TaskSections) جستجو می‌کند. /// public class GetProjectSearchQueryHandler : IBaseQueryHandler { private readonly IProgramManagerDbContext _context; private const int MaxResults = 50; public GetProjectSearchQueryHandler(IProgramManagerDbContext context) { _context = context; } public async Task> Handle( GetProjectSearchQuery request, CancellationToken cancellationToken) { var searchQuery = request.SearchQuery.ToLower(); var results = new List(); // جستجو در پروژه‌ها و ProjectSections var projects = await SearchProjects(searchQuery, cancellationToken); results.AddRange(projects); // جستجو در فازها و PhaseSections var phases = await SearchPhases(searchQuery, cancellationToken); results.AddRange(phases); // جستجو در تسک‌ها و TaskSections var tasks = await SearchTasks(searchQuery, cancellationToken); results.AddRange(tasks); // مرتب‌سازی نتایج: ابتدا بر اساس سطح سلسله‌مراتب (پروژه → فاز → تسک)، سپس بر اساس نام var sortedResults = results .OrderBy(r => r.Level) .ThenBy(r => r.Title) .Take(MaxResults) .ToList(); var response = new GetProjectSearchResponse(sortedResults); return OperationResult.Success(response); } /// /// جستجو در جدول پروژه‌ها (نام، توضیحات) و ProjectSections (نام مهارت، توضیحات اولیه) /// private async Task> SearchProjects( string searchQuery, CancellationToken cancellationToken) { var projects = await _context.Projects .Where(p => p.Name.ToLower().Contains(searchQuery) || (p.Description != null && p.Description.ToLower().Contains(searchQuery))) .Select(p => new ProjectHierarchySearchResultDto { Id = p.Id, Title = p.Name, Level = ProjectHierarchyLevel.Project, ProjectId = null, PhaseId = null }) .ToListAsync(cancellationToken); return projects; } /// /// جستجو در جدول فازهای پروژه (نام، توضیحات) و PhaseSections /// private async Task> SearchPhases( string searchQuery, CancellationToken cancellationToken) { var phases = await _context.ProjectPhases .Where(ph => ph.Name.ToLower().Contains(searchQuery) || (ph.Description != null && ph.Description.ToLower().Contains(searchQuery))) .Select(ph => new ProjectHierarchySearchResultDto { Id = ph.Id, Title = ph.Name, Level = ProjectHierarchyLevel.Phase, ProjectId = ph.ProjectId, PhaseId = null }) .ToListAsync(cancellationToken); return phases; } /// /// جستجو در جدول تسک‌های پروژه (نام، توضیحات) و TaskSections (نام مهارت، توضیح اولیه، اطلاعات اضافی) /// private async Task> SearchTasks( string searchQuery, CancellationToken cancellationToken) { var tasks = await _context.ProjectTasks .Include(t => t.Sections) .Include(t => t.Phase) .Where(t => t.Name.ToLower().Contains(searchQuery) || (t.Description != null && t.Description.ToLower().Contains(searchQuery)) || t.Sections.Any(s => (s.InitialDescription != null && s.InitialDescription.ToLower().Contains(searchQuery)) || s.AdditionalTimes.Any(at => at.Reason != null && at.Reason.ToLower().Contains(searchQuery)))) .Select(t => new ProjectHierarchySearchResultDto { Id = t.Id, Title = t.Name, Level = ProjectHierarchyLevel.Task, ProjectId = t.Phase.ProjectId, PhaseId = t.PhaseId }) .ToListAsync(cancellationToken); return tasks; } }