private List <Att_AnnualDetail> AnalyzeAnnualSickPerProfile(Hre_ProfileEntity Profile, List <Cat_GradeAttendance> lstGradeCfg, List <Att_Grade> lstGrade, DateTime BeginYear, DateTime EndYear, List <Att_LeaveDay> lstLeaveSick, List <Att_AnnualDetail> lstAnnualDetailInDB, Att_AnnualLeave AnnualLeave, List <Att_Roster> lstRosterInYear, List <Att_RosterGroup> lstRosterGroup, List <Hre_WorkHistory> lstWorkHistory, List <Cat_DayOff> lstDayOff, bool IsFrom1To31, List <Cat_Shift> shifts) { List <Att_AnnualDetail> lstResult = new List <Att_AnnualDetail>(); double leaveBeginYearToMonth = 0; double leaveBeginYearToMonth_Init = 0; string E_ROSTERGROUP = RosterType.E_ROSTERGROUP.ToString(); List <Att_Roster> lstRoster_byProfile = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type != E_ROSTERGROUP).ToList(); List <Att_Roster> lstRosterTypeGroup = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type == E_ROSTERGROUP).ToList(); for (DateTime Month = BeginYear; Month <= EndYear; Month = Month.AddMonths(1)) { var gradeByProfileByTime = lstGrade.Where(m => m.ProfileID == Profile.ID && m.MonthStart <= Month).OrderByDescending(m => m.MonthStart).FirstOrDefault(); if (gradeByProfileByTime == null) { continue; } var GradeCfg = lstGradeCfg.Where(m => m.ID == gradeByProfileByTime.GradeAttendanceID).FirstOrDefault(); if (GradeCfg == null) { continue; } DateTime BeginMonth = Month; DateTime EndMonth = BeginMonth.AddMonths(1).AddMinutes(-1); if (!IsFrom1To31) { Att_AttendanceServices.GetRangeMaxMinGrade(new List <Cat_GradeAttendance>() { GradeCfg }, Month, out BeginMonth, out EndMonth); } double Availale = AnnualLeave == null ? 0 : AnnualLeave.InitSickValue; double LeaveInMonth = 0; List <Att_LeaveDay> lstSickInMonth = lstLeaveSick.Where(m => m.ProfileID == Profile.ID && m.DateStart <= EndMonth && m.DateEnd >= BeginMonth).ToList(); var listRosterEntity = lstRoster_byProfile.Select(d => new Att_RosterEntity { ID = d.ID, ProfileID = d.ProfileID, RosterGroupName = d.RosterGroupName, Type = d.Type, Status = d.Status, DateEnd = d.DateEnd, DateStart = d.DateStart, MonShiftID = d.MonShiftID, TueShiftID = d.TueShiftID, WedShiftID = d.WedShiftID, ThuShiftID = d.ThuShiftID, FriShiftID = d.FriShiftID, SatShiftID = d.SatShiftID, SunShiftID = d.SunShiftID, MonShift2ID = d.MonShiftID, TueShift2ID = d.TueShift2ID, WedShift2ID = d.WedShift2ID, ThuShift2ID = d.ThuShift2ID, FriShift2ID = d.FriShift2ID, SatShift2ID = d.SatShift2ID, SunShift2ID = d.SunShift2ID }).ToList(); var listRosterGroupEntity = lstRosterGroup.Select(d => new Att_RosterGroupEntity { ID = d.ID, DateEnd = d.DateEnd, DateStart = d.DateStart, MonShiftID = d.MonShiftID, TueShiftID = d.TueShiftID, WedShiftID = d.WedShiftID, ThuShiftID = d.ThuShiftID, FriShiftID = d.FriShiftID, SatShiftID = d.SatShiftID, SunShiftID = d.SunShiftID, RosterGroupName = d.RosterGroupName }).ToList(); foreach (var item in lstSickInMonth) { if (item.DateStart >= BeginMonth && item.DateEnd <= EndMonth) { //Chi cần lấy TotalDuration hoặc lấy giờ rồi lấy ca if (item.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString()) { LeaveInMonth += item.TotalDuration ?? 0; } else { //Lấy ra ca làm việc DateTime DateBeginLeave = item.DateStart.Date; DateTime DateEndLeave = item.DateEnd.Date; Dictionary <DateTime, Cat_Shift> dicShift = Att_AttendanceLib.GetDailyShifts(Profile != null ? Profile.ID : Guid.Empty, DateBeginLeave, DateEndLeave, listRosterEntity, listRosterGroupEntity, shifts); if (dicShift != null && dicShift.ContainsKey(DateBeginLeave)) { Cat_Shift shift = dicShift[DateBeginLeave]; if (shift != null) { double HourWorkday = 8; if (shift.WorkHours != null && shift.WorkHours != 0) { HourWorkday = shift.WorkHours ?? 8; } LeaveInMonth += item.Duration / HourWorkday; } } } } else { DateTime DateBegin = BeginMonth > item.DateStart ? BeginMonth : item.DateStart; DateTime DateEnd = EndMonth < item.DateEnd ? BeginMonth : item.DateEnd; Dictionary <DateTime, Cat_Shift> dicShift = Att_AttendanceLib.GetDailyShifts(Profile != null ? Profile.ID : Guid.Empty, DateBegin, DateEnd, listRosterEntity, listRosterGroupEntity, shifts); for (DateTime dateCheck = DateBegin; dateCheck <= DateEnd; dateCheck = dateCheck.AddDays(1)) { if (Att_WorkDayHelper.IsWorkDay(dateCheck, GradeCfg, dicShift, lstDayOff) && !lstDayOff.Any(m => m.DateOff == dateCheck)) { LeaveInMonth++; } } } } Att_AnnualDetail AnnualDetail = lstAnnualDetailInDB.Where(m => m.ProfileID == Profile.ID && m.MonthYear == Month).FirstOrDefault(); if (AnnualDetail == null) { AnnualDetail = new Att_AnnualDetail(); } if (Profile.DateQuit != null) { DateTime MonthQuit = Profile.DateQuit.Value.Day >= 15 ? Profile.DateQuit.Value.AddMonths(1) : Profile.DateQuit.Value; MonthQuit = new DateTime(MonthQuit.Year, MonthQuit.Month, 1); if (Month >= MonthQuit) { AnnualDetail.IsDelete = true; } } AnnualDetail.Available = Availale; AnnualDetail.InitAvailable = AnnualLeave == null ? 0 : AnnualLeave.InitSickValue; AnnualDetail.ProfileID = Profile.ID; AnnualDetail.Year = BeginYear.Year; AnnualDetail.MonthYear = Month; AnnualDetail.MonthBeginInYear = MonthStartAnl; //todo: Phần tử này để trong cấu hình chung if (AnnualLeave != null && AnnualLeave.MonthResetAnlOfBeforeYear != null) { AnnualDetail.MonthResetInitAvailable = AnnualLeave.MonthResetAnlOfBeforeYear.Value;//todo: MonthReset Này để trong chế độ lương } else { AnnualDetail.MonthResetInitAvailable = 12;//todo: MonthReset Này để trong chế độ lương } AnnualDetail.MonthStartProfile = AnnualLeave == null ? 1 : AnnualLeave.MonthStart; if (AnnualDetail.MonthResetInitAvailable != null && AnnualDetail.MonthResetInitAvailable != 12 && AnnualDetail.Year != null) { DateTime MonthReset = new DateTime(AnnualDetail.Year.Value, AnnualDetail.MonthResetInitAvailable.Value, 1); AnnualDetail.IsHaveResetInitAvailable = true; if (Month <= MonthReset) //Trong những tháng có { double delta = leaveBeginYearToMonth_Init + LeaveInMonth - AnnualDetail.InitAvailable.Value; if (delta > 0) { AnnualDetail.TotalLeaveBefFromInitAvailable = leaveBeginYearToMonth_Init; AnnualDetail.LeaveInMonthFromInitAvailable = LeaveInMonth - delta; AnnualDetail.LeaveInMonth = delta; AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth; leaveBeginYearToMonth += delta; leaveBeginYearToMonth_Init += LeaveInMonth - delta; } else { AnnualDetail.TotalLeaveBefFromInitAvailable = leaveBeginYearToMonth_Init; AnnualDetail.LeaveInMonthFromInitAvailable = LeaveInMonth; AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth; AnnualDetail.LeaveInMonth = 0; leaveBeginYearToMonth_Init += LeaveInMonth; } } else //sau những tháng kho có { AnnualDetail.InitAvailable = 0; AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth; AnnualDetail.LeaveInMonth = LeaveInMonth; leaveBeginYearToMonth += LeaveInMonth; } } else //Bình thường { AnnualDetail.IsHaveResetInitAvailable = false; AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth; AnnualDetail.LeaveInMonth = LeaveInMonth; leaveBeginYearToMonth += LeaveInMonth; } double remain = (AnnualDetail.Available ?? 0) + (AnnualDetail.InitAvailable ?? 0) - (AnnualDetail.TotalLeaveBefFromInitAvailable ?? 0) - (AnnualDetail.LeaveInMonthFromInitAvailable ?? 0) - (AnnualDetail.TotalLeaveBef ?? 0) - (AnnualDetail.LeaveInMonth ?? 0); AnnualDetail.Remain = remain; AnnualDetail.Type = AnnualLeaveDetailType.E_SICK_LEAVE.ToString(); lstResult.Add(AnnualDetail); } return(lstResult); }
/// <summary> /// Hàm tính toán Phép năm dành cho từng nhân viên /// </summary> /// <param name="Profile">Nhân Viên</param> /// <param name="lstGradeCfg">Ds Chế Độ lương</param> /// <param name="lstGrade">Ds Grade của Nhân viên</param> /// <param name="BeginYear">Ngày bắt đầu của năm</param> /// <param name="EndYear">Ngày Kết Thúc Của Năm</param> /// <param name="lstLeaveAnl">Ds nghỉ phép năm</param> /// <param name="lstAnnualDetailInDB">Ds AnnualDetail trong DB</param> /// <param name="AnnualLeave">AnnualLeave</param> /// <param name="lstRosterInYear">Ds Roster</param> /// <param name="lstRosterGroup">Ds RosterGroup</param> /// <param name="lstWorkHistory">Ds WorkingHistory</param> /// <param name="lstDayOff">Ds Ngày Nghỉ Lễ </param> /// <returns></returns> private List <Att_AnnualDetail> AnalyzeAnnualDetailPerProfile(Hre_ProfileMultiField Profile, List <Cat_GradeAttendance> lstGradeCfg, List <Att_Grade> lstGrade, DateTime BeginYear, DateTime EndYear, List <Att_LeaveDayInfo> lstLeaveAnl, List <Att_AnnualDetail> lstAnnualDetailInDB, Att_AnnualLeave AnnualLeave, List <Att_RosterInfo> lstRosterInYearIn, List <Att_RosterGroup> lstRosterGroup, List <Cat_DayOff> lstDayOff, bool IsFrom1To31, Cat_Position Position, List <Sys_AllSetting> lstAllSetting, List <Hre_HDTJob> lstHDTJob, out List <Att_AnnualDetail> AnalyzeAnnualDetailPerProfile_Update, string userLogin) { AnalyzeAnnualDetailPerProfile_Update = new List <Att_AnnualDetail>(); using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)(new UnitOfWork(context)); var repoAtt_Roster = new CustomBaseRepository <Att_Roster>(unitOfWork); var repoCat_Shift = new Cat_ShiftRepository(unitOfWork); var shifts = repoCat_Shift.FindBy(s => s.IsDelete == null).ToList(); var lstRosterID = lstRosterInYearIn.Select(s => s.ID).ToList(); var lstRosterInYear = repoAtt_Roster.FindBy(s => lstRosterID.Contains(s.ID)).ToList(); List <Att_AnnualDetail> lstResult = new List <Att_AnnualDetail>(); double leaveBeginYearToMonth = 0; double leaveBeginYearToMonth_Init = 0; string E_ROSTERGROUP = RosterType.E_ROSTERGROUP.ToString(); List <Att_Roster> lstRoster_byProfile = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type != E_ROSTERGROUP).ToList(); List <Att_Roster> lstRosterTypeGroup = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type == E_ROSTERGROUP).ToList(); for (DateTime Month = BeginYear; Month <= EndYear; Month = Month.AddMonths(1)) { var gradeByProfileByTime = lstGrade.Where(m => m.ProfileID == Profile.ID && m.MonthStart <= Month).OrderByDescending(m => m.MonthStart).FirstOrDefault(); if (gradeByProfileByTime == null) { continue; } var GradeCfg = lstGradeCfg.Where(m => m.ID == gradeByProfileByTime.GradeAttendanceID).FirstOrDefault(); if (GradeCfg == null) { continue; } DateTime BeginMonth = Month; DateTime EndMonth = BeginMonth.AddMonths(1).AddMinutes(-1); if (!IsFrom1To31) { Att_AttendanceServices.GetRangeMaxMinGrade(new List <Cat_GradeAttendance>() { GradeCfg }, Month, out BeginMonth, out EndMonth); } int AnnualLeaveMonthStart = AnnualLeave != null ? AnnualLeave.MonthStart : 1; double AnnualLeaveInitAnlValue = AnnualLeave != null ? AnnualLeave.InitAnlValue : 0; double Availale = Att_AttendanceLib.GetAnnualLeaveReceive(BeginYear.Year, Month, GradeCfg, Profile.DateHire, Profile.DateEndProbation, Profile.DateQuit, AnnualLeaveMonthStart, AnnualLeaveInitAnlValue, Position, Profile, lstLeaveAnl, lstAllSetting, lstHDTJob, lstDayOff.Select(m => m.DateOff).ToList(), lstLeaveAnl, userLogin); double LeaveInMonth = 0; List <Att_LeaveDayInfo> lstAnlInMonth = lstLeaveAnl.Where(m => m.ProfileID == Profile.ID && m.DateStart <= EndMonth && m.DateEnd >= BeginMonth).ToList(); foreach (var item in lstAnlInMonth) { var listRosterEntity = lstRoster_byProfile.Select(d => new Att_RosterEntity { ID = d.ID, ProfileID = d.ProfileID, RosterGroupName = d.RosterGroupName, Type = d.Type, Status = d.Status, DateEnd = d.DateEnd, DateStart = d.DateStart, MonShiftID = d.MonShiftID, TueShiftID = d.TueShiftID, WedShiftID = d.WedShiftID, ThuShiftID = d.ThuShiftID, FriShiftID = d.FriShiftID, SatShiftID = d.SatShiftID, SunShiftID = d.SunShiftID, MonShift2ID = d.MonShiftID, TueShift2ID = d.TueShift2ID, WedShift2ID = d.WedShift2ID, ThuShift2ID = d.ThuShift2ID, FriShift2ID = d.FriShift2ID, SatShift2ID = d.SatShift2ID, SunShift2ID = d.SunShift2ID }).ToList(); var listRosterGroupEntity = lstRosterGroup.Select(d => new Att_RosterGroupEntity { ID = d.ID, DateEnd = d.DateEnd, DateStart = d.DateStart, MonShiftID = d.MonShiftID, TueShiftID = d.TueShiftID, WedShiftID = d.WedShiftID, ThuShiftID = d.ThuShiftID, FriShiftID = d.FriShiftID, SatShiftID = d.SatShiftID, SunShiftID = d.SunShiftID, RosterGroupName = d.RosterGroupName }).ToList(); if (item.DateStart >= BeginMonth && item.DateEnd <= EndMonth) { //Chi cần lấy TotalDuration hoặc lấy giờ rồi lấy ca if (item.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString()) { LeaveInMonth += item.LeaveDays ?? 0; } else { //Lấy ra ca làm việc DateTime DateBeginLeave = item.DateStart.Date; DateTime DateEndLeave = item.DateEnd.Date; Dictionary <DateTime, Cat_Shift> dicShift = Att_AttendanceLib.GetDailyShifts(Profile != null ? Profile.ID : Guid.Empty, DateBeginLeave, DateEndLeave, listRosterEntity, listRosterGroupEntity, shifts); if (dicShift != null && dicShift.ContainsKey(DateBeginLeave)) { Cat_Shift shift = dicShift[DateBeginLeave]; if (shift != null) { double HourWorkday = shift.udStandardWorkHours > 0 ? shift.udStandardWorkHours : 8.0; LeaveInMonth += item.LeaveHours.Value / HourWorkday; } } } } else { DateTime DateBegin = BeginMonth > item.DateStart ? BeginMonth : item.DateStart; DateTime DateEnd = EndMonth < item.DateEnd ? BeginMonth : item.DateEnd; Dictionary <DateTime, Cat_Shift> dicShift = Att_AttendanceLib.GetDailyShifts(Profile != null ? Profile.ID : Guid.Empty, DateBegin, DateEnd, listRosterEntity, listRosterGroupEntity, shifts); for (DateTime dateCheck = DateBegin; dateCheck <= DateEnd; dateCheck = dateCheck.AddDays(1)) { if (Att_WorkDayHelper.IsWorkDay(dateCheck, GradeCfg, dicShift, lstDayOff) && !lstDayOff.Any(m => m.DateOff == dateCheck)) { LeaveInMonth++; } } } } Att_AnnualDetail AnnualDetail = lstAnnualDetailInDB.Where(m => m.ProfileID == Profile.ID && m.MonthYear == Month).FirstOrDefault(); bool isNew = false; if (AnnualDetail == null) { isNew = true; AnnualDetail = new Att_AnnualDetail(); } else { AnalyzeAnnualDetailPerProfile_Update.Add(AnnualDetail); } if (Profile.DateQuit != null) { DateTime MonthQuit = Profile.DateQuit.Value.Day >= 15 ? Profile.DateQuit.Value.AddMonths(1) : Profile.DateQuit.Value; MonthQuit = new DateTime(MonthQuit.Year, MonthQuit.Month, 1); if (Month >= MonthQuit) { AnnualDetail.IsDelete = true; } } AnnualDetail.Available = Availale; AnnualDetail.InitAvailable = AnnualLeave == null ? 0 : AnnualLeave.InitAnlValue; AnnualDetail.ProfileID = Profile.ID; //AnnualDetail.Hre_Profile = Profile.CopyData<Hre_Profile>(); AnnualDetail.Year = BeginYear.Year; AnnualDetail.MonthYear = Month; AnnualDetail.MonthBeginInYear = MonthStartAnl; //todo: Phần tử này để trong cấu hình chung if (AnnualLeave != null && AnnualLeave.MonthResetAnlOfBeforeYear != null) { AnnualDetail.MonthResetInitAvailable = AnnualLeave.MonthResetAnlOfBeforeYear.Value;//todo: MonthReset Này để trong chế độ lương } else { AnnualDetail.MonthResetInitAvailable = 12;//todo: MonthReset Này để trong chế độ lương } AnnualDetail.MonthStartProfile = AnnualLeave == null ? 1 : AnnualLeave.MonthStart; if (AnnualDetail.MonthResetInitAvailable != null && AnnualDetail.MonthResetInitAvailable != 12 && AnnualDetail.Year != null) { DateTime MonthReset = new DateTime(AnnualDetail.Year.Value, AnnualDetail.MonthResetInitAvailable.Value, 1); AnnualDetail.IsHaveResetInitAvailable = true; if (Month <= MonthReset) //Trong những tháng có { double delta = leaveBeginYearToMonth_Init + LeaveInMonth - AnnualDetail.InitAvailable.Value; if (delta > 0) { AnnualDetail.TotalLeaveBefFromInitAvailable = leaveBeginYearToMonth_Init; AnnualDetail.LeaveInMonthFromInitAvailable = LeaveInMonth - delta; AnnualDetail.LeaveInMonth = delta; AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth; leaveBeginYearToMonth += delta; leaveBeginYearToMonth_Init += LeaveInMonth - delta; } else { AnnualDetail.TotalLeaveBefFromInitAvailable = leaveBeginYearToMonth_Init; AnnualDetail.LeaveInMonthFromInitAvailable = LeaveInMonth; AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth; AnnualDetail.LeaveInMonth = 0; leaveBeginYearToMonth_Init += LeaveInMonth; } } else //sau những tháng kho có { AnnualDetail.InitAvailable = 0; AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth; AnnualDetail.LeaveInMonth = LeaveInMonth; leaveBeginYearToMonth += LeaveInMonth; } } else //Bình thường { AnnualDetail.IsHaveResetInitAvailable = false; AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth; AnnualDetail.LeaveInMonth = LeaveInMonth; leaveBeginYearToMonth += LeaveInMonth; } double remain = (AnnualDetail.Available ?? 0) + (AnnualDetail.InitAvailable ?? 0) - (AnnualDetail.TotalLeaveBefFromInitAvailable ?? 0) - (AnnualDetail.LeaveInMonthFromInitAvailable ?? 0) - (AnnualDetail.TotalLeaveBef ?? 0) - (AnnualDetail.LeaveInMonth ?? 0); AnnualDetail.Remain = remain; AnnualDetail.Type = AnnualLeaveDetailType.E_ANNUAL_LEAVE.ToString(); if (isNew) { lstResult.Add(AnnualDetail); } } return(lstResult); } }