diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs index b7ed7859..02f9c95c 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs @@ -12,6 +12,7 @@ public record SetTimeProjectCommand( public class SetTimeSectionTime { + public Guid? Id { get; set; } public string Description { get; set; } public int Hours { get; set; } public int Minutes { get; set; } diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs index a9ca3a61..49f43a88 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs @@ -349,6 +349,15 @@ public class SetTimeProjectCommandHandler : IBaseCommandHandler x.Id == existingTime.Id); + if (!stillExists) + { + section.RemoveAdditionalTime(existingTime.Id); + hasRealChange = true; + } + } + + // ویرایش یا اضافه کردن آیتم‌های جدید + foreach (var additionalTime in incomingAdditionalTimes) + { + var additionalTimeSpan = TimeSpan.FromHours(additionalTime.Hours) + .Add(TimeSpan.FromMinutes(additionalTime.Minutes)); + + if (additionalTimeSpan <= TimeSpan.Zero) + continue; + + var existingAdditionalTime = existingAdditionalTimes.FirstOrDefault(x => x.Id == additionalTime.Id); + + if (existingAdditionalTime != null) + { + // اگر آیتم با این ID وجود دارد، بررسی کن اگر تغییر کرده باشد + if (existingAdditionalTime.HasChanged(additionalTimeSpan, additionalTime.Description)) + { + var newTotalTime = section.InitialEstimatedHours + .Add(existingAdditionalTimes + .Where(x => x.Id != existingAdditionalTime.Id) + .Aggregate(TimeSpan.Zero, (acc, x) => acc.Add(x.Hours)) + .Add(additionalTimeSpan)); + + ValidateTotalTimeNotLessThanSpent(newTotalTime, currentTotalSpent); + + // ویرایش بدون حذف و ایجاد دوباره + existingAdditionalTime.Update(additionalTimeSpan, additionalTime.Description); + hasRealChange = true; + } + } + else + { + // اگر ID نداشت یا ID جدید بود، اضافه کن + if (additionalTime.Id == null || additionalTime.Id == Guid.Empty) + { + var newTotalTime = section.FinalEstimatedHours.Add(additionalTimeSpan); + ValidateTotalTimeNotLessThanSpent(newTotalTime, currentTotalSpent); + + section.AddAdditionalTime(additionalTimeSpan, additionalTime.Description, addedByUserId); + hasRealChange = true; + } + } } - // تغییر status به Incomplete فقط اگر زمان اضافی اضافه شده باشد و در وضعیتی غیر از ReadyToStart باشد - if (hasAdditionalTime && section.Status != TaskSectionStatus.ReadyToStart) + // تغییر status به Incomplete فقط اگر تغییری واقعی اعمال شده باشد و در وضعیتی غیر از ReadyToStart باشد + if (hasRealChange && section.Status != TaskSectionStatus.ReadyToStart) { // اگر سکشن درحال انجام است، باید متوقف شود قبل از تغییر status if (section.Status == TaskSectionStatus.InProgress) diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs index 657f76cc..e4cf303b 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs @@ -26,4 +26,15 @@ public class TaskSectionAdditionalTime : EntityBase { Reason = reason; } + + public void Update(TimeSpan hours, string? reason = null) + { + Hours = hours; + Reason = reason; + } + + public bool HasChanged(TimeSpan newHours, string? newReason) + { + return Hours != newHours || Reason != newReason; + } }