using _0_Framework.Application; using _0_Framework.Domain.CustomizeCheckoutShared.Enums; using Company.Domain.RollCallAgg.DomainService; using CompanyManagment.App.Contracts.EmployeeDocuments; using WorkFlow.Application.Contracts.RollCallConfirmedAbsence; using WorkFlow.Application.Contracts.RollCallConfirmedWithoutLunchBreak; using WorkFlow.Application.Contracts.Shared; using WorkFlow.Application.Contracts.WorkFlow; using WorkFlow.Domain.RollCallConfirmedAbsenceAgg; using WorkFlow.Domain.RollCallConfirmedWithoutLunchBreakAgg; using WorkFlow.Infrastructure.ACL.Checkout; using WorkFlow.Infrastructure.ACL.CustomizedWorkshopSettings; using WorkFlow.Infrastructure.ACL.RollCall; namespace WorkFlow.Application; public class WorkFlowApplication : IWorkFlowApplication { private readonly IRollCallConfirmedAbsenceRepository _absenceRepository; private readonly IWorkFlowRollCallACL _rollCallACL; private readonly IWorkFlowCheckoutACL _checkoutACL; private readonly IWorkFlowCustomizedWorkshopSettingsACL _customizedWorkshopSettingsACL; private readonly IRollCallDomainService _rollCallDomainService; private readonly IRollCallConfirmedWithoutLunchBreakRepository _rollCallConfirmedWithoutLunchBreakRepository; private readonly IEmployeeDocumentsApplication _employeeDocumentsApplication; public WorkFlowApplication(IRollCallConfirmedAbsenceRepository absenceRepository, IWorkFlowRollCallACL rollCallACL, IWorkFlowCheckoutACL checkoutACL, IWorkFlowCustomizedWorkshopSettingsACL customizedWorkshopSettingsACL, IRollCallConfirmedWithoutLunchBreakRepository rollCallConfirmedWithoutLunchBreakRepository, IRollCallDomainService rollCallDomainService, IEmployeeDocumentsApplication employeeDocumentsApplication) { _absenceRepository = absenceRepository; _rollCallACL = rollCallACL; _checkoutACL = checkoutACL; _customizedWorkshopSettingsACL = customizedWorkshopSettingsACL; _rollCallConfirmedWithoutLunchBreakRepository = rollCallConfirmedWithoutLunchBreakRepository; _rollCallDomainService = rollCallDomainService; _employeeDocumentsApplication = employeeDocumentsApplication; } public async Task CreateRollCallConfirmedAbsence(CreateRollCallConfirmedAbsence command) { OperationResult op = new OperationResult(); if (!command.AbsenceDate.TryToGeorgianDateTime(out var absenceDateGe)) { throw new InvalidDataException("تاریخ را به درستی وارد کنید"); } var entity = new RollCallConfirmedAbsence(command.WorkshopId, command.EmployeeId, absenceDateGe, command.ConfirmedByAccountId); _absenceRepository.Create(entity); await _absenceRepository.SaveChangesAsync(); return op.Succcedded(); } public async Task CreateRollCallConfirmedWithoutLunchBreak(CreateRollCallConfirmedWithoutLunchBreak command) { OperationResult op = new(); var entity = _rollCallACL.GetDetails(command.RollCallId); if (entity == null) return op.Failed("خطای سیستمی"); var newEntity = new RollCallConfirmedWithoutLunchBreak(command.RollCallId, entity.EmployeeId, entity.WorkshopId, entity.RollCallDate); await _rollCallConfirmedWithoutLunchBreakRepository.CreateAsync(newEntity); await _rollCallConfirmedWithoutLunchBreakRepository.SaveChangesAsync(); return op.Succcedded(); } public async Task GetCountAllWorkFlows(long workshopId, long accountId) { int count = 0; count += await GetAllWorkFlowCount(workshopId, accountId); return count; } public Task GetRollCallAbsentsWorkFlows(long workshopId) { var now = DateTime.Now; DateTime.Now.Date.AddMonthsFa(-2, out var twoMonthsAgo); return Task.FromResult(_rollCallACL.GetRollCallAbsentsWorkFlowsCount(workshopId, now, twoMonthsAgo)); } public async Task GetCountCutRollCallByBgService(long workshopId) { return (await GetRollCallWorkFlowsCutByBgService(workshopId)).Count; } public async Task GetAllWorkFlowCount(long workshopId, long accountId) { var count = 0; // RollCall count += await GetAllRollCallCount(workshopId); count += await GetAllEmployeeDocuments(workshopId, accountId); // Employee Documents return count; } public async Task GetAllEmployeeDocuments(long workshopId, long accountId) { int count = 0; count += (await _employeeDocumentsApplication.GetClientRejectedDocumentForClient(workshopId, accountId)).Count; return count; } public Task GetAllWorkFlowCountAsync(long workshopId) { return Task.FromResult(20); } 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; } #region Methods For Ajax /// ///غیبت ها /// public async Task GetAbsentRollCallWorkFlowsByDate(long workshopId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1).Date.AddTicks(-1); startOfDay.AddMonthsFa(-2, out var twoMonthsAgo); var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, DateTime.Now); var absences = _rollCallACL.GetAbsentRollCallWorkFlows(workshopId, startOfDay, endOfDay); var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, startOfDay, endOfDay); var confirmedAbssences = await GetConfirmAbsencesBy(workshopId, startOfDay, endOfDay); //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 = absences.FirstOrDefault(); if (allAbsencesInDate == null) return await Task.FromResult(new DailyRollCallWorkFlowViewModel()); var newItem = new DailyRollCallWorkFlowViewModel() { DateTime = date.Date, DateTimeFa = date.ToFarsi(), }; //dont count absences before the last checkout var absencesWithoutCheckout = allAbsencesInDate.RollCallWorkFlowPerDayViewModels .Where(x => !lastCheckouts.Any(y => x.EmployeeId == y.EmployeeId && y.CheckoutStart <= date && y.CheckoutEnd >= date) && activeEmployees.Any(y => y.EmployeeId == x.EmployeeId)); if (confirmedAbssences != null) { newItem.RollCallWorkFlowPerDayViewModels = absencesWithoutCheckout .Where(x => confirmedAbssences.All(y => x.EmployeeId != y.EmployeeId)) .ToList(); } else { newItem.RollCallWorkFlowPerDayViewModels = absencesWithoutCheckout.ToList(); } FilterWithOffset(workshopId, date, ref newItem); newItem.DayOfWeekFa = newItem.DateTime.DayOfWeek.DayOfWeeKToPersian(); return newItem; } 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); } } } /// /// بدون ثبت استراحت /// public async Task GetEmployeesWithoutLunchBreakByDate(long workshopId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1).Date.AddTicks(-1); startOfDay.AddMonthsFa(-2, out var twoMonthsAgo); var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, DateTime.Now); var notSlicedRollCalls = _rollCallACL.GetNotSlicedRollCallsByWorkshopId(workshopId, startOfDay, endOfDay); var employeesWithoutBreakTime = _customizedWorkshopSettingsACL.GetEmployeesWithoutBreakTime(workshopId); var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, startOfDay, endOfDay); notSlicedRollCalls = notSlicedRollCalls .Where(x => !lastCheckouts.Any(y => y.EmployeeId == x.EmployeeId && y.CheckoutStart.Date <= x.RollCallDate.Date && y.CheckoutEnd.Date >= x.RollCallDate.Date) && activeEmployees.Any(y => y.EmployeeId == x.EmployeeId)).ToList(); var employeeWithoutBreakTimeAndNotSliced = notSlicedRollCalls .Join(employeesWithoutBreakTime, x => x.EmployeeId, y => y.EmployeeId, (x, y) => new { x.EmployeeId, x.EmployeeName, x.RollCallId, x.RollCallDate }).ToList(); var confirmed = _rollCallConfirmedWithoutLunchBreakRepository.GetByWorkshopId(workshopId, startOfDay, endOfDay).ToList(); return new DailyRollCallConfirmedWithoutLunchBreakViewModel() { DateFa = date.ToFarsi(), DateGr = date.Date, DayOfWeekFa = date.DayOfWeek.DayOfWeeKToPersian(), RollCallConfirmedWithoutLunchList = employeeWithoutBreakTimeAndNotSliced .Where(x => confirmed.All(y => y.RollCallId != x.RollCallId)).Select(y => new RollCallConfirmedWithoutLunchBreakViewModel { EmployeeId = y.EmployeeId, EmployeeName = y.EmployeeName, RollCallId = y.RollCallId }).ToList() }; } /// /// قطع شده توسط سیستم /// public async Task GetRollCallWorkFlowsCutByBgServiceByDate(long workshopId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1).Date.AddTicks(-1); startOfDay.AddMonthsFa(-2, out var twoMonthsAgo); var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, DateTime.Now.Date); var rollCalls = _rollCallACL.GetRollCallWorkFlowsCutByBgService(workshopId, startOfDay, endOfDay); var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, startOfDay, endOfDay); var rollCallsForDate = rollCalls.FirstOrDefault(); if (rollCallsForDate == null) return new(); var result = new DailyRollCallWorkFlowViewModel() { DateTime = date.Date, DateTimeFa = date.ToFarsi(), RollCallWorkFlowPerDayViewModels = rollCallsForDate.RollCallWorkFlowPerDayViewModels .Where(y => !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && z.CheckoutStart.Date <= rollCallsForDate.DateTime.Date && z.CheckoutEnd.Date >= rollCallsForDate.DateTime.Date) && activeEmployees.Any(z => y.EmployeeId == z.EmployeeId)) .ToList(), DayOfWeekFa = date.DayOfWeek.DayOfWeeKToPersian() }; return result; } /// /// تعیین وضعیت تردد پرسنل /// public async Task GetUndefinedRollCallsByDate(long workshopId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1).Date.AddTicks(-1); startOfDay.AddMonthsFa(-2, out var twoMonthsAgo); var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, DateTime.Now.Date); var rollCalls = _rollCallACL.GetUndefinedRollCalls(workshopId, startOfDay, endOfDay); var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, startOfDay, endOfDay); var rollCallsForDate = rollCalls.FirstOrDefault(); if (rollCallsForDate == null) return new(); var result = new DailyRollCallWorkFlowViewModel() { DateTime = date.Date, DateTimeFa = date.ToFarsi(), RollCallWorkFlowPerDayViewModels = rollCallsForDate.RollCallWorkFlowPerDayViewModels .Where(y => !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && z.CheckoutStart.Date <= rollCallsForDate.DateTime.Date && z.CheckoutEnd.Date >= rollCallsForDate.DateTime.Date) && activeEmployees.Any(z => y.EmployeeId == z.EmployeeId)) .ToList(), DayOfWeekFa = date.DayOfWeek.DayOfWeeKToPersian() }; return result; } /// /// تداخل مرخصی و حضور /// public async Task GetRollCallsOverlappingLeaveByDate(long workshopId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1).Date.AddTicks(-1); startOfDay.AddMonthsFa(-2, out var twoMonthsAgo); var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, DateTime.Now.Date); var rollCalls = _rollCallACL.GetRollCallsOverlappingLeaves(workshopId, startOfDay, endOfDay); var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, startOfDay, endOfDay); var rollCallsForDate = rollCalls.FirstOrDefault(x => x.Date == date); if (rollCallsForDate == null) return new(); var result = new DailyWorkFlowEmployeesWithRollCallOnLeaveViewModel() { Date = date.Date, DateFa = date.ToFarsi(), EmployeesList = rollCallsForDate.EmployeesList .Where(y => !lastCheckouts.Any(z => z.EmployeeId == y.EmployeeId && z.CheckoutStart.Date <= rollCallsForDate.Date.Date && z.CheckoutEnd.Date >= rollCallsForDate.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 = date.DayOfWeek.DayOfWeeKToPersian() }; return result; } #endregion public async Task> GetConfirmAbsencesBy(long workshopId, DateTime start, DateTime end) { return _absenceRepository.GetConfirmAbsencesBy(workshopId, start, end); } #region Methods For OnGet /// /// لیست تداخل مرخصی و حضور /// 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() { 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(), DayOfWeekFa = x.DateTime.DayOfWeek.DayOfWeeKToPersian() }).Where(y => y.RollCallWorkFlowPerDayViewModels != null && y.RollCallWorkFlowPerDayViewModels.Any()) .OrderBy(x => x.DateTime).ToList(); } #region CountForCreateCheckout 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).Count(); } /// /// لیست غیبت ها /// 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 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).Count(); } 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(); 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() }).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 public async Task> GetEmployeesWithoutGroup(long workshopId) { return _customizedWorkshopSettingsACL.GetEmployeesWithoutGroup(workshopId); } }