private async Task <bool> processDaysReports(IEnumerable <EmployeeInfoViewModel> employees, DateTime fromDate, DateTime toDate) { try { var employeesIds = employees.Select(e => e.EmployeeId).OrderBy(e => e).ToList(); //Get employees Calendars var allEmployeesCalendars = await _employeesCalendarManager.GetAllAsNoTrackingListAsync(ec => employeesIds.Contains(ec.EmployeeId) && ((ec.StartDate <= fromDate && ec.EndDate == null) || (ec.StartDate >= fromDate && ec.StartDate <= toDate) || (ec.StartDate <= fromDate && ec.EndDate >= fromDate))); //Get workCalendars var calendarsDaysReports = new Dictionary <ContractWorkTime, List <CalendarDayReport> >(); foreach (var workTime in (ContractWorkTime[])Enum.GetValues(typeof(ContractWorkTime))) { calendarsDaysReports.Add(workTime, await _workCalendarsManager.GetCalendarsDaysReport(workTime, fromDate, toDate)); } //Get employees vacations var allEmployeesVacations = await _erpManager.GetAllVacations(fromDate, toDate, employeesIds); //Get employees Open vacations requests var allEmployeesOpenVacationsRequests = await _erpManager.GetAllOpenVacations(fromDate, toDate, employeesIds); //Get employees open delegations requests var allEmployeesOpenDelegationsRequests = await _erpManager.GetAllOpenDelegations(fromDate, toDate, employeesIds); //Get employees transactions var allEmployeesTransactions = await _erpManager.GetAllTransaction(fromDate, toDate, employeesIds); //Get employees excuses var allEmployeesExcuses = await _employeesExcusesManager.GetAllAsNoTrackingListAsync(ex => employeesIds.Contains(ex.EmployeeId) && ex.ExcueseDate >= fromDate && ex.ExcueseDate <= toDate); var resultsDaysReports = new List <EmployeeDayReport>(); DateTime startDate = fromDate; while (startDate <= toDate) { var employeesCalendars = allEmployeesCalendars.Where(c => (c.StartDate <= startDate && c.EndDate == null) || (startDate >= c.StartDate && startDate <= c.EndDate)).ToList(); var excuses = allEmployeesExcuses.Where(x => x.ExcueseDate.Date == startDate); var vacations = allEmployeesVacations.Where(v => startDate >= v.StartDate && startDate <= v.EndDate).ToList(); var openDelegationsRequests = allEmployeesOpenDelegationsRequests.Where(d => startDate >= d.StartDate && startDate <= d.EndDate).ToList(); var openVacationsRequests = allEmployeesOpenVacationsRequests.Where(d => startDate >= d.StartDate && startDate <= d.EndDate).ToList(); var transactions = allEmployeesTransactions.Where(t => t.TransactionDate.Date >= startDate && t.TransactionDate.Date <= startDate.AddDays(1).Date).ToList(); foreach (var employee in employees) { var newDayReport = new EmployeeDayReport { EmployeeId = employee.EmployeeId, EmployeeName = employee.Name, DepartmentId = employee.DepartmentId, DepartmentName = employee.DepartmentName, DayDate = startDate.Date, ProcessingDate = DateTime.Now }; var defaultEmployeeCalendar = employeesCalendars.Where(c => c.EndDate == null && c.EmployeeId == employee.EmployeeId) .OrderByDescending(c => c.StartDate).FirstOrDefault() ?? new EmployeeCalendar { StartDate = startDate, AttendanceProof = AttendanceProof.RequiredInOut, EmployeeId = employee.EmployeeId, ContractWorkTime = ContractWorkTime.Default }; var limitedCalendar = employeesCalendars.Where(c => c.EndDate.HasValue && c.EmployeeId == employee.EmployeeId).FirstOrDefault(); var appliedCalendar = limitedCalendar ?? defaultEmployeeCalendar; newDayReport.AttendanceProof = appliedCalendar.AttendanceProof; var contractDayReport = calendarsDaysReports[appliedCalendar.ContractWorkTime]? .FirstOrDefault(d => d.DayDate.Date == startDate.Date); if (!contractDayReport.IsDayOff) { newDayReport.ContractCheckInDateTime = contractDayReport.CheckInDateTime; newDayReport.ContractCheckOutDateTime = contractDayReport.CheckOutDateTime; newDayReport.ContractWorkDurationTime = contractDayReport.WorkDuration; } else { newDayReport.IsVacation = true; newDayReport.VacationName = contractDayReport.DayOffDescription; } var employeeVacation = vacations.FirstOrDefault(v => v.EmployeeId == employee.EmployeeId); if (employeeVacation != null) { newDayReport.IsVacation = true; newDayReport.VacationName = employeeVacation.VacationTypeName; newDayReport.VacationRegisterDate = employeeVacation.RegisterDate; } var employeeOpenVacationRequest = openVacationsRequests .FirstOrDefault(vr => vr.EmployeeId == employee.EmployeeId); if (employeeOpenVacationRequest != null) { newDayReport.IsVacationRequest = true; newDayReport.VacationRequestDate = employeeOpenVacationRequest.RequestDate; } var employeeOpenDelegationRequest = openDelegationsRequests .FirstOrDefault(vr => vr.EmployeeId == employee.EmployeeId); if (employeeOpenDelegationRequest != null) { newDayReport.IsDelegationRequest = true; newDayReport.DelegationRequestDate = employeeOpenDelegationRequest.RequestDate; } DateTime?checkOutStartRange = null; if (newDayReport.ContractCheckInDateTime.HasValue && newDayReport.ContractCheckOutDateTime.HasValue) { var checkInStartRange = newDayReport.ContractCheckInDateTime.Value.Add(new TimeSpan(-2, 0, 0)); checkOutStartRange = newDayReport.ContractCheckInDateTime.Value.Add(new TimeSpan(0, 31, 0)); var checkOutEndRange = newDayReport.ContractCheckOutDateTime.Value.Add(new TimeSpan(5, 0, 0)); var employeeTransactions = transactions.Where(t => t.EmployeeId == employee.EmployeeId).OrderBy(o => o.TransactionDate).ToList(); if (employeeTransactions.Count > 0) { newDayReport.ActualCheckInDateTime = employeeTransactions .FirstOrDefault(t => t.TransactionDate >= checkInStartRange && t.TransactionDate <= newDayReport.ContractCheckOutDateTime.Value)?.TransactionDate; newDayReport.ActualCheckOutDateTime = employeeTransactions.LastOrDefault(t => t.TransactionDate >= checkOutStartRange.Value && t.TransactionDate <= checkOutEndRange)?.TransactionDate; if (newDayReport.ActualCheckInDateTime.HasValue && newDayReport.ActualCheckOutDateTime.HasValue) { newDayReport.ActualCheckOutDateTime = newDayReport.ActualCheckOutDateTime >= newDayReport.ActualCheckInDateTime.Value.AddMinutes(1) ? newDayReport.ActualCheckOutDateTime : default(DateTime?); var checkIn = newDayReport.ActualCheckInDateTime >= newDayReport.ContractCheckInDateTime ? newDayReport.ActualCheckInDateTime : newDayReport.ContractCheckInDateTime; var checkOut = newDayReport.ActualCheckOutDateTime.HasValue && newDayReport.ActualCheckOutDateTime > newDayReport.ContractCheckOutDateTime ? newDayReport.ContractCheckOutDateTime : newDayReport.ActualCheckOutDateTime; newDayReport.ActualWorkDurationTime = checkOut.HasValue ? checkOut.Value.Subtract(checkIn.Value) : default(TimeSpan?); newDayReport.ActualTotalDurationTime = newDayReport.ActualCheckOutDateTime.HasValue ? newDayReport.ActualCheckOutDateTime.Value .Subtract(newDayReport.ActualCheckInDateTime.Value) : default(TimeSpan?); } } } var employeeExcuses = excuses.Where(x => x.EmployeeId == employee.EmployeeId).ToList(); newDayReport.CheckInExcuse = employeeExcuses.Any(x => x.ExcuseType == ExcuseType.CheckIn); newDayReport.CheckOutExcuse = employeeExcuses.Any(x => x.ExcuseType == ExcuseType.CheckOut); newDayReport.CheckInExcuseHours = employeeExcuses.FirstOrDefault(x => x.ExcuseType == ExcuseType.CheckIn)?.ExcuseHours ?? 0; newDayReport.CheckOutExcuseHours = employeeExcuses.FirstOrDefault(x => x.ExcuseType == ExcuseType.CheckOut)?.ExcuseHours ?? 0; if (!newDayReport.IsVacation) { newDayReport.CheckInDateTime = newDayReport.ActualCheckInDateTime; newDayReport.CheckOutDateTime = newDayReport.ActualCheckOutDateTime; if (newDayReport.CheckInDateTime.HasValue && (newDayReport.CheckInDateTime.HasValue && checkOutStartRange.HasValue && newDayReport.CheckInDateTime.Value > checkOutStartRange.Value) && !newDayReport.CheckOutDateTime.HasValue && newDayReport.CheckInExcuse) { newDayReport.CheckOutDateTime = newDayReport.CheckInDateTime; } if (newDayReport.CheckInDateTime.HasValue && newDayReport.CheckInDateTime > newDayReport.ContractCheckInDateTime) { if (newDayReport.CheckInDateTime <= newDayReport.ContractCheckInDateTime.Value.Add(new TimeSpan(0, 31, 0)) || newDayReport.IsOpenCheckInExcuse) { newDayReport.CheckInDateTime = newDayReport.ContractCheckInDateTime; } else if (newDayReport.CheckInExcuse) { newDayReport.CheckInDateTime = newDayReport.CheckInDateTime.Value .Subtract(newDayReport.CheckInExcuseHours.ConvertToTime()); newDayReport.CheckInDateTime = newDayReport.CheckInDateTime < newDayReport.ContractCheckInDateTime ? newDayReport.ContractCheckInDateTime : newDayReport.CheckInDateTime; } } else if (!newDayReport.CheckInDateTime.HasValue && newDayReport.IsOpenCheckInExcuse) { newDayReport.CheckInDateTime = newDayReport.ContractCheckInDateTime; } if (newDayReport.CheckOutDateTime.HasValue && newDayReport.CheckOutDateTime.Value < newDayReport.ContractCheckOutDateTime) { newDayReport.CheckOutDateTime = newDayReport.IsOpenCheckOutExcuse ? newDayReport.ContractCheckOutDateTime : newDayReport.CheckOutDateTime; if (!newDayReport.IsOpenCheckOutExcuse) { newDayReport.CheckOutDateTime = newDayReport.CheckOutDateTime.Value .Add(newDayReport.CheckOutExcuseHours.ConvertToTime()); newDayReport.CheckOutDateTime = newDayReport.CheckOutDateTime > newDayReport.ContractCheckOutDateTime ? newDayReport.ContractCheckOutDateTime : newDayReport.CheckOutDateTime; } } else if (!newDayReport.CheckOutDateTime.HasValue && newDayReport.IsOpenCheckOutExcuse) { newDayReport.CheckOutDateTime = newDayReport.ContractCheckOutDateTime; } //Calculations newDayReport.IsAbsentEmployee = !newDayReport.IsVacation && !newDayReport.CheckInDateTime.HasValue && !newDayReport.CheckOutDateTime.HasValue && newDayReport.AttendanceProof != AttendanceProof.Exempted; if (newDayReport.CheckInDateTime.HasValue && newDayReport.CheckOutDateTime.HasValue && newDayReport.AttendanceProof == AttendanceProof.RequiredInOut) { var checkIn = newDayReport.CheckInDateTime >= newDayReport.ContractCheckInDateTime ? newDayReport.CheckInDateTime : newDayReport.ContractCheckInDateTime; var checkOut = newDayReport.CheckOutDateTime > newDayReport.ContractCheckOutDateTime ? newDayReport.ContractCheckOutDateTime : newDayReport.CheckOutDateTime; newDayReport.WorkDurationTime = checkOut.Value.Subtract(checkIn.Value); newDayReport.WorkTotalDurationTime = newDayReport.CheckOutDateTime.Value .Subtract(newDayReport.CheckInDateTime.Value); } if (newDayReport.AttendanceProof == AttendanceProof.RequiredInOut) { newDayReport.CheckInLateDurationTime = newDayReport.CheckInDateTime.HasValue && newDayReport.CheckInDateTime.Value > newDayReport.ContractCheckInDateTime ? newDayReport.CheckInDateTime.Value.Subtract(newDayReport.ContractCheckInDateTime.Value) : default(TimeSpan?); newDayReport.CheckOutEarlyDurationTime = newDayReport.CheckOutDateTime.HasValue && newDayReport.CheckOutDateTime.Value < newDayReport.ContractCheckOutDateTime ? newDayReport.ContractCheckOutDateTime.Value.Subtract(newDayReport.CheckOutDateTime.Value) : default(TimeSpan?); if (!newDayReport.IsAbsentEmployee) { newDayReport.WasteDurationTime = !newDayReport.WorkDurationTime.HasValue ? newDayReport.ContractWorkDurationTime : newDayReport.ContractWorkDurationTime.Value .Subtract(newDayReport.WorkDurationTime.Value); } } } resultsDaysReports.Add(newDayReport); } startDate = startDate.AddDays(1); } using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { try { await _employeesDaysReportsManager .DirectDeleteItems(d => (employeesIds.Count < 1 || employeesIds.Contains(d.EmployeeId)) && d.DayDate >= fromDate && d.DayDate <= toDate); try { var notificationsLogs = await _absentsNotificationsManager.GetAllAsNoTrackingListAsync(d => (employeesIds.Count < 1 || employeesIds.Contains(d.EmployeeId)) && d.AbsentDate >= fromDate && d.AbsentDate <= toDate); if (notificationsLogs.Count > 0) { foreach (var rdr in resultsDaysReports) { var notificationLog = notificationsLogs.FirstOrDefault(n => n.EmployeeId == rdr.EmployeeId && n.AbsentDate == rdr.DayDate); rdr.AbsentNotified = notificationLog != null; rdr.AbsentNotifiedByEmployeeId = notificationLog?.ByEmployeeId; rdr.AbsentNotifiedByEmployeeName = notificationLog?.ByEmployeeName; rdr.AbsentNotifiedDate = notificationLog?.SendDate; } } } catch (Exception) { } //foreach (var item in resultsDaysReports) //{ // try // { // await _employeesDaysReportsManager.InsertNewDataItem(item); // } // catch (Exception ex) // { // throw; // } //} await _employeesDaysReportsManager.InsertNewDataItems(resultsDaysReports); scope.Complete(); } catch (Exception ex) { scope.Dispose(); throw; } } return(true); } catch (Exception ex) { _logger.LogError(ex.Message); return(false); } }