From 0772604432dbb84a8b25f0562259d74bc07ed9fc Mon Sep 17 00:00:00 2001 From: mahan Date: Thu, 8 Jan 2026 15:02:43 +0330 Subject: [PATCH] feat: enhance GetMessagesQuery to include additional time notes in message retrieval --- .../Queries/GetMessages/GetMessagesQuery.cs | 127 ++++++++++-------- 1 file changed, 74 insertions(+), 53 deletions(-) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskChat/Queries/GetMessages/GetMessagesQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskChat/Queries/GetMessages/GetMessagesQuery.cs index fbc3e3b8..9d0deccf 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskChat/Queries/GetMessages/GetMessagesQuery.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskChat/Queries/GetMessages/GetMessagesQuery.cs @@ -1,7 +1,6 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application.Modules.TaskChat.DTOs; -using MediatR; using Microsoft.EntityFrameworkCore; namespace GozareshgirProgramManager.Application.Modules.TaskChat.Queries.GetMessages; @@ -25,6 +24,39 @@ public class GetMessagesQueryHandler : IBaseQueryHandler CreateAdditionalTimeNotes( + IEnumerable additionalTimes, + Dictionary users, + Guid taskId) + { + var notes = new List(); + + foreach (var additionalTime in additionalTimes) + { + var addedByUserName = additionalTime.AddedByUserId.HasValue && users.TryGetValue(additionalTime.AddedByUserId.Value, out var user) + ? user + : "سیستم"; + + var noteContent = $"⏱️ زمان اضافی: {additionalTime.Hours.TotalHours.ToString("F2")} ساعت - {(string.IsNullOrWhiteSpace(additionalTime.Reason) ? "بدون علت" : additionalTime.Reason)} - توسط {addedByUserName}"; + + var noteDto = new MessageDto + { + Id = Guid.NewGuid(), + TaskId = taskId, + SenderUserId = 0, + SenderName = "سیستم", + MessageType = "Note", + TextContent = noteContent, + CreationDate = additionalTime.CreationDate, + IsMine = false + }; + + notes.Add(noteDto); + } + + return notes; + } + public async Task>> Handle(GetMessagesQuery request, CancellationToken cancellationToken) { var currentUserId = _authHelper.GetCurrentUserId(); @@ -44,36 +76,52 @@ public class GetMessagesQueryHandler : IBaseQueryHandler m.SenderUserId).Distinct().ToList(); var users = await _context.Users .Where(u => senderUserIds.Contains(u.Id)) .ToDictionaryAsync(u => u.Id, u => u.FullName, cancellationToken); // ✅ گرفتن تمامی زمان‌های اضافی (Additional Times) برای نمایش به صورت نوت - // در اینجا تمامی TaskSections مربوط به این تسک را می‌گیریم - // و برای هر کدام تمام AdditionalTimes آن را بارگذاری می‌کنیم var taskSections = await _context.TaskSections .Where(ts => ts.TaskId == request.TaskId) .Include(ts => ts.AdditionalTimes) .ToListAsync(cancellationToken); + // ✅ تمام زمان‌های اضافی را یکجا بگیر و مرتب کن + var allAdditionalTimes = taskSections + .SelectMany(ts => ts.AdditionalTimes) + .OrderBy(at => at.CreationDate) + .ToList(); + var messageDtos = new List(); + // ✅ ابتدا زمان‌های اضافی قبل از اولین پیام را اضافه کن (اگر پیامی وجود داشته باشد) + if (messages.Any()) + { + var firstMessageDate = messages.First().CreationDate; + var additionalTimesBeforeFirstMessage = allAdditionalTimes + .Where(at => at.CreationDate < firstMessageDate) + .ToList(); + + messageDtos.AddRange(CreateAdditionalTimeNotes(additionalTimesBeforeFirstMessage, users, request.TaskId)); + } + else + { + // ✅ اگر هیچ پیامی وجود ندارد، همه زمان‌های اضافی را نمایش بده + messageDtos.AddRange(CreateAdditionalTimeNotes(allAdditionalTimes, users, request.TaskId)); + } + foreach (var message in messages) { // ✅ نام فرستنده را از Dictionary Users بگیر، در صورت عدم وجود "کاربر ناشناس" نمایش بده - var senderName = users.ContainsKey(message.SenderUserId) - ? users[message.SenderUserId] - : "کاربر ناشناس"; + var senderName = users.GetValueOrDefault(message.SenderUserId, "کاربر ناشناس"); var dto = new MessageDto { Id = message.Id, TaskId = message.TaskId, SenderUserId = message.SenderUserId, - SenderName = senderName, // ✅ از User واقعی استفاده می‌کنیم + SenderName = senderName, MessageType = message.MessageType.ToString(), TextContent = message.TextContent, ReplyToMessageId = message.ReplyToMessageId, @@ -88,10 +136,7 @@ public class GetMessagesQueryHandler : IBaseQueryHandler ts.AdditionalTimes) - .Where(at => at.AddedAt > message.CreationDate) // ✅ تغییر به AddedAt (زمان واقعی اضافه شدن) - .OrderBy(at => at.AddedAt) - .FirstOrDefault(); + // ✅ پیدا کردن پیام بعدی (اگر وجود داشته باشد) + var currentIndex = messages.IndexOf(message); + var nextMessage = currentIndex < messages.Count - 1 ? messages[currentIndex + 1] : null; - if (additionalTimesAfterMessage != null) + if (nextMessage != null) { - // ✅ تمام AdditionalTimes بین این پیام و پیام قبلی را بگیر - var additionalTimesByDate = taskSections - .SelectMany(ts => ts.AdditionalTimes) - .Where(at => at.AddedAt <= message.CreationDate && - (messageDtos.Count == 1 || at.AddedAt > messageDtos[messageDtos.Count - 2].CreationDate)) - .OrderBy(at => at.AddedAt) + // ✅ زمان‌های اضافی بین این پیام و پیام بعدی + var additionalTimesBetween = allAdditionalTimes + .Where(at => at.CreationDate > message.CreationDate && at.CreationDate < nextMessage.CreationDate) .ToList(); - foreach (var additionalTime in additionalTimesByDate) - { - // ✅ نام کاربری که این زمان اضافی را اضافه کرد - var addedByUserName = additionalTime.AddedByUserId.HasValue && users.TryGetValue(additionalTime.AddedByUserId.Value, out var user) - ? user - : "سیستم"; + messageDtos.AddRange(CreateAdditionalTimeNotes(additionalTimesBetween, users, request.TaskId)); + } + else + { + // ✅ این آخرین پیام است، زمان‌های اضافی بعد از آن را اضافه کن + var additionalTimesAfterLastMessage = allAdditionalTimes + .Where(at => at.CreationDate > message.CreationDate) + .ToList(); - // ✅ محتوای نوت را با اطلاعات کامل ایجاد کن - // نمایش می‌دهد: مقدار زمان + علت + نام کسی که اضافه کرد - var noteContent = $"⏱️ زمان اضافی: {additionalTime.Hours.TotalHours:F2} ساعت - {(string.IsNullOrWhiteSpace(additionalTime.Reason) ? "بدون علت" : additionalTime.Reason)} - توسط {addedByUserName}"; - - // ✅ نوت را به عنوان MessageDto خاصی ایجاد کن - var noteDto = new MessageDto - { - Id = Guid.NewGuid(), - TaskId = request.TaskId, - SenderUserId = 0, // ✅ سیستم برای نشان دادن اینکه یک پیام خودکار است - SenderName = "سیستم", - MessageType = "Note", // ✅ نوع پیام: Note (یادداشت سیستم) - TextContent = noteContent, - CreationDate = additionalTime.AddedAt, // ✅ تاریخ اضافه شدن زمان اضافی - IsMine = false - }; - - messageDtos.Add(noteDto); - } + messageDtos.AddRange(CreateAdditionalTimeNotes(additionalTimesAfterLastMessage, users, request.TaskId)); } } // ✅ مرتب کردن نهایی تمام پیام‌ها (معمولی + نوت‌ها) بر اساس زمان ایجاد - // اینطور که نوت‌های زمان اضافی در جای درست خود قرار می‌گیرند messageDtos = messageDtos.OrderBy(m => m.CreationDate).ToList(); var response = new PaginationResult()