From fbf367677ce7f0cfa9016a013358781f445bb69e Mon Sep 17 00:00:00 2001 From: MahanCh Date: Thu, 8 May 2025 12:16:26 +0330 Subject: [PATCH] Change rollcall rotating shift TimeDifferences --- .../DomainService/IRollCallDomainService.cs | 116 ++++++++++-------- .../RollCallApplication.cs | 12 ++ .../Repository/RollCallMandatoryRepository.cs | 96 ++++++++------- .../Pages/Company/AndroidApk/Index.cshtml.cs | 14 ++- 4 files changed, 141 insertions(+), 97 deletions(-) diff --git a/Company.Domain/RollCallAgg/DomainService/IRollCallDomainService.cs b/Company.Domain/RollCallAgg/DomainService/IRollCallDomainService.cs index 100af86d..9c13b981 100644 --- a/Company.Domain/RollCallAgg/DomainService/IRollCallDomainService.cs +++ b/Company.Domain/RollCallAgg/DomainService/IRollCallDomainService.cs @@ -15,6 +15,7 @@ using System.Threading.Tasks; using _0_Framework.Application; using OfficeOpenXml; using OfficeOpenXml.Drawing.Chart; +using System.Collections; namespace Company.Domain.RollCallAgg.DomainService; @@ -25,7 +26,7 @@ public interface IRollCallDomainService long workshopId); TimeOnly GetEmployeeOffSetForRegularSettings(long employeeId, long workshopId); - DateTime GetEmployeeShiftDateByRollCallStartDate(long workshopId, long employeeId, DateTime rollCallStartDate,DateTime rollCallEndDate); + DateTime GetEmployeeShiftDateByRollCallStartDate(long workshopId, long employeeId, DateTime rollCallStartDate, DateTime rollCallEndDate); void CalculateTimeDifferences(RollCall rollCall); @@ -173,16 +174,16 @@ public class RollCallDomainService : IRollCallDomainService } public DateTime GetEmployeeShiftDateByRollCallStartDate(long workshopId, long employeeId, - DateTime rollCallStartDate,DateTime rollCallEndDate) + DateTime rollCallStartDate, DateTime rollCallEndDate) { var shiftDetails = GetEmployeeShiftDetails(employeeId, workshopId); - + var offset = GetEmployeeOffSetForRegularSettings(employeeId, workshopId); return shiftDetails.shiftType switch { WorkshopShiftStatus.Regular => CalculateRegularShiftDate(rollCallStartDate, offset), - WorkshopShiftStatus.Rotating => FindRotatingShift(rollCallStartDate,rollCallEndDate,shiftDetails.rotatingShifts).start.Date, + WorkshopShiftStatus.Rotating => FindRotatingShift(rollCallStartDate, rollCallEndDate, shiftDetails.rotatingShifts).start.Date, WorkshopShiftStatus.Irregular => rollCallStartDate.Date, _ => throw new ArgumentOutOfRangeException() }; @@ -216,6 +217,7 @@ public class RollCallDomainService : IRollCallDomainService rollCalls.Remove(deletedRollCall); rollCalls.Add(rollCall); + rollCall.ClearTimeDiff(); switch (shiftDetails.shiftType) { case WorkshopShiftStatus.Regular: @@ -255,8 +257,9 @@ public class RollCallDomainService : IRollCallDomainService var earlyEntryRollCall = rollCallsInShift.OrderBy(x => x.StartDate).FirstOrDefault(x => x.StartDate < employeeShift.start); var lateEntryRollCall = rollCallsInShift.OrderBy(x => x.StartDate).FirstOrDefault(x => x.StartDate > employeeShift.start); + + - var previousShift = employeeShifts.OrderByDescending(x => x.start) .FirstOrDefault(x => x.end < employeeShift.start); @@ -299,8 +302,6 @@ public class RollCallDomainService : IRollCallDomainService var lateExitRollCall = rollCallsInShift.OrderBy(x => x.EndDate).FirstOrDefault(x => x.EndDate > employeeShift.end); - - // تعجیل در خروج - زود رفتن var nextShift = employeeShifts.OrderBy(x => x.start) .FirstOrDefault(x => x.start > employeeShift.end); @@ -373,8 +374,8 @@ 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?.ClearTimeDiff(); + lateEntryRollCallRotating?.ClearTimeDiff(); if (earlyEntryRollCallRotating != null) { @@ -403,9 +404,10 @@ 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?.ClearTimeDiff(); + lateExitRollCallRotating?.ClearTimeDiff(); - if (earlyExitRollCallRotating != null && (rollCallsInRotatingShift.Any(x => x.StartDate < rotatingShiftEnd && x.StartDate > earlyExitRollCallRotating.EndDate) == false)) @@ -453,10 +455,10 @@ public class RollCallDomainService : IRollCallDomainService DateTime startEntryWithDate = startDate.Add(startRollCall.TimeOfDay); DateTime endEntryWithDate = endDate.Add(endRollCall.TimeOfDay); - DateTime oneHourBeforeStart = startEntryWithDate.AddHours(-1); - DateTime oneHourAfterStart = startEntryWithDate.AddHours(1); - DateTime oneHourBeforeEnd = endEntryWithDate.AddHours(-1); - DateTime oneHourAfterEnd = endEntryWithDate.AddHours(1); + DateTime twoHourBeforeStart = startEntryWithDate.AddHours(-2); + DateTime twoHourAfterStart = startEntryWithDate.AddHours(2); + DateTime twoHourBeforeEnd = endEntryWithDate.AddHours(-2); + DateTime twoHourAfterEnd = endEntryWithDate.AddHours(2); var shiftDateTimes = rotatingShifts.SelectMany(shift => @@ -477,56 +479,68 @@ public class RollCallDomainService : IRollCallDomainService #region مقایسه شروع حضور غیاب با شیفت - var startFilteredTimes = shiftDateTimes.Where(shift => - (oneHourBeforeStart <= shift.Start && oneHourAfterStart >= shift.Start) || - (oneHourBeforeStart <= shift.End && oneHourAfterStart >= shift.End)).ToList(); + //var startFilteredTimes = shiftDateTimes.Where(shift => + // (twoHourBeforeStart <= shift.Start && twoHourAfterStart >= shift.Start) || + // (twoHourBeforeStart <= shift.End && twoHourAfterStart >= shift.End)).ToList(); - if (startFilteredTimes.Count == 0) - { - startFilteredTimes = shiftDateTimes; - } - else if (startFilteredTimes.Count == 1) - { - var startChosenShift = startFilteredTimes.First(); + //if (startFilteredTimes.Count == 0) + //{ + // startFilteredTimes = shiftDateTimes; + //} + //else if (startFilteredTimes.Count == 1) + //{ + // var startChosenShift = startFilteredTimes.First(); - if (startChosenShift.End < startChosenShift.Start) - startChosenShift.End = startChosenShift.End.AddDays(1); + // if (startChosenShift.End < startChosenShift.Start) + // startChosenShift.End = startChosenShift.End.AddDays(1); - return startChosenShift; - } + // return startChosenShift; + //} - #endregion + //#endregion - #region مقایسه پایان حضورغیاب با شیفت - - var endFilteredTimes = shiftDateTimes.Where(shift => - (oneHourBeforeEnd <= shift.Start && oneHourAfterEnd >= shift.Start) || - (oneHourBeforeEnd <= shift.End && oneHourAfterEnd >= shift.End)).ToList(); - if (endFilteredTimes.Count == 0) - { - endFilteredTimes = startFilteredTimes; - } - else if (endFilteredTimes.Count == 1) - { - var endChosenShift = endFilteredTimes.First(); - return endChosenShift; - } + //#region مقایسه پایان حضورغیاب با شیفت + //var endFilteredTimes = shiftDateTimes.Where(shift => + // (twoHourBeforeEnd <= shift.Start && twoHourAfterEnd >= shift.Start) || + // (twoHourBeforeEnd <= shift.End && twoHourAfterEnd >= shift.End)).ToList(); + //if (endFilteredTimes.Count == 0) + //{ + // endFilteredTimes = startFilteredTimes; + //} + //else if (endFilteredTimes.Count == 1) + //{ + // var endChosenShift = endFilteredTimes.First(); + // return endChosenShift; + //} #endregion #region اشتراک حضور غیاب و شیفت - var overlapShifts = endFilteredTimes.Select(shift => new - { - Shift = shift, - Overlap = new TimeSpan(Math.Max(0, - Math.Min(shift.End.Ticks, oneHourAfterEnd.Ticks) - - Math.Max(shift.Start.Ticks, oneHourBeforeStart.Ticks))) - }); + var overlapShifts = shiftDateTimes + .Select(shift => new + { + Shift = shift, + Overlap = new TimeSpan(Math.Max(0, + Math.Min(shift.End.Ticks, endRollCall.Ticks) - + Math.Max(shift.Start.Ticks, startRollCall.Ticks))), + // زمان حضور فرد در شیفت (مجموع Overlap با شیفت) + TotalTimeInShift = new TimeSpan(Math.Max(0, + Math.Min(shift.End.Ticks, endRollCall.Ticks) - + Math.Max(shift.Start.Ticks, startRollCall.Ticks))), + StartDistance = Math.Abs((shift.Start - startRollCall).Ticks), + EndDistance = Math.Abs((shift.End - endRollCall).Ticks), + TotalDistance = Math.Abs((shift.Start - startRollCall).Ticks) + Math.Abs((shift.End - endRollCall).Ticks) + }) + .OrderByDescending(s => s.TotalTimeInShift) // 1. بیشترین زمان حضور فرد + .ThenByDescending(s => s.Overlap) // 2. بیشترین Overlap + .ThenBy(s => s.TotalDistance) + .ThenBy(s => s.StartDistance) + .ThenBy(x => x.EndDistance); // 3. اگر برابر بود، Start نزدیک‌تر - var overlapChosenShift = overlapShifts.MaxBy(s => s.Overlap); + var overlapChosenShift = overlapShifts.First(); var end = overlapChosenShift.Shift.End; if (overlapChosenShift.Shift.End < overlapChosenShift.Shift.Start) end = overlapChosenShift.Shift.End.AddDays(1); diff --git a/CompanyManagment.Application/RollCallApplication.cs b/CompanyManagment.Application/RollCallApplication.cs index 9b84101c..e97a8282 100644 --- a/CompanyManagment.Application/RollCallApplication.cs +++ b/CompanyManagment.Application/RollCallApplication.cs @@ -504,6 +504,12 @@ public class RollCallApplication : IRollCallApplication _rollCallRepository.AddRange(rollCallsAsEntityModels); _rollCallRepository.SaveChanges(); foreach (var rollCallsAsEntityModel in rollCallsAsEntityModels) + { + rollCallsAsEntityModel.ClearTimeDiff(); + rollCallsAsEntityModel.SetShiftDate(_rollCallDomainService); + } + _rollCallRepository.SaveChanges(); + foreach (var rollCallsAsEntityModel in rollCallsAsEntityModels) { rollCallsAsEntityModel.Edit(rollCallsAsEntityModel.StartDate.Value, rollCallsAsEntityModel.EndDate.Value, _rollCallDomainService); } @@ -673,6 +679,12 @@ public class RollCallApplication : IRollCallApplication _rollCallRepository.AddRange(rollCallsAsEntityModels); _rollCallRepository.SaveChanges(); + foreach (var rollCallsAsEntityModel in rollCallsAsEntityModels) + { + rollCallsAsEntityModel.ClearTimeDiff(); + rollCallsAsEntityModel.SetShiftDate(_rollCallDomainService); + } + _rollCallRepository.SaveChanges(); foreach (var rollCallsAsEntityModel in rollCallsAsEntityModels) { diff --git a/CompanyManagment.EFCore/Repository/RollCallMandatoryRepository.cs b/CompanyManagment.EFCore/Repository/RollCallMandatoryRepository.cs index 42131f83..44e58ff4 100644 --- a/CompanyManagment.EFCore/Repository/RollCallMandatoryRepository.cs +++ b/CompanyManagment.EFCore/Repository/RollCallMandatoryRepository.cs @@ -3815,7 +3815,7 @@ CreateWorkingHoursTemp command, bool holidayWorking) public static (DateTime start, DateTime end) FindRotatingShift(DateTime startRollCall, DateTime endRollCall, - ICollection rotatingShifts) + ICollection rotatingShifts) { DateTime startDate = startRollCall.Date; DateTime endDate = endRollCall.Date; @@ -3825,10 +3825,10 @@ CreateWorkingHoursTemp command, bool holidayWorking) DateTime startEntryWithDate = startDate.Add(startRollCall.TimeOfDay); DateTime endEntryWithDate = endDate.Add(endRollCall.TimeOfDay); - DateTime oneHourBeforeStart = startEntryWithDate.AddHours(-1); - DateTime oneHourAfterStart = startEntryWithDate.AddHours(1); - DateTime oneHourBeforeEnd = endEntryWithDate.AddHours(-1); - DateTime oneHourAfterEnd = endEntryWithDate.AddHours(1); + DateTime twoHourBeforeStart = startEntryWithDate.AddHours(-2); + DateTime twoHourAfterStart = startEntryWithDate.AddHours(2); + DateTime twoHourBeforeEnd = endEntryWithDate.AddHours(-2); + DateTime twoHourAfterEnd = endEntryWithDate.AddHours(2); var shiftDateTimes = rotatingShifts.SelectMany(shift => @@ -3849,56 +3849,68 @@ CreateWorkingHoursTemp command, bool holidayWorking) #region مقایسه شروع حضور غیاب با شیفت - var startFilteredTimes = shiftDateTimes.Where(shift => - (oneHourBeforeStart <= shift.Start && oneHourAfterStart >= shift.Start) || - (oneHourBeforeStart <= shift.End && oneHourAfterStart >= shift.End)).ToList(); + //var startFilteredTimes = shiftDateTimes.Where(shift => + // (twoHourBeforeStart <= shift.Start && twoHourAfterStart >= shift.Start) || + // (twoHourBeforeStart <= shift.End && twoHourAfterStart >= shift.End)).ToList(); - if (startFilteredTimes.Count == 0) - { - startFilteredTimes = shiftDateTimes; - } - else if (startFilteredTimes.Count == 1) - { - var startChosenShift = startFilteredTimes.First(); + //if (startFilteredTimes.Count == 0) + //{ + // startFilteredTimes = shiftDateTimes; + //} + //else if (startFilteredTimes.Count == 1) + //{ + // var startChosenShift = startFilteredTimes.First(); - if (startChosenShift.End < startChosenShift.Start) - startChosenShift.End = startChosenShift.End.AddDays(1); + // if (startChosenShift.End < startChosenShift.Start) + // startChosenShift.End = startChosenShift.End.AddDays(1); - return startChosenShift; - } + // return startChosenShift; + //} - #endregion + //#endregion - #region مقایسه پایان حضورغیاب با شیفت - - var endFilteredTimes = shiftDateTimes.Where(shift => - (oneHourBeforeEnd <= shift.Start && oneHourAfterEnd >= shift.Start) || - (oneHourBeforeEnd <= shift.End && oneHourAfterEnd >= shift.End)).ToList(); - if (endFilteredTimes.Count == 0) - { - endFilteredTimes = startFilteredTimes; - } - else if (endFilteredTimes.Count == 1) - { - var endChosenShift = endFilteredTimes.First(); - return endChosenShift; - } + //#region مقایسه پایان حضورغیاب با شیفت + //var endFilteredTimes = shiftDateTimes.Where(shift => + // (twoHourBeforeEnd <= shift.Start && twoHourAfterEnd >= shift.Start) || + // (twoHourBeforeEnd <= shift.End && twoHourAfterEnd >= shift.End)).ToList(); + //if (endFilteredTimes.Count == 0) + //{ + // endFilteredTimes = startFilteredTimes; + //} + //else if (endFilteredTimes.Count == 1) + //{ + // var endChosenShift = endFilteredTimes.First(); + // return endChosenShift; + //} #endregion #region اشتراک حضور غیاب و شیفت - var overlapShifts = endFilteredTimes.Select(shift => new - { - Shift = shift, - Overlap = new TimeSpan(Math.Max(0, - Math.Min(shift.End.Ticks, oneHourAfterEnd.Ticks) - - Math.Max(shift.Start.Ticks, oneHourBeforeStart.Ticks))) - }); + var overlapShifts = shiftDateTimes + .Select(shift => new + { + Shift = shift, + Overlap = new TimeSpan(Math.Max(0, + Math.Min(shift.End.Ticks, endRollCall.Ticks) - + Math.Max(shift.Start.Ticks, startRollCall.Ticks))), + // زمان حضور فرد در شیفت (مجموع Overlap با شیفت) + TotalTimeInShift = new TimeSpan(Math.Max(0, + Math.Min(shift.End.Ticks, endRollCall.Ticks) - + Math.Max(shift.Start.Ticks, startRollCall.Ticks))), + StartDistance = Math.Abs((shift.Start - startRollCall).Ticks), + EndDistance = Math.Abs((shift.End - endRollCall).Ticks), + TotalDistance = Math.Abs((shift.Start - startRollCall).Ticks) + Math.Abs((shift.End - endRollCall).Ticks) + }) + .OrderByDescending(s => s.TotalTimeInShift) // 1. بیشترین زمان حضور فرد + .ThenByDescending(s => s.Overlap) // 2. بیشترین Overlap + .ThenBy(s => s.TotalDistance) + .ThenBy(s => s.StartDistance) + .ThenBy(x => x.EndDistance); // 3. اگر برابر بود، Start نزدیک‌تر - var overlapChosenShift = overlapShifts.MaxBy(s => s.Overlap); + var overlapChosenShift = overlapShifts.First(); var end = overlapChosenShift.Shift.End; if (overlapChosenShift.Shift.End < overlapChosenShift.Shift.Start) end = overlapChosenShift.Shift.End.AddDays(1); diff --git a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs index 289d337f..c5ba8e2d 100644 --- a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs +++ b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs @@ -59,9 +59,9 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk public IActionResult OnPostShiftDateNew() { - var startRollCall = new DateTime(2025, 3, 21); - var rollCalls = _context.RollCalls.Where(x => x.ShiftDate >= startRollCall && x.EndDate != null).ToList(); - var r1 = rollCalls.Take(10000).ToList(); + var startRollCall = new DateTime(2025, 4, 21); + var rollCalls = _context.RollCalls.Where(x => x.ShiftDate >= startRollCall && x.EndDate != null ).ToList(); + var r1 = rollCalls.ToList(); Console.ForegroundColor = ConsoleColor.DarkRed; Console.WriteLine("endStep 1 ============"); @@ -294,9 +294,15 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk var endedRollCalls2 = r1.Where(x => x.EndDate != null).ToList(); var countSetTDRollCall = endedRollCalls2.Count; var stepSetTDRollCal = 1; + + foreach (var rollCall in endedRollCalls2) + { + rollCall.ClearTimeDiff(); + } + _context.SaveChanges(); foreach (var endedRollCall in endedRollCalls2) { - endedRollCall.SetShiftDate(_rollCallDomainService); + endedRollCall.Edit(endedRollCall.StartDate.Value, endedRollCall.EndDate.Value, _rollCallDomainService); Console.WriteLine($"{stepSetTDRollCal} - {countSetTDRollCall} ended Set Time Differences{endedRollCall.id}"); stepSetTDRollCal += 1; }