CHANGE FIND ROTATING SHIFT FOR TIME DIFFERENCES

This commit is contained in:
MahanCh
2025-05-12 15:12:20 +03:30
parent 8d175920d5
commit 3c8f212825

View File

@@ -377,6 +377,7 @@ public class RollCallDomainService : IRollCallDomainService
var earlyEntryRollCallRotating = rollCallsInRotatingShift.OrderBy(x => x.StartDate).FirstOrDefault(x => x.StartDate < shift.start);
var lateEntryRollCallRotating = rollCallsInRotatingShift.OrderBy(x => x.StartDate).FirstOrDefault(x => x.StartDate > shift.start);
//برای خالی کردن اولیه حضور غیاب انتخاب شده
earlyEntryRollCallRotating?.SetEarlyEnter(TimeSpan.Zero);
if (earlyEntryRollCallRotating != null)
@@ -406,6 +407,7 @@ public class RollCallDomainService : IRollCallDomainService
var earlyExitRollCallRotating = rollCallsInRotatingShift.OrderByDescending(x => x.EndDate).FirstOrDefault(x => x.EndDate < shift.end);
var lateExitRollCallRotating = rollCallsInRotatingShift.OrderBy(x => x.EndDate).FirstOrDefault(x => x.EndDate > shift.end);
//برای خالی کردن اولیه حضور غیاب انتخاب شده
earlyExitRollCallRotating?.SetEarlyExit(TimeSpan.Zero);
@@ -564,42 +566,104 @@ public class RollCallDomainService : IRollCallDomainService
return shifts;
}).ToList();
var shiftScores = shiftDateTimes
//var shiftScores = shiftDateTimes
// .Select(shift =>
// {
// var totalOverlap = TimeSpan.Zero;
// var firstRollCall = rollCalls.MinBy(x => x.StartDate);
// var lastRollCall = rollCalls.MaxBy(x => x.EndDate);
// long totalStartDistance = Math.Abs((shift.Start - firstRollCall.StartDate).Ticks);
// long totalEndDistance = Math.Abs((shift.End - lastRollCall.EndDate).Ticks);
// foreach (var rollCall in rollCalls)
// {
// var start = rollCall.StartDate;
// var end = rollCall.EndDate;
// var overlapTicks = Math.Max(0,
// Math.Min(shift.End.Ticks, end.Ticks) -
// Math.Max(shift.Start.Ticks, start.Ticks));
// totalOverlap += new TimeSpan(overlapTicks);
// //totalStartDistance += Math.Abs((shift.Start - start).Ticks);
// //totalEndDistance += Math.Abs((shift.End - end).Ticks);
// }
// return new
// {
// Shift = shift,
// TotalOverlap = totalOverlap,
// TotalDistance = totalStartDistance + totalEndDistance,
// StartDistance = totalStartDistance,
// EndDistance = totalEndDistance
// };
// })
// .OrderBy(s => s.StartDistance)
// .ThenBy(s => s.TotalDistance)
// .ThenByDescending(s => s.TotalOverlap)
// .ThenBy(s => s.EndDistance);
// مرحله 1: گروه‌بندی بر اساس نزدیکی زمان شروع به اولین حضور و غیاب
var groupedByStart = shiftDateTimes
.GroupBy(shift =>
{
var firstRollCallStart = rollCalls.Min(x => x.StartDate);
var ticksDiff = Math.Abs((shift.Start - firstRollCallStart).Ticks);
return Math.Round(TimeSpan.FromTicks(ticksDiff).TotalMinutes / 30); // گروه‌بندی هر 30 دقیقه
})
.OrderBy(g => g.Key)
.First(); // نزدیک‌ترین گروه به شروع
// مرحله 2 (جایگزین مرحله ۴): گروه‌بندی بر اساس نزدیکی پایان شیفت به آخرین حضور و غیاب
var filteredByEnd = groupedByStart
.Select(shift =>
{
var lastRollCallEnd = rollCalls.Max(x => x.EndDate);
var endDistance = Math.Abs((shift.End - lastRollCallEnd).Ticks);
return new { Shift = shift, EndDistance = endDistance };
})
.GroupBy(x => x.EndDistance / TimeSpan.FromMinutes(30).Ticks) // گروه‌بندی هر 30 دقیقه
.OrderBy(g => g.Key)
.First() // نزدیک‌ترین پایان
.ToList();
// مرحله 3: فیلتر بر اساس بیشترین همپوشانی با حضور و غیاب‌ها
var filteredByOverlap = filteredByEnd
.Select(shift =>
{
var totalOverlap = TimeSpan.Zero;
long totalStartDistance = 0;
long totalEndDistance = 0;
foreach (var rollCall in rollCalls)
{
var start = rollCall.StartDate;
var end = rollCall.EndDate;
var overlapTicks = Math.Max(0,
Math.Min(shift.End.Ticks, end.Ticks) -
Math.Max(shift.Start.Ticks, start.Ticks));
Math.Min(shift.Shift.End.Ticks, rollCall.EndDate.Ticks) -
Math.Max(shift.Shift.Start.Ticks, rollCall.StartDate.Ticks));
totalOverlap += new TimeSpan(overlapTicks);
totalStartDistance += Math.Abs((shift.Start - start).Ticks);
totalEndDistance += Math.Abs((shift.End - end).Ticks);
}
return new
{
Shift = shift,
TotalOverlap = totalOverlap,
TotalDistance = totalStartDistance + totalEndDistance,
StartDistance = totalStartDistance,
EndDistance = totalEndDistance
};
return new { Shift = shift.Shift, TotalOverlap = totalOverlap };
})
.OrderByDescending(s => s.TotalOverlap)
.ThenBy(s => s.TotalDistance)
.ThenBy(s => s.StartDistance)
.ThenBy(s => s.EndDistance);
.GroupBy(x => Math.Round(x.TotalOverlap.TotalMinutes /5)) // گروه‌بندی همپوشانی
.OrderByDescending(g => g.Key) // بیشترین همپوشانی اول
.First()
.ToList();
var overlapChosenShift = shiftScores.First();
// مرحله 4 (جایگزین مرحله ۲): فیلتر نهایی بر اساس کمترین مجموع فاصله (TotalDistance)
var bestShift = filteredByOverlap
.Select(shift =>
{
var firstRollCall = rollCalls.MinBy(x => x.StartDate);
var lastRollCall = rollCalls.MaxBy(x => x.EndDate);
var totalDistance =
Math.Abs((shift.Shift.Start - firstRollCall.StartDate).Ticks) +
Math.Abs((shift.Shift.End - lastRollCall.EndDate).Ticks);
return new { Shift = shift.Shift, TotalDistance = totalDistance };
})
.OrderBy(x => x.TotalDistance) // کمترین فاصله کلی
.First(); // بهترین شیفت نهایی
var overlapChosenShift = bestShift;
var end = overlapChosenShift.Shift.End;
if (overlapChosenShift.Shift.End < overlapChosenShift.Shift.Start)
end = overlapChosenShift.Shift.End.AddDays(1);