CHANGE FIND ROTATING SHIFT FOR TIME DIFFERENCES
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user