add validation and management for additional time entries in SetTimeProjectCommand
This commit is contained in:
@@ -12,6 +12,7 @@ public record SetTimeProjectCommand(
|
|||||||
|
|
||||||
public class SetTimeSectionTime
|
public class SetTimeSectionTime
|
||||||
{
|
{
|
||||||
|
public Guid? Id { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public int Hours { get; set; }
|
public int Hours { get; set; }
|
||||||
public int Minutes { get; set; }
|
public int Minutes { get; set; }
|
||||||
|
|||||||
@@ -349,6 +349,15 @@ public class SetTimeProjectCommandHandler : IBaseCommandHandler<SetTimeProjectCo
|
|||||||
return OperationResult.Success();
|
return OperationResult.Success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ValidateTotalTimeNotLessThanSpent(TimeSpan newTotalTime, TimeSpan currentTotalSpent)
|
||||||
|
{
|
||||||
|
if (newTotalTime < currentTotalSpent)
|
||||||
|
{
|
||||||
|
throw new BadRequestException(
|
||||||
|
$"تایم کل سکشن نمیتواند کمتر از زمان مصرف شده ({currentTotalSpent.TotalHours:F2} ساعت) باشد");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SetSectionTime(TaskSection section, SetTimeProjectSkillItem sectionItem, long? addedByUserId)
|
private void SetSectionTime(TaskSection section, SetTimeProjectSkillItem sectionItem, long? addedByUserId)
|
||||||
{
|
{
|
||||||
var initData = sectionItem.InitData;
|
var initData = sectionItem.InitData;
|
||||||
@@ -363,18 +372,69 @@ public class SetTimeProjectCommandHandler : IBaseCommandHandler<SetTimeProjectCo
|
|||||||
// تنظیم زمان اولیه
|
// تنظیم زمان اولیه
|
||||||
section.UpdateInitialEstimatedHours(initialTime, initData.Description);
|
section.UpdateInitialEstimatedHours(initialTime, initData.Description);
|
||||||
|
|
||||||
section.ClearAdditionalTimes();
|
// مدیریت هوشمند زمانهای اضافی
|
||||||
// افزودن زمانهای اضافی
|
var existingAdditionalTimes = section.AdditionalTimes.ToList();
|
||||||
bool hasAdditionalTime = false;
|
var incomingAdditionalTimes = sectionItem.AdditionalTime ?? [];
|
||||||
foreach (var additionalTime in sectionItem.AdditionalTime)
|
var currentTotalSpent = section.GetTotalTimeSpent();
|
||||||
|
|
||||||
|
bool hasRealChange = false;
|
||||||
|
|
||||||
|
// حذف آیتمهایی که دیگر در لیست نیستند
|
||||||
|
foreach (var existingTime in existingAdditionalTimes)
|
||||||
{
|
{
|
||||||
var additionalTimeSpan = TimeSpan.FromHours(additionalTime.Hours).Add(TimeSpan.FromMinutes(additionalTime.Minutes));
|
var stillExists = incomingAdditionalTimes.Any(x => x.Id == existingTime.Id);
|
||||||
section.AddAdditionalTime(additionalTimeSpan, additionalTime.Description, addedByUserId);
|
if (!stillExists)
|
||||||
hasAdditionalTime = true;
|
{
|
||||||
|
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 باشد
|
// تغییر status به Incomplete فقط اگر تغییری واقعی اعمال شده باشد و در وضعیتی غیر از ReadyToStart باشد
|
||||||
if (hasAdditionalTime && section.Status != TaskSectionStatus.ReadyToStart)
|
if (hasRealChange && section.Status != TaskSectionStatus.ReadyToStart)
|
||||||
{
|
{
|
||||||
// اگر سکشن درحال انجام است، باید متوقف شود قبل از تغییر status
|
// اگر سکشن درحال انجام است، باید متوقف شود قبل از تغییر status
|
||||||
if (section.Status == TaskSectionStatus.InProgress)
|
if (section.Status == TaskSectionStatus.InProgress)
|
||||||
|
|||||||
@@ -26,4 +26,15 @@ public class TaskSectionAdditionalTime : EntityBase<Guid>
|
|||||||
{
|
{
|
||||||
Reason = reason;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user