diff --git a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs index 73afdd1f..b2b0319b 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs +++ b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs @@ -703,10 +703,10 @@ public class IndexModel : PageModel DateTime lastMonthEnd = ($"{DateTime.Now.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime().AddDays(-1); if (lastMonthEnd == endSearch) { - var countWorkFlowCut = (await _workFlowApplication.GetCountCutRollCallByBgService(WorkshopId)); - var countWorkFlowAbsent = (await _workFlowApplication.GetAbsentRollCallWorkFlows(WorkshopId)).Count(); - var countWorkFlowLunchBreak = (await _workFlowApplication.GetEmployeesWithoutLunchBreak(WorkshopId)).Count(); - var countUndefinedRollCalls = (await _workFlowApplication.GetUndefinedRollCalls(WorkshopId)).Count(); + var countWorkFlowCut = await _workFlowApplication.CountCutByBgServiceLastMonth(WorkshopId); + var countWorkFlowAbsent = await _workFlowApplication.CountAbsentRollCallLastMonth(WorkshopId); + var countWorkFlowLunchBreak = await _workFlowApplication.CountEmployeesWithoutLunchBreakLastMonth(WorkshopId); + var countUndefinedRollCalls = await _workFlowApplication.CountUndefinedLastMonth(WorkshopId); hasWorkFlow = countWorkFlowCut > 0 || countWorkFlowAbsent > 0 || countWorkFlowLunchBreak > 0 || countUndefinedRollCalls > 0; diff --git a/WorkFlow/Application/WorkFlow.Application.Contracts/WorkFlow/IWorkFlowApplication.cs b/WorkFlow/Application/WorkFlow.Application.Contracts/WorkFlow/IWorkFlowApplication.cs index 518c2ee4..e000f514 100644 --- a/WorkFlow/Application/WorkFlow.Application.Contracts/WorkFlow/IWorkFlowApplication.cs +++ b/WorkFlow/Application/WorkFlow.Application.Contracts/WorkFlow/IWorkFlowApplication.cs @@ -36,7 +36,41 @@ public interface IWorkFlowApplication Task> GetUndefinedRollCalls(long workshopId); + #region CountWorkFlowForCheckout + /// + /// شمارنده کات شده توسط سیستم کارپوشه + /// برای ایجاد تصفیه حساب + /// + /// + /// + Task CountCutByBgServiceLastMonth(long workshopId); - Task> GetEmployeesWithoutLunchBreak(long workshopId); + /// + /// شمارنده غیبت کارپوشه + /// برای ایجاد تصفیه حساب + /// + /// + /// + Task CountAbsentRollCallLastMonth(long workshopId); + + /// + /// شمارنده عدم ثبت استراحت کارپوشه + /// برای ایجاد تصفیه حساب + /// + /// + /// + Task CountEmployeesWithoutLunchBreakLastMonth(long workshopId); + + /// + /// شمارنده ثبت نامشخص کارپوشه + /// برای ایجاد تصفیه حساب + /// + /// + /// + Task CountUndefinedLastMonth(long workshopId); + #endregion + + + Task> GetEmployeesWithoutLunchBreak(long workshopId); Task> GetEmployeesWithoutGroup(long workshopId); } \ No newline at end of file diff --git a/WorkFlow/Application/WorkFlow.Application/WorkFlowApplication.cs b/WorkFlow/Application/WorkFlow.Application/WorkFlowApplication.cs index 45cba30a..9bed52c5 100644 --- a/WorkFlow/Application/WorkFlow.Application/WorkFlowApplication.cs +++ b/WorkFlow/Application/WorkFlow.Application/WorkFlowApplication.cs @@ -65,10 +65,10 @@ public class WorkFlowApplication : IWorkFlowApplication return op.Succcedded(); } - public async Task GetCountAllWorkFlows(long workshopId,long accountId) + public async Task GetCountAllWorkFlows(long workshopId, long accountId) { int count = 0; - count += await GetAllWorkFlowCount(workshopId,accountId); + count += await GetAllWorkFlowCount(workshopId, accountId); return count; } public Task GetRollCallAbsentsWorkFlows(long workshopId) @@ -84,28 +84,28 @@ public class WorkFlowApplication : IWorkFlowApplication return (await GetRollCallWorkFlowsCutByBgService(workshopId)).Count; } - - public async Task GetAllWorkFlowCount(long workshopId,long accountId) + + public async Task GetAllWorkFlowCount(long workshopId, long accountId) { - var count = 0; - // RollCall + var count = 0; + // RollCall - count += await GetAllRollCallCount(workshopId); + count += await GetAllRollCallCount(workshopId); - count += await GetAllEmployeeDocuments(workshopId,accountId ); + count += await GetAllEmployeeDocuments(workshopId, accountId); - // Employee Documents - + // Employee Documents - return count; + + return count; } public async Task GetAllEmployeeDocuments(long workshopId, long accountId) { - int count = 0; - count += (await _employeeDocumentsApplication.GetClientRejectedDocumentForClient(workshopId, accountId)).Count; - return count; + int count = 0; + count += (await _employeeDocumentsApplication.GetClientRejectedDocumentForClient(workshopId, accountId)).Count; + return count; } public Task GetAllWorkFlowCountAsync(long workshopId) @@ -115,19 +115,19 @@ public class WorkFlowApplication : IWorkFlowApplication public async Task GetAllRollCallCount(long workshopId) { - int count = 0; - var activeServiceByWorkshopId = _rollCallACL.GetActiveServiceByWorkshopId(workshopId); - if (activeServiceByWorkshopId == null) - { - return count; - } - //count += _rollCallACL.GetRollCallAbsentsWorkFlows(accId, workshopId); - count += (await GetAbsentRollCallWorkFlows(workshopId))?.Count ?? 0; - count += (await GetRollCallWorkFlowsCutByBgService(workshopId))?.Count ?? 0; - count += (await GetEmployeesWithoutLunchBreak(workshopId))?.Count ?? 0; - //count += (await GetRollCallsOverlappingLeaves(workshopId))?.Count ?? 0; - count += (await GetUndefinedRollCalls(workshopId))?.Count ?? 0; - return count; + int count = 0; + var activeServiceByWorkshopId = _rollCallACL.GetActiveServiceByWorkshopId(workshopId); + if (activeServiceByWorkshopId == null) + { + return count; + } + //count += _rollCallACL.GetRollCallAbsentsWorkFlows(accId, workshopId); + count += (await GetAbsentRollCallWorkFlows(workshopId))?.Count ?? 0; + count += (await GetRollCallWorkFlowsCutByBgService(workshopId))?.Count ?? 0; + count += (await GetEmployeesWithoutLunchBreak(workshopId))?.Count ?? 0; + //count += (await GetRollCallsOverlappingLeaves(workshopId))?.Count ?? 0; + count += (await GetUndefinedRollCalls(workshopId))?.Count ?? 0; + return count; } #region Methods For Ajax @@ -170,7 +170,7 @@ public class WorkFlowApplication : IWorkFlowApplication { DateTime = date.Date, DateTimeFa = date.ToFarsi(), - + }; //dont count absences before the last checkout @@ -193,7 +193,7 @@ public class WorkFlowApplication : IWorkFlowApplication - FilterWithOffset(workshopId, date,ref newItem); + FilterWithOffset(workshopId, date, ref newItem); newItem.DayOfWeekFa = newItem.DateTime.DayOfWeek.DayOfWeeKToPersian(); @@ -201,17 +201,17 @@ public class WorkFlowApplication : IWorkFlowApplication return newItem; } - private void FilterWithOffset(long workshopId, DateTime date,ref DailyRollCallWorkFlowViewModel dailyRollCall) + private void FilterWithOffset(long workshopId, DateTime date, ref DailyRollCallWorkFlowViewModel dailyRollCall) { - if(date.Date == DateTime.Now.Date.AddDays(-1)) - { - foreach (var item in dailyRollCall.RollCallWorkFlowPerDayViewModels.ToList()) - { - var employeeOffset = _rollCallDomainService.GetEmployeeOffSetForRegularSettings(item.EmployeeId, workshopId); - if (DateTime.Now < DateTime.Today + employeeOffset.ToTimeSpan()) - dailyRollCall.RollCallWorkFlowPerDayViewModels.Remove(item); - } - } + if (date.Date == DateTime.Now.Date.AddDays(-1)) + { + foreach (var item in dailyRollCall.RollCallWorkFlowPerDayViewModels.ToList()) + { + var employeeOffset = _rollCallDomainService.GetEmployeeOffSetForRegularSettings(item.EmployeeId, workshopId); + if (DateTime.Now < DateTime.Today + employeeOffset.ToTimeSpan()) + dailyRollCall.RollCallWorkFlowPerDayViewModels.Remove(item); + } + } } /// @@ -371,202 +371,358 @@ public class WorkFlowApplication : IWorkFlowApplication #region Methods For OnGet - /// - /// لیست تداخل مرخصی و حضور - /// - public async Task> GetRollCallsOverlappingLeaves(long workshopId) + /// + /// لیست تداخل مرخصی و حضور + /// + public async Task> GetRollCallsOverlappingLeaves(long workshopId) + { + var now = DateTime.Now; + DateTime.Now.Date.AddMonthsFa(-2, out var twoMonthsAgo); + var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); + var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); + var rollCalls = _rollCallACL.GetRollCallsOverlappingLeaves(workshopId, twoMonthsAgo, now); + return rollCalls + .Select(x => new DailyWorkFlowEmployeesWithRollCallOnLeaveViewModel() + { + Date = x.Date, + DateFa = x.DateFa, + EmployeesList = x.EmployeesList + .Where(y => !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && + z.CheckoutStart.Date <= x.Date.Date && + z.CheckoutEnd.Date >= x.Date.Date) && activeEmployees.Any(z => y.EmployeeId == z.EmployeeId)) + .Select(e => new WorkFlowEmployeeWithRollCallOnLeaveViewModel() + { + EmployeeId = e.EmployeeId, + EmployeeFullName = e.EmployeeFullName, + LeaveId = e.LeaveId, + EndOfOverlapTime = e.EndOfOverlapTime, + StartOfOverlapTime = e.StartOfOverlapTime, + RollCallId = e.RollCallId, + EndOfOverlapDateFa = e.EndOfOverlapDateFa, + EndOfOverlapDateTime = e.EndOfOverlapDateTime, + StartOfOverlapDateFa = e.StartOfOverlapDateFa, + StartOfOverlapDateTime = e.StartOfOverlapDateTime + }).ToList(), + DayOfWeek = x.DayOfWeek + }) + .Where(y => y.EmployeesList != null && y.EmployeesList.Any()) + .OrderBy(x => x.Date).ToList(); + + + } + + /// + /// لیست وضعیت تردد پرسنل + /// + public async Task> GetUndefinedRollCalls(long workshopId) + { + var now = DateTime.Now; + + DateTime.Now.Date.AddMonthsFa(-2, out var twoMonthsAgo); + + var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); + List rollCalls = _rollCallACL.GetUndefinedRollCalls(workshopId, twoMonthsAgo, now.AddDays(-1).Date); + var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); + return rollCalls.Select(x => new DailyRollCallWorkFlowViewModel() { - var now = DateTime.Now; - DateTime.Now.Date.AddMonthsFa(-2, out var twoMonthsAgo); - var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); - var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); - var rollCalls = _rollCallACL.GetRollCallsOverlappingLeaves(workshopId, twoMonthsAgo, now); - return rollCalls - .Select(x => new DailyWorkFlowEmployeesWithRollCallOnLeaveViewModel() - { - Date = x.Date, - DateFa = x.DateFa, - EmployeesList = x.EmployeesList - .Where(y => !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && - z.CheckoutStart.Date <= x.Date.Date && - z.CheckoutEnd.Date >= x.Date.Date) && activeEmployees.Any(z => y.EmployeeId == z.EmployeeId)) - .Select(e => new WorkFlowEmployeeWithRollCallOnLeaveViewModel() - { - EmployeeId = e.EmployeeId, - EmployeeFullName = e.EmployeeFullName, - LeaveId = e.LeaveId, - EndOfOverlapTime = e.EndOfOverlapTime, - StartOfOverlapTime = e.StartOfOverlapTime, - RollCallId = e.RollCallId, - EndOfOverlapDateFa = e.EndOfOverlapDateFa, - EndOfOverlapDateTime = e.EndOfOverlapDateTime, - StartOfOverlapDateFa = e.StartOfOverlapDateFa, - StartOfOverlapDateTime = e.StartOfOverlapDateTime - }).ToList(), - DayOfWeek = x.DayOfWeek - }) - .Where(y => y.EmployeesList != null && y.EmployeesList.Any()) - .OrderBy(x => x.Date).ToList(); + DateTime = x.DateTime, + DateTimeFa = x.DateTimeFa, + RollCallWorkFlowPerDayViewModels = x.RollCallWorkFlowPerDayViewModels + .Where(y => + !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && z.CheckoutStart.Date <= x.DateTime.Date && + z.CheckoutEnd.Date >= x.DateTime.Date) && + activeEmployees.Any(z => z.EmployeeId == y.EmployeeId && x.DateTime.Date >= z.startActive && + x.DateTime.Date <= z.endActive)) + .ToList(), + DayOfWeekFa = x.DateTime.DayOfWeek.DayOfWeeKToPersian() + }).Where(y => y.RollCallWorkFlowPerDayViewModels != null && y.RollCallWorkFlowPerDayViewModels.Any()).OrderBy(x => x.DateTime).ToList(); + } + /// + /// لیست قطع شده توسط سیستم + /// + public async Task> GetRollCallWorkFlowsCutByBgService(long workshopId) + { + var now = DateTime.Now; - } + DateTime.Now.Date.AddMonthsFa(-2, out var twoMonthsAgo); - /// - /// لیست وضعیت تردد پرسنل - /// - public async Task> GetUndefinedRollCalls(long workshopId) + var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); + var rollCalls = _rollCallACL.GetRollCallWorkFlowsCutByBgService(workshopId, twoMonthsAgo, now.AddDays(-1).Date); + var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); + return rollCalls.Select(x => new DailyRollCallWorkFlowViewModel() { - var now = DateTime.Now; + DateTime = x.DateTime, + DateTimeFa = x.DateTimeFa, + RollCallWorkFlowPerDayViewModels = x.RollCallWorkFlowPerDayViewModels + .Where(y => !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && z.CheckoutStart.Date <= x.DateTime.Date && + z.CheckoutEnd.Date >= x.DateTime.Date) && activeEmployees.Any(z => z.EmployeeId == y.EmployeeId && x.DateTime.Date >= z.startActive && + x.DateTime.Date <= z.endActive)) + .ToList(), + DayOfWeekFa = x.DateTime.DayOfWeek.DayOfWeeKToPersian() + }).Where(y => y.RollCallWorkFlowPerDayViewModels != null && y.RollCallWorkFlowPerDayViewModels.Any()) + .OrderBy(x => x.DateTime).ToList(); + } - DateTime.Now.Date.AddMonthsFa(-2, out var twoMonthsAgo); + #region CountForCreateCheckout - var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); - List rollCalls = _rollCallACL.GetUndefinedRollCalls(workshopId, twoMonthsAgo, now.AddDays(-1).Date); - var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); - return rollCalls.Select(x => new DailyRollCallWorkFlowViewModel() + public async Task CountCutByBgServiceLastMonth(long workshopId) + { + DateTime lastMonthEnd = ($"{DateTime.Now.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime().AddDays(-1); + var now = lastMonthEnd; + var twoMonthsAgo = ($"{lastMonthEnd.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime(); + + + var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); + var rollCalls = _rollCallACL.GetRollCallWorkFlowsCutByBgService(workshopId, twoMonthsAgo, now.AddDays(-1).Date); + var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); + return rollCalls.Select(x => new DailyRollCallWorkFlowViewModel() { DateTime = x.DateTime, DateTimeFa = x.DateTimeFa, RollCallWorkFlowPerDayViewModels = x.RollCallWorkFlowPerDayViewModels - .Where(y => - !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && z.CheckoutStart.Date <= x.DateTime.Date && - z.CheckoutEnd.Date >= x.DateTime.Date) && - activeEmployees.Any(z => z.EmployeeId == y.EmployeeId && x.DateTime.Date >= z.startActive && - x.DateTime.Date <= z.endActive)) - .ToList(), - DayOfWeekFa = x.DateTime.DayOfWeek.DayOfWeeKToPersian() - }).Where(y => y.RollCallWorkFlowPerDayViewModels != null && y.RollCallWorkFlowPerDayViewModels.Any()).OrderBy(x => x.DateTime).ToList(); - } - - /// - /// لیست قطع شده توسط سیستم - /// - public async Task> GetRollCallWorkFlowsCutByBgService(long workshopId) - { - var now = DateTime.Now; - - DateTime.Now.Date.AddMonthsFa(-2, out var twoMonthsAgo); - - var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); - var rollCalls = _rollCallACL.GetRollCallWorkFlowsCutByBgService(workshopId, twoMonthsAgo, now.AddDays(-1).Date); - var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); - return rollCalls.Select(x => new DailyRollCallWorkFlowViewModel() - { - DateTime = x.DateTime, - DateTimeFa = x.DateTimeFa, - RollCallWorkFlowPerDayViewModels = x.RollCallWorkFlowPerDayViewModels - .Where(y => !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && z.CheckoutStart.Date <= x.DateTime.Date && - z.CheckoutEnd.Date >= x.DateTime.Date) && activeEmployees.Any(z => z.EmployeeId == y.EmployeeId && x.DateTime.Date >= z.startActive && - x.DateTime.Date <= z.endActive)) - .ToList(), + .Where(y => !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && z.CheckoutStart.Date <= x.DateTime.Date && + z.CheckoutEnd.Date >= x.DateTime.Date) && activeEmployees.Any(z => z.EmployeeId == y.EmployeeId && x.DateTime.Date >= z.startActive && + x.DateTime.Date <= z.endActive)) + .ToList(), DayOfWeekFa = x.DateTime.DayOfWeek.DayOfWeeKToPersian() }).Where(y => y.RollCallWorkFlowPerDayViewModels != null && y.RollCallWorkFlowPerDayViewModels.Any()) - .OrderBy(x => x.DateTime).ToList(); - } + .OrderBy(x => x.DateTime).Count(); + } - /// - /// لیست غیبت ها - /// - public async Task> GetAbsentRollCallWorkFlows(long workshopId) + + /// + /// لیست غیبت ها + /// + public async Task CountAbsentRollCallLastMonth(long workshopId) + { + + DateTime lastMonthEnd = ($"{DateTime.Now.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime().AddDays(-1); + var now = lastMonthEnd; + var twoMonthsAgo = ($"{lastMonthEnd.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime(); + + + var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); + + var absences = _rollCallACL.GetAbsentRollCallWorkFlows(workshopId, twoMonthsAgo, now.AddDays(-1).Date); + var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); + + var confirmedAbssences = await GetConfirmAbsencesBy(workshopId, twoMonthsAgo, + now); + + + var groupedConfirmedAbssencesByDate = confirmedAbssences.GroupBy(x => x.AbsenceDate.Date).ToList(); + + List result = new(); + + //iterating day by day in absences + foreach (var item in absences) { - var now = DateTime.Now; - - DateTime.Now.Date.AddMonthsFa(-2, out var twoMonthsAgo); - - - var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); - - var absences = _rollCallACL.GetAbsentRollCallWorkFlows(workshopId, twoMonthsAgo, now.AddDays(-1).Date); - var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); - - var confirmedAbssences = await GetConfirmAbsencesBy(workshopId, twoMonthsAgo, - now); - - - var groupedConfirmedAbssencesByDate = confirmedAbssences.GroupBy(x => x.AbsenceDate.Date).ToList(); - - List result = new(); - - //iterating day by day in absences - foreach (var item in absences) + var allAbsencesInDate = item.RollCallWorkFlowPerDayViewModels; + var confirmedAbssencesInDate = groupedConfirmedAbssencesByDate.FirstOrDefault(x => x.Key == item.DateTime.Date); + //set the date of new item + var newItem = new DailyRollCallWorkFlowViewModel() { + DateTime = item.DateTime, + DateTimeFa = item.DateTime.ToFarsi() + }; - var allAbsencesInDate = item.RollCallWorkFlowPerDayViewModels; - var confirmedAbssencesInDate = groupedConfirmedAbssencesByDate.FirstOrDefault(x => x.Key == item.DateTime.Date); - //set the date of new item - var newItem = new DailyRollCallWorkFlowViewModel() - { - DateTime = item.DateTime, - DateTimeFa = item.DateTime.ToFarsi() - }; - - //dont count absences before the last checkout - allAbsencesInDate = allAbsencesInDate.Where(x => !lastCheckouts.Any(y => - x.EmployeeId == y.EmployeeId && y.CheckoutStart <= item.DateTime.Date && y.CheckoutEnd >= item.DateTime.Date) && activeEmployees.Any(y => - item.DateTime.Date >= y.startActive && item.DateTime.Date <= y.endActive)).ToList(); + //dont count absences before the last checkout + allAbsencesInDate = allAbsencesInDate.Where(x => !lastCheckouts.Any(y => + x.EmployeeId == y.EmployeeId && y.CheckoutStart <= item.DateTime.Date && y.CheckoutEnd >= item.DateTime.Date) && activeEmployees.Any(y => + item.DateTime.Date >= y.startActive && item.DateTime.Date <= y.endActive)).ToList(); - if (confirmedAbssencesInDate != null) - { - newItem.RollCallWorkFlowPerDayViewModels = allAbsencesInDate - .Where(x => confirmedAbssencesInDate.All(y => x.EmployeeId != y.EmployeeId)) - .ToList(); - } - else - { - newItem.RollCallWorkFlowPerDayViewModels = allAbsencesInDate.ToList(); - - } - - newItem.DayOfWeekFa = newItem.DateTime.DayOfWeek.DayOfWeeKToPersian(); - FilterWithOffset(workshopId,item.DateTime,ref newItem); - if (newItem.RollCallWorkFlowPerDayViewModels.Count > 0) - result.Add(newItem); + if (confirmedAbssencesInDate != null) + { + newItem.RollCallWorkFlowPerDayViewModels = allAbsencesInDate + .Where(x => confirmedAbssencesInDate.All(y => x.EmployeeId != y.EmployeeId)) + .ToList(); + } + else + { + newItem.RollCallWorkFlowPerDayViewModels = allAbsencesInDate.ToList(); } - return result.OrderByDescending(x => x.DateTime).ToList(); + + newItem.DayOfWeekFa = newItem.DateTime.DayOfWeek.DayOfWeeKToPersian(); + FilterWithOffset(workshopId, item.DateTime, ref newItem); + if (newItem.RollCallWorkFlowPerDayViewModels.Count > 0) + result.Add(newItem); + } - - /// - /// لیست بدون ثبت استرحت - /// - public async Task> GetEmployeesWithoutLunchBreak(long workshopId) - { - var now = DateTime.Now.Date; - - now.AddMonthsFa(-2, out var twoMonthsAgo); - - var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); - var notSlicedRollCalls = _rollCallACL.GetNotSlicedRollCallsByWorkshopId(workshopId, twoMonthsAgo, now.AddDays(-1).Date); - var employeesWithoutBreakTime = _customizedWorkshopSettingsACL.GetEmployeesWithoutBreakTime(workshopId); - - notSlicedRollCalls = notSlicedRollCalls - .Where(x => !lastCheckouts.Any(y => y.EmployeeId == x.EmployeeId && y.CheckoutStart.Date <= x.RollCallDate.Date && y.CheckoutEnd.Date >= x.RollCallDate.Date)).ToList(); - - var employeeWithoutBreakTimeAndNotSliced = notSlicedRollCalls - .Join(employeesWithoutBreakTime, x => x.EmployeeId, - y => y.EmployeeId, (x, y) => - new { y.EmployeeId, x.EmployeeName, x.RollCallId, x.RollCallDate }).ToList(); + return result.OrderByDescending(x => x.DateTime).Count(); + } - var entites = _rollCallConfirmedWithoutLunchBreakRepository.GetByWorkshopId(workshopId, twoMonthsAgo, now).ToList(); + public async Task CountEmployeesWithoutLunchBreakLastMonth(long workshopId) + { + DateTime lastMonthEnd = ($"{DateTime.Now.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime().AddDays(-1); + var now = lastMonthEnd; + var twoMonthsAgo = ($"{lastMonthEnd.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime(); - return employeeWithoutBreakTimeAndNotSliced.Where(x => !entites.Any(y => y.RollCallId == x.RollCallId)) - .GroupBy(x => x.RollCallDate.Date).OrderBy(x => x.Key).Select(x => new DailyRollCallConfirmedWithoutLunchBreakViewModel + var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); + var notSlicedRollCalls = _rollCallACL.GetNotSlicedRollCallsByWorkshopId(workshopId, twoMonthsAgo, now.AddDays(-1).Date); + var employeesWithoutBreakTime = _customizedWorkshopSettingsACL.GetEmployeesWithoutBreakTime(workshopId); + + notSlicedRollCalls = notSlicedRollCalls + .Where(x => !lastCheckouts.Any(y => y.EmployeeId == x.EmployeeId && y.CheckoutStart.Date <= x.RollCallDate.Date && y.CheckoutEnd.Date >= x.RollCallDate.Date)).ToList(); + + var employeeWithoutBreakTimeAndNotSliced = notSlicedRollCalls + .Join(employeesWithoutBreakTime, x => x.EmployeeId, + y => y.EmployeeId, (x, y) => + new { y.EmployeeId, x.EmployeeName, x.RollCallId, x.RollCallDate }).ToList(); + + + var entites = _rollCallConfirmedWithoutLunchBreakRepository.GetByWorkshopId(workshopId, twoMonthsAgo, now).ToList(); + + return employeeWithoutBreakTimeAndNotSliced.Where(x => !entites.Any(y => y.RollCallId == x.RollCallId)) + .GroupBy(x => x.RollCallDate.Date).OrderBy(x => x.Key).Select(x => new DailyRollCallConfirmedWithoutLunchBreakViewModel + { + DateGr = x.Key.Date, + DateFa = x.Key.Date.ToFarsi(), + DayOfWeekFa = x.Key.DayOfWeek.DayOfWeeKToPersian(), + RollCallConfirmedWithoutLunchList = x.Select(y => new RollCallConfirmedWithoutLunchBreakViewModel { - DateGr = x.Key.Date, - DateFa = x.Key.Date.ToFarsi(), - DayOfWeekFa = x.Key.DayOfWeek.DayOfWeeKToPersian(), - RollCallConfirmedWithoutLunchList = x.Select(y => new RollCallConfirmedWithoutLunchBreakViewModel - { - EmployeeId = y.EmployeeId, - EmployeeName = y.EmployeeName, - RollCallId = y.RollCallId, - }).ToList() - }).ToList(); + EmployeeId = y.EmployeeId, + EmployeeName = y.EmployeeName, + RollCallId = y.RollCallId, + }).ToList() + }).Count(); + + } + + + public async Task CountUndefinedLastMonth(long workshopId) + { + DateTime lastMonthEnd = ($"{DateTime.Now.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime().AddDays(-1); + var now = lastMonthEnd; + var twoMonthsAgo = ($"{lastMonthEnd.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime(); + + var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); + List rollCalls = _rollCallACL.GetUndefinedRollCalls(workshopId, twoMonthsAgo, now.AddDays(-1).Date); + var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); + return rollCalls.Select(x => new DailyRollCallWorkFlowViewModel() + { + DateTime = x.DateTime, + DateTimeFa = x.DateTimeFa, + RollCallWorkFlowPerDayViewModels = x.RollCallWorkFlowPerDayViewModels + .Where(y => + !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && z.CheckoutStart.Date <= x.DateTime.Date && + z.CheckoutEnd.Date >= x.DateTime.Date) && + activeEmployees.Any(z => z.EmployeeId == y.EmployeeId && x.DateTime.Date >= z.startActive && + x.DateTime.Date <= z.endActive)) + .ToList(), + DayOfWeekFa = x.DateTime.DayOfWeek.DayOfWeeKToPersian() + }).Where(y => y.RollCallWorkFlowPerDayViewModels != null && y.RollCallWorkFlowPerDayViewModels.Any()).OrderBy(x => x.DateTime).Count(); + } + #endregion + + + /// + /// لیست غیبت ها + /// + public async Task> GetAbsentRollCallWorkFlows(long workshopId) + { + + var now = DateTime.Now; + + DateTime.Now.Date.AddMonthsFa(-2, out var twoMonthsAgo); + + + var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); + + var absences = _rollCallACL.GetAbsentRollCallWorkFlows(workshopId, twoMonthsAgo, now.AddDays(-1).Date); + var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); + + var confirmedAbssences = await GetConfirmAbsencesBy(workshopId, twoMonthsAgo, + now); + + + var groupedConfirmedAbssencesByDate = confirmedAbssences.GroupBy(x => x.AbsenceDate.Date).ToList(); + + List result = new(); + + //iterating day by day in absences + foreach (var item in absences) + { + + var allAbsencesInDate = item.RollCallWorkFlowPerDayViewModels; + var confirmedAbssencesInDate = groupedConfirmedAbssencesByDate.FirstOrDefault(x => x.Key == item.DateTime.Date); + //set the date of new item + var newItem = new DailyRollCallWorkFlowViewModel() + { + DateTime = item.DateTime, + DateTimeFa = item.DateTime.ToFarsi() + }; + + //dont count absences before the last checkout + allAbsencesInDate = allAbsencesInDate.Where(x => !lastCheckouts.Any(y => + x.EmployeeId == y.EmployeeId && y.CheckoutStart <= item.DateTime.Date && y.CheckoutEnd >= item.DateTime.Date) && activeEmployees.Any(y => + item.DateTime.Date >= y.startActive && item.DateTime.Date <= y.endActive)).ToList(); + + + if (confirmedAbssencesInDate != null) + { + newItem.RollCallWorkFlowPerDayViewModels = allAbsencesInDate + .Where(x => confirmedAbssencesInDate.All(y => x.EmployeeId != y.EmployeeId)) + .ToList(); + } + else + { + newItem.RollCallWorkFlowPerDayViewModels = allAbsencesInDate.ToList(); + + } + + newItem.DayOfWeekFa = newItem.DateTime.DayOfWeek.DayOfWeeKToPersian(); + FilterWithOffset(workshopId, item.DateTime, ref newItem); + if (newItem.RollCallWorkFlowPerDayViewModels.Count > 0) + result.Add(newItem); } + return result.OrderByDescending(x => x.DateTime).ToList(); + } + + /// + /// لیست بدون ثبت استرحت + /// + public async Task> GetEmployeesWithoutLunchBreak(long workshopId) + { + var now = DateTime.Now.Date; + + now.AddMonthsFa(-2, out var twoMonthsAgo); + + var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); + var notSlicedRollCalls = _rollCallACL.GetNotSlicedRollCallsByWorkshopId(workshopId, twoMonthsAgo, now.AddDays(-1).Date); + var employeesWithoutBreakTime = _customizedWorkshopSettingsACL.GetEmployeesWithoutBreakTime(workshopId); + + notSlicedRollCalls = notSlicedRollCalls + .Where(x => !lastCheckouts.Any(y => y.EmployeeId == x.EmployeeId && y.CheckoutStart.Date <= x.RollCallDate.Date && y.CheckoutEnd.Date >= x.RollCallDate.Date)).ToList(); + + var employeeWithoutBreakTimeAndNotSliced = notSlicedRollCalls + .Join(employeesWithoutBreakTime, x => x.EmployeeId, + y => y.EmployeeId, (x, y) => + new { y.EmployeeId, x.EmployeeName, x.RollCallId, x.RollCallDate }).ToList(); + + + var entites = _rollCallConfirmedWithoutLunchBreakRepository.GetByWorkshopId(workshopId, twoMonthsAgo, now).ToList(); + + return employeeWithoutBreakTimeAndNotSliced.Where(x => !entites.Any(y => y.RollCallId == x.RollCallId)) + .GroupBy(x => x.RollCallDate.Date).OrderBy(x => x.Key).Select(x => new DailyRollCallConfirmedWithoutLunchBreakViewModel + { + DateGr = x.Key.Date, + DateFa = x.Key.Date.ToFarsi(), + DayOfWeekFa = x.Key.DayOfWeek.DayOfWeeKToPersian(), + RollCallConfirmedWithoutLunchList = x.Select(y => new RollCallConfirmedWithoutLunchBreakViewModel + { + EmployeeId = y.EmployeeId, + EmployeeName = y.EmployeeName, + RollCallId = y.RollCallId, + }).ToList() + }).ToList(); + + } #endregion