/// <summary> /// Tính số ngày phép năm tích lũy được đến thời điểm currentMonth. /// </summary> /// <param name="currentMonth">Tháng đang xét</param> /// <param name="gradeCfg"></param> /// <param name="dateHire">Ngày vào làm của nhân viên.</param> /// <param name="dateEndProbation">Ngày kết thúc thử việc</param> /// <param name="dateQuit">Ngày nghỉ làm của nhân viên</param> /// <param name="monthStartAnnualLeave">Tháng bắt đầu tính phép năm.</param> /// <param name="initAnnualValue">Phép năm có sẵn từ trước</param> /// <param name="lstLeaveDay">DS nghỉ phép theo loại trong cấu hình từ đầu năm tới giờ</param> /// <returns></returns> public static Double GetAnnualLeaveReceive(int Year, DateTime currentMonth, Cat_GradeAttendance gradeCfg, DateTime? dateHire, DateTime? dateEndProbation, DateTime? dateQuit, int? monthStartAnnualLeave, double? initAnnualValue, Cat_Position pos, Hre_ProfileMultiField profile , List<Att_LeaveDayInfo> lstLeaveDay, List<Sys_AllSetting> lstAllSetting, List<Hre_HDTJob> lstHDTJob_ByProfile, List<DateTime> lstDayOff, List<Att_LeaveDayInfo> lstLeaveDayAllYear,string userLogin) { double result = 0; int Month = currentMonth.Month; Cat_JobTitle CatJobTitle = new Cat_JobTitle(); if (profile.JobTitleID != null && profile.JobTitleID != Guid.Empty) { CatJobTitle = lstCatJobTitle.Where(s => s.ID == profile.JobTitleID).FirstOrDefault(); } if (gradeCfg == null) { return result; } if (string.IsNullOrWhiteSpace(gradeCfg.FormulaAnnualLeave)) { throw new Exception("Formula Annual Leave not found."); } //Lấy khoảng thời gian của kỳ lương DateTime dtStart, dtEnd; Att_AttendanceServices.GetSalaryDateRange(gradeCfg, null, null, currentMonth, out dtStart, out dtEnd); double totalDayAnnualLeaveOnYear = gradeCfg.TotalDayAnnualLeaveOnYear.Get_Integer(); double seniority = GetAnnualBySeniority(currentMonth, dateHire, gradeCfg); string formulaAnnualLeave = gradeCfg.FormulaAnnualLeave; Formula formula = new Formula(formulaAnnualLeave); //đâsdasd #region abc #region Param lstHDTJob_ByProfile = lstHDTJob_ByProfile.Where(m => m.DateFrom != null && m.Type != null).OrderBy(m => m.DateFrom).ToList(); ParamGetConfigANL paramConfig = new ParamGetConfigANL(); //set du lieu GetConfigANL(lstAllSetting, out paramConfig); int monthBeginYear = paramConfig.monthBeginYear; //Tháng bắt đầu tính phép năm int dayBeginFullMonth = paramConfig.dayBeginFullMonth; //Ngày bắt đầu tính tròn ANL cho tháng int seniorMonth = paramConfig.seniorMonth; // Số tháng để có 1 level cho thâm niên int dayPerMonth = paramConfig.dayPerMonth; // Số ngày cho 1 tháng double anlRoundUp = paramConfig.anlRoundUp; //Số làm tròn Lên xuống string typeProfileBegin = paramConfig.typeProfileBegin; //Loại lấy theo DateHire hay DateQuit int maxInMonthToGetAct = paramConfig.maxInMonthToGetAct; //Ngày chuẩn để xét là DT4 và DT5 đc tính cho tháng àno double anlFullYear = paramConfig.anlFullYear; // Số ngày phép bình thường cho 1 năm (tính theo tháng) double anlSeniorMoreThanNormal = paramConfig.anlSeniorMoreThanNormal; // Số ngày phép Được cộng thêm do thâm niên so với bình thường (tính theo tháng) double anlHDT4MoreThanNormal = paramConfig.anlHDT4MoreThanNormal; // Số ngày phép được cộng thêm do HDT4 so với bình thường (tính theo tháng) double anlHDT5MoreThanNormal = paramConfig.anlHDT5MoreThanNormal; // Số ngày phép được cộng thêm do HDT5 so với bình thường (tính theo tháng) List<string> lstCodeLeaveNonANL = paramConfig.lstCodeLeaveNonANL; int monthInYearSenior = paramConfig.monthInYearSenior; int monthRoundUp = paramConfig.monthRoundUp; #endregion #region Data //gan du lieu can thiet DateTime BeginYear = new DateTime(Year, monthBeginYear, 1); DateTime EndYear = BeginYear.AddYears(1).AddMinutes(-1); DateTime? DateCheckByMonth = null; if (Month != null) { DateCheckByMonth = new DateTime(Year, Month, 1); if (Month < monthBeginYear) { DateCheckByMonth = new DateTime(Year + 1, Month, 1); } } DateTime? DateStartProfile = null; DateTime DateEndProfile = EndYear; if (typeProfileBegin == AnlProfileTypeBegin.E_DATE_ENDPROBATION.ToString()) { DateStartProfile = dateEndProbation; } else { DateStartProfile = dateHire; } if (DateStartProfile == null) return 0; if (dateQuit != null && dateQuit < EndYear) { DateEndProfile = dateQuit.Value.Date.AddDays(1).AddMinutes(-1); } if (DateStartProfile.Value.Day > dayBeginFullMonth) { DateTime beginMonthOfDateTime = new DateTime(DateStartProfile.Value.Year, DateStartProfile.Value.Month, dayBeginFullMonth); bool IsAdd1Month = false; for (DateTime dateCheck = beginMonthOfDateTime; dateCheck < DateStartProfile.Value.Date; dateCheck = dateCheck.AddDays(1)) { if (!lstDayOff.Any(m => m == dateCheck)) { IsAdd1Month = true; break; } } if (IsAdd1Month) { DateStartProfile = new DateTime(DateStartProfile.Value.AddMonths(1).Year, DateStartProfile.Value.AddMonths(1).Month, 1); } else { DateStartProfile = new DateTime(DateStartProfile.Value.Year, DateStartProfile.Value.Month, dayBeginFullMonth); } } DateTime DateStartInYear = BeginYear > DateStartProfile.Value ? BeginYear : DateStartProfile.Value; DateTime DateEndInYear = EndYear < DateEndProfile ? EndYear : DateEndProfile; List<HDTJobTypeRange> lstHDTJobContaint = new List<HDTJobTypeRange>(); foreach (var item in lstHDTJob_ByProfile) { HDTJobTypeRange hdtJob = new HDTJobTypeRange(); hdtJob.Type = item.Type; hdtJob.DateStart = item.DateFrom.Value; hdtJob.DateEnd = item.DateTo; lstHDTJobContaint.Add(hdtJob); } lstHDTJobContaint = lstHDTJobContaint.OrderByDescending(m => m.DateStart).ToList(); DateTime DateBeFore = DateTime.MaxValue; foreach (var item in lstHDTJobContaint) { if (item.DateEnd == null) { item.DateEnd = DateBeFore; } DateBeFore = item.DateStart; } #endregion //ANL_WORK_HDT4, //ANL_WORK_HDT5, if (DateCheckByMonth == null) { #region ANL and Leave if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ANL_NORMAL.ToString())) { double value = 0; double monthWorkingNormalInYear = 0; for (int i = 0; i < 12; i++) { if (DateStartInYear.AddMonths(i) < DateEndInYear) { monthWorkingNormalInYear++; } else { break; } } value = anlFullYear * monthWorkingNormalInYear; formula.Parameters.Add(Formula.FormulaConstant.ANL_NORMAL.ToString(), value); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ANL_SENIOR.ToString())) { double value = 0; int MonBegin = monthInYearSenior == 0 ? 1 : monthInYearSenior; //--DateStartProfile DateTime Monthyear = new DateTime(Year, MonBegin, 1); double dateLeave = lstLeaveDayAllYear.Where(m => m.TotalDuration != null).Sum(m => m.TotalDuration.Value); dateLeave += (lstLeaveDayAllYear.Where(m => m.TotalDuration == null).Sum(m => m.Duration) / 8); DateTime dateRoundProfileStart = DateStartProfile.Value.AddMonths(-monthRoundUp); double Days = (Monthyear - dateRoundProfileStart).TotalDays - dateLeave; double YearSenior = Math.Round(Days / 365, MidpointRounding.AwayFromZero); int level = (int)(YearSenior / (seniorMonth / 12)); value = level * anlSeniorMoreThanNormal * 12; formula.Parameters.Add(Formula.FormulaConstant.ANL_SENIOR.ToString(), value); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ANL_LEAVE_NON_HAVEANL.ToString())) { double value = 0; //Logic: Vướng cai đầu năm cuối năm nên phải cắt cái ngày đó ra cho chính xác double numLeave = 0; foreach (var item in lstLeaveDay) { if (item.DateStart < DateStartInYear && item.DateEnd > DateStartInYear) { DateTime FirstSunday = DateTime.MinValue; for (DateTime DateCheck = DateStartInYear; DateCheck < item.DateEnd; DateCheck = DateCheck.AddDays(1)) { if (DateCheck.DayOfWeek == DayOfWeek.Sunday) { FirstSunday = DateCheck; break; } } int sundayCount = 0; if (FirstSunday != DateTime.MinValue) { sundayCount = (int)((item.DateEnd - FirstSunday).TotalDays / 7) + 1; } int dayOffCount = lstDayOff.Select(m => m.Date >= DateStartInYear && m.Date < item.DateEnd).Count(); numLeave += (item.DateEnd - DateStartInYear).TotalDays - sundayCount - dayOffCount; } else if (item.DateStart < DateEndInYear && item.DateEnd > DateEndInYear) { DateTime FirstSunday = DateTime.MinValue; for (DateTime DateCheck = item.DateStart; DateCheck < DateEndInYear; DateCheck = DateCheck.AddDays(1)) { if (DateCheck.DayOfWeek == DayOfWeek.Sunday) { FirstSunday = DateCheck; break; } } int sundayCount = 0; if (FirstSunday != DateTime.MinValue) { sundayCount = (int)((DateEndInYear - FirstSunday).TotalDays / 7) + 1; } int dayOffCount = lstDayOff.Select(m => m.Date >= item.DateStart && m.Date < DateEndInYear).Count(); numLeave += (item.DateEnd - DateStartInYear).TotalDays - sundayCount - dayOffCount; } else { numLeave += item.LeaveDays ?? 0; } } value = ((int)(numLeave / dayPerMonth)) + ((numLeave % dayPerMonth) >= anlRoundUp ? 1 : 0); formula.Parameters.Add(Formula.FormulaConstant.ANL_LEAVE_NON_HAVEANL.ToString(), value); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ANL_WORK_HDT4.ToString())) { double value = 0; double monthCount = 0; double dayCount = 0; //thuat: 1. lây cái mới nhất so với ngày bắt đầu năm //Lấy cái moi nhất nhỏ hơn ngày bắt đầu năm string Lv4 = HDTJobType.E_Four.ToString(); List<HDTJobTypeRange> lstHDTJobContaintLV4 = lstHDTJobContaint.Where(m => m.Type == Lv4).ToList(); //Lấy ra 3 khoảng //Đầu Năm HDTJobTypeRange lstHDTJobContaintLV4_BeginYear = lstHDTJobContaintLV4.Where(m => m.DateStart < DateStartInYear && m.DateEnd != null && m.DateEnd.Value > DateStartInYear).FirstOrDefault(); //Trong Năm List<HDTJobTypeRange> lstHDTJobContaintLV4_InYear = lstHDTJobContaintLV4.Where(m => m.DateStart >= DateStartInYear && m.DateEnd != null && m.DateEnd.Value <= DateEndInYear).ToList(); //Cuối Năm HDTJobTypeRange lstHDTJobContaintLV4_EndYear = lstHDTJobContaintLV4.Where(m => m.DateStart < DateEndInYear && m.DateEnd != null && m.DateEnd.Value > DateEndInYear).FirstOrDefault(); bool isFullYear = false; if (lstHDTJobContaintLV4_BeginYear != null && !isFullYear) { if (lstHDTJobContaintLV4_BeginYear.DateEnd.Value > DateEndInYear) { dayCount = (DateEndInYear - DateStartInYear).TotalDays; isFullYear = true; } else { dayCount += (lstHDTJobContaintLV4_BeginYear.DateEnd.Value - DateStartInYear).TotalDays; } } if (lstHDTJobContaintLV4_EndYear != null && !isFullYear) { if (lstHDTJobContaintLV4_EndYear.DateStart < DateStartInYear) { dayCount = (DateEndInYear - DateStartInYear).TotalDays; isFullYear = true; } else { dayCount += (DateEndInYear - lstHDTJobContaintLV4_EndYear.DateStart).TotalDays; } } if (!isFullYear) { foreach (var item in lstHDTJobContaintLV4_InYear) { dayCount += (item.DateEnd.Value - item.DateStart).TotalDays; } } monthCount = ((int)(dayCount / dayPerMonth)) + (((dayCount % dayPerMonth) / dayPerMonth) >= anlRoundUp ? 1 : 0); value = monthCount * anlHDT4MoreThanNormal; formula.Parameters.Add(Formula.FormulaConstant.ANL_WORK_HDT4.ToString(), value); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ANL_WORK_HDT5.ToString())) { double value = 0; double monthCount = 0; double dayCount = 0; //thuat: 1. lây cái mới nhất so với ngày bắt đầu năm //Lấy cái moi nhất nhỏ hơn ngày bắt đầu năm string Lv5 = HDTJobType.E_Five.ToString(); List<HDTJobTypeRange> lstHDTJobContaintLV5 = lstHDTJobContaint.Where(m => m.Type == Lv5).ToList(); //Lấy ra 3 khoảng //Đầu Năm HDTJobTypeRange lstHDTJobContaintLV5_BeginYear = lstHDTJobContaintLV5.Where(m => m.DateStart < DateStartInYear && m.DateEnd != null && m.DateEnd.Value > DateStartInYear).FirstOrDefault(); //Trong Năm List<HDTJobTypeRange> lstHDTJobContaintLV5_InYear = lstHDTJobContaintLV5.Where(m => m.DateStart >= DateStartInYear && m.DateEnd != null && m.DateEnd.Value <= DateEndInYear).ToList(); //Cuối Năm HDTJobTypeRange lstHDTJobContaintLV5_EndYear = lstHDTJobContaintLV5.Where(m => m.DateStart < DateEndInYear && m.DateEnd != null && m.DateEnd.Value > DateEndInYear).FirstOrDefault(); bool isFullYear = false; if (lstHDTJobContaintLV5_BeginYear != null && !isFullYear) { if (lstHDTJobContaintLV5_BeginYear.DateEnd.Value > DateEndInYear) { dayCount = (DateEndInYear - DateStartInYear).TotalDays; isFullYear = true; } else { dayCount += (lstHDTJobContaintLV5_BeginYear.DateEnd.Value - DateStartInYear).TotalDays; } } if (lstHDTJobContaintLV5_EndYear != null && !isFullYear) { if (lstHDTJobContaintLV5_EndYear.DateStart < DateStartInYear) { dayCount = (DateEndInYear - DateStartInYear).TotalDays; isFullYear = true; } else { dayCount += (DateEndInYear - lstHDTJobContaintLV5_EndYear.DateStart).TotalDays; } } if (!isFullYear) { foreach (var item in lstHDTJobContaintLV5_InYear) { dayCount += (item.DateEnd.Value - item.DateStart).TotalDays; } } monthCount = ((int)(dayCount / dayPerMonth)) + (((dayCount % dayPerMonth) / dayPerMonth) >= anlRoundUp ? 1 : 0); value = monthCount * anlHDT5MoreThanNormal; formula.Parameters.Add(Formula.FormulaConstant.ANL_WORK_HDT5.ToString(), value); } #endregion } else { #region BHXH if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ANL_NORMAL.ToString())) { double value = 0; if (DateStartInYear <= DateCheckByMonth) { value = anlFullYear; } formula.Parameters.Add(Formula.FormulaConstant.ANL_NORMAL.ToString(), value); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ANL_SENIOR.ToString())) { double value = 0; int level = 0; DateTime DateSenior = DateTime.MinValue; for (int i = 0; i < 20; i++) { DateSenior = DateStartProfile.Value.AddMonths(seniorMonth); if (DateSenior <= DateCheckByMonth) { level++; continue; } else { break; } } value = (level * anlSeniorMoreThanNormal); formula.Parameters.Add(Formula.FormulaConstant.ANL_SENIOR.ToString(), value); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ANL_WORK_HDT4.ToString())) { double value = 0; double monthCount = 0; double dayCount = 0; //thuat: 1. lây cái mới nhất so với ngày bắt đầu năm //Lấy cái moi nhất nhỏ hơn ngày bắt đầu năm string Lv4 = HDTJobType.E_Four.ToString(); DateTime DateStartMonth = DateCheckByMonth.Value; DateTime DateEndMonth = DateStartMonth.AddMonths(1).AddMinutes(-1); List<HDTJobTypeRange> lstHDTJobContaintLV4 = lstHDTJobContaint.Where(m => m.Type == Lv4).ToList(); //Lấy ra 3 khoảng //Đầu Năm HDTJobTypeRange lstHDTJobContaintLV4_BeginMonth = lstHDTJobContaintLV4.Where(m => m.DateStart < DateStartMonth && m.DateEnd != null && m.DateEnd.Value > DateStartMonth).FirstOrDefault(); //Trong Năm List<HDTJobTypeRange> lstHDTJobContaintLV4_InMonth = lstHDTJobContaintLV4.Where(m => m.DateStart >= DateStartMonth && m.DateEnd != null && m.DateEnd.Value <= DateEndMonth).ToList(); //Cuối Năm HDTJobTypeRange lstHDTJobContaintLV4_EndMonth = lstHDTJobContaintLV4.Where(m => m.DateStart < DateEndMonth && m.DateEnd != null && m.DateEnd.Value > DateEndMonth).FirstOrDefault(); bool isFullMonth = false; if (lstHDTJobContaintLV4_BeginMonth != null && !isFullMonth) { if (lstHDTJobContaintLV4_BeginMonth.DateEnd.Value > DateEndMonth) { dayCount = (DateEndMonth - DateStartMonth).TotalDays; isFullMonth = true; } else { dayCount += (lstHDTJobContaintLV4_BeginMonth.DateEnd.Value - DateStartMonth).TotalDays; } } if (lstHDTJobContaintLV4_EndMonth != null && !isFullMonth) { if (lstHDTJobContaintLV4_EndMonth.DateStart < DateStartMonth) { dayCount = (DateEndMonth - DateStartMonth).TotalDays; isFullMonth = true; } else { dayCount += (DateEndMonth - lstHDTJobContaintLV4_EndMonth.DateStart).TotalDays; } } if (!isFullMonth) { foreach (var item in lstHDTJobContaintLV4_InMonth) { dayCount += (item.DateEnd.Value - item.DateStart).TotalDays; } } monthCount = ((dayCount % dayPerMonth) >= anlRoundUp ? 1 : 0); value = monthCount * anlHDT4MoreThanNormal; formula.Parameters.Add(Formula.FormulaConstant.ANL_WORK_HDT4.ToString(), value); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ANL_WORK_HDT5.ToString())) { double value = 0; double monthCount = 0; double dayCount = 0; //thuat: 1. lây cái mới nhất so với ngày bắt đầu năm //Lấy cái moi nhất nhỏ hơn ngày bắt đầu năm string Lv5 = HDTJobType.E_Five.ToString(); DateTime DateStartMonth = DateCheckByMonth.Value; DateTime DateEndMonth = DateStartMonth.AddMonths(1).AddMinutes(-1); List<HDTJobTypeRange> lstHDTJobContaintLV5 = lstHDTJobContaint.Where(m => m.Type == Lv5).ToList(); //Lấy ra 3 khoảng //Đầu Năm HDTJobTypeRange lstHDTJobContaintLV5_BeginMonth = lstHDTJobContaintLV5.Where(m => m.DateStart < DateStartMonth && m.DateEnd != null && m.DateEnd.Value > DateStartMonth).FirstOrDefault(); //Trong Năm List<HDTJobTypeRange> lstHDTJobContaintLV5_InMonth = lstHDTJobContaintLV5.Where(m => m.DateStart >= DateStartMonth && m.DateEnd != null && m.DateEnd.Value <= DateEndMonth).ToList(); //Cuối Năm HDTJobTypeRange lstHDTJobContaintLV5_EndMonth = lstHDTJobContaintLV5.Where(m => m.DateStart < DateEndMonth && m.DateEnd != null && m.DateEnd.Value > DateEndMonth).FirstOrDefault(); bool isFullMonth = false; if (lstHDTJobContaintLV5_BeginMonth != null && !isFullMonth) { if (lstHDTJobContaintLV5_BeginMonth.DateEnd.Value > DateEndMonth) { dayCount = (DateEndMonth - DateStartMonth).TotalDays; isFullMonth = true; } else { dayCount += (lstHDTJobContaintLV5_BeginMonth.DateEnd.Value - DateStartMonth).TotalDays; } } if (lstHDTJobContaintLV5_EndMonth != null && !isFullMonth) { if (lstHDTJobContaintLV5_EndMonth.DateStart < DateStartMonth) { dayCount = (DateEndMonth - DateStartMonth).TotalDays; isFullMonth = true; } else { dayCount += (DateEndMonth - lstHDTJobContaintLV5_EndMonth.DateStart).TotalDays; } } if (!isFullMonth) { foreach (var item in lstHDTJobContaintLV5_InMonth) { dayCount += (item.DateEnd.Value - item.DateStart).TotalDays; } } monthCount = ((dayCount % dayPerMonth) >= anlRoundUp ? 1 : 0); value = monthCount * anlHDT5MoreThanNormal; formula.Parameters.Add(Formula.FormulaConstant.ANL_WORK_HDT5.ToString(), value); } #endregion } #endregion double AnnualDays = 0; if (profile != null && CatJobTitle != null) { AnnualDays = CatJobTitle.AnnualDays ?? 0; } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.INS_PROBATION.ToString())) { DateTime midDate = new DateTime(currentMonth.Year, currentMonth.Month, 15); bool isProbation = dateEndProbation.HasValue && dateEndProbation.Value > midDate; formula.Parameters.Add(Formula.FormulaConstant.INS_PROBATION.ToString(), isProbation.ToString()); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.TOTAL.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.TOTAL.ToString(), totalDayAnnualLeaveOnYear); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.CURRENTYEAR.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.CURRENTYEAR.ToString(), currentMonth.Year); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.TOTAL_LEAVE_BY_TYPE_IN_MONTH.ToString())) { if (ProfileCurrentID != profile.ID || dtEnd.Month == 1) { _Num_TOTAL_LEAVE_BY_TYPE_IN_MONTH = 0; ProfileCurrentID = profile.ID; } DateTime DateBeginMonth = dtStart; DateTime DateEndMonth = dtEnd; string E_FULLSHIFT = LeaveDayDurationType.E_FULLSHIFT.ToString(); List<string> lstCodeLeave = lstCodeLeaveNonAnl; double Sum = 0; if (lstCodeLeave.Count > 0) { Guid guidNewRelease = Guid.NewGuid(); string status = string.Empty; BaseService baseService = new BaseService(); List<object> lst3ParamFT = new List<object>(); lst3ParamFT.Add(null); lst3ParamFT.Add(DateBeginMonth); lst3ParamFT.Add(DateEndMonth); var dataAtt_LeaveDay = baseService.GetData<Att_LeaveDay>(lst3ParamFT, ConstantSql.hrm_att_getdata_LeaveDay_Inner, userLogin, ref status).ToList(); var lstLeaveTotalDuration = dataAtt_LeaveDay.Where(m => m.ProfileID == profile.ID //&& m.DateStart <= DateEndMonth //&& m.DateEnd >= DateBeginMonth && m.DurationType == E_FULLSHIFT && m.TotalDuration != null && m.Cat_LeaveDayType != null && lstCodeLeave.Contains(m.Cat_LeaveDayType.Code)) .Select(m => m.TotalDuration); foreach (var item in lstLeaveTotalDuration) { if (item != null) { Sum += item.Value; } } if (Sum > 13) _Num_TOTAL_LEAVE_BY_TYPE_IN_MONTH = _Num_TOTAL_LEAVE_BY_TYPE_IN_MONTH + 1; //EntityService.Instance.ReleaseContext(guidNewRelease); } formula.Parameters.Add(Formula.FormulaConstant.TOTAL_LEAVE_BY_TYPE_IN_MONTH.ToString(), _Num_TOTAL_LEAVE_BY_TYPE_IN_MONTH); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.MONTHHIRE.ToString())) { double monthHire = dateHire == null ? 1 : dateHire.Value.Month; formula.Parameters.Add(Formula.FormulaConstant.MONTHHIRE.ToString(), monthHire); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.YEARHIRE.ToString())) { int yearHire = dateHire != null ? dateHire.Value.Year : 0; formula.Parameters.Add(Formula.FormulaConstant.YEARHIRE.ToString(), yearHire); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.ADDITIONAL_ANNUAL.ToString())) { initAnnualValue = initAnnualValue.HasValue ? initAnnualValue.Value : 0; formula.Parameters.Add(Formula.FormulaConstant.ADDITIONAL_ANNUAL.ToString(), initAnnualValue.Value); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.MONTHENDPRO.ToString())) { #region Tháng kết thúc thử việc if (dateEndProbation.HasValue) { DateTime fromDate = currentMonth.Date.AddDays(1 - currentMonth.Day); DateTime toDate = fromDate.Date.AddMonths(1).AddSeconds(-1); GetDuration(gradeCfg, currentMonth, out fromDate, out toDate); int monthstart = dateEndProbation.Value.Month; if (currentMonth.Year > dateEndProbation.Value.Year) { monthstart = monthStartAnnualLeave == null ? 1 : monthStartAnnualLeave.Value; } else if (currentMonth.Year == dateEndProbation.Value.Year) { monthstart = dateEndProbation.Value.Month; if (dateEndProbation.Value.Day > 15) { monthstart++; } //Tháng đang xét nhỏ hơn tháng vào cty if (currentMonth.Month < monthstart) { return 0; } } else if (currentMonth.Year < dateEndProbation.Value.Year) { return 0; } formula.Parameters.Add(Formula.FormulaConstant.MONTHENDPRO.ToString(), monthstart); } #endregion } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.MONTHSTART_PROB.FormulaToString())) { #region Tháng bắt đầu thử việc DateTime dateTemp = DateTime.Now; if (dateEndProbation.HasValue) { dateTemp = dateEndProbation.Value; } else if (dateHire.HasValue) { dateTemp = dateHire.Value; } int monthstart = dateTemp.Month; if (currentMonth.Year > dateTemp.Year) { monthstart = monthStartAnnualLeave == null ? 1 : monthStartAnnualLeave.Value; } else if (currentMonth.Year == dateTemp.Year) { monthstart = dateTemp.Month; if (dateTemp.Day > 15) { monthstart++; } //Trường hợp tháng vào cty nhỏn hơn tháng bắt đầu tính phép năm if (monthStartAnnualLeave != null && monthstart < monthStartAnnualLeave.Value) { monthstart = monthStartAnnualLeave.Value; } //Tháng đang xét nhỏ hơn tháng vào cty if (currentMonth.Month < monthstart) { return 0; } } else if (currentMonth.Year < dateTemp.Year) { return 0; } formula.Parameters.Add(Formula.FormulaConstant.MONTHSTART_PROB.ToString(), monthstart); #endregion } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.MONTHSTART2.FormulaToString())) { #region MONTHSTART2 if (!dateHire.HasValue) { return 0; } double monthstart = dateHire.Value.Month; if (currentMonth.Year > dateHire.Value.Year) { monthstart = monthStartAnnualLeave == null ? 1 : monthStartAnnualLeave.Value; } else if (currentMonth.Year == dateHire.Value.Year) { DateTime monthHirePro = dateHire.Value; DateTime fromDate = currentMonth.Date.AddDays(1 - currentMonth.Day); DateTime toDate = fromDate.Date.AddMonths(1).AddSeconds(-1); Att_AttendanceServices.GetMonthSalary(gradeCfg, dateHire.Value, out monthHirePro); Att_AttendanceLib.GetDuration(gradeCfg, monthHirePro, out fromDate, out toDate); Double countDay = toDate.Date.Subtract(dateHire.Value.Date).TotalDays; if (countDay <= 20 && countDay >= 10) { monthstart += 0.5; } else if (countDay < 10) { monthstart += 1; } //cung nam nhung thang dang xet nho hon thang vao cty if (currentMonth.Month < dateHire.Value.Month) { return 0; } } else if (currentMonth.Year < dateHire.Value.Year) { return 0; } formula.Parameters.Add(Formula.FormulaConstant.MONTHSTART2.ToString(), monthstart); #endregion } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.MONTHSTART.FormulaToString())) { #region MONTHSTART if (dateHire != null) { int monthstart = dateHire.Value.Month; if (currentMonth.Year > dateHire.Value.Year) { monthstart = monthStartAnnualLeave == null ? 1 : monthStartAnnualLeave.Value; } else if (currentMonth.Year == dateHire.Value.Year) { monthstart = dateHire.Value.Month; if (dateHire.Value.Day > 15) { monthstart++; } //cung nam nhung thang dang xet nho hon thang vao cty if (currentMonth.Month < monthstart) { return 0; } } else if (currentMonth.Year < dateHire.Value.Year) { return 0; } formula.Parameters.Add(Formula.FormulaConstant.MONTHSTART.ToString(), monthstart); } #endregion } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.TERMINATION.ToString())) { #region TERMINATION bool isTermination = dateQuit.HasValue && dateQuit.Value.Year == currentMonth.Year && dateQuit.Value.Month == currentMonth.Month; formula.Parameters.Add(Formula.FormulaConstant.TERMINATION.ToString(), isTermination); #endregion } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.MONTHEND.ToString())) { #region MONTHEND int monthEnd = 0; if (dateQuit.HasValue && dateQuit.Value.Year == currentMonth.Year) { if (dateQuit.Value.Day > 15) { monthEnd = dateQuit.Value.Month; } else { monthEnd = dateQuit.Value.Month - 1; } } formula.Parameters.Add(Formula.FormulaConstant.MONTHEND.ToString(), monthEnd); #endregion } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.CURRENTMONTH.ToString())) { #region CURRENTMONTH int month = 0; month = currentMonth.Month; if (dateQuit.HasValue && dateQuit.Value.Year == currentMonth.Year && dateQuit.Value.Month == currentMonth.Month) { if (dateQuit.Value.Day > 15) { month = currentMonth.Month; } else { month = currentMonth.Month - 1; } } formula.Parameters.Add(Formula.FormulaConstant.CURRENTMONTH.ToString(), month); #endregion } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.SENIOR_BONUS_LEAVE.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.SENIOR_BONUS_LEAVE.ToString(), seniority); } if (formulaAnnualLeave.Contains(Formula.FormulaConstant.SENIOR_BONUS_LEAVE_FROM_.ToString())) { #region SENIOR_BONUS_LEAVE_FROM Double hourOnWorkDate = 8; if (gradeCfg.HourOnWorkDate.HasValue) { hourOnWorkDate = gradeCfg.HourOnWorkDate.Value; } int idx = formulaAnnualLeave.IndexOf(Formula.FormulaConstant.SENIOR_BONUS_LEAVE_FROM_.ToString()); while (idx != -1) { int idx2 = formulaAnnualLeave.IndexOf(@"]", idx) - 1; int lengh = Formula.FormulaConstant.SENIOR_BONUS_LEAVE_FROM_.ToString().Length; string monthYearString = formulaAnnualLeave.Substring(idx + lengh, idx2 - idx - lengh + 1); string year = monthYearString.Substring(4); string month = monthYearString.Substring(2, 2); string fullParamString = Formula.FormulaConstant.SENIOR_BONUS_LEAVE_FROM_.ToString() + monthYearString; if (!formula.Parameters.ContainsKey(fullParamString)) { DateTime monthYearEffect = new DateTime(int.Parse(year), int.Parse(month), 1); seniority = GetAnnualBySeniority(currentMonth, monthYearEffect, dateHire, gradeCfg); formula.Parameters.Add(fullParamString, seniority); } idx = formulaAnnualLeave.IndexOf(Formula.FormulaConstant.SENIOR_BONUS_LEAVE_FROM_.ToString(), idx2); } #endregion } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.MONTHENDPRO.ToString())) { #region MONTHENDPRO DateTime fromDate = new DateTime(currentMonth.Year, currentMonth.Month, 1); DateTime toDate = fromDate.AddMonths(1).AddMinutes(-1); Att_AttendanceServices.GetSalaryDateRange(gradeCfg, null, null, currentMonth, out fromDate, out toDate); int monthstart = 0; if (dateEndProbation != null) { monthstart = dateEndProbation.Value.Month; } if (dateEndProbation != null && currentMonth.Year > dateEndProbation.Value.Year) { monthstart = 1; monthstart = monthStartAnnualLeave ?? 1; } else if (dateEndProbation != null && currentMonth.Year == dateEndProbation.Value.Year) { if (dateEndProbation != null) { if (dateEndProbation.Value.Day > 15) monthstart = dateEndProbation.Value.Month; } monthstart++; // cung nam nhung thang dang xet nho hon thang vao cty if (currentMonth.Month < monthstart) return 0; } else if (dateEndProbation != null && currentMonth.Year < dateEndProbation.Value.Year) { return 0; } formula.Parameters.Add(Formula.FormulaConstant.MONTHENDPRO.ToString(), monthstart); #endregion } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.POSITION_CODE.ToString())) { string PositionCode = string.Empty; if (pos != null && pos.Code != null) { PositionCode = pos.Code; } formula.Parameters.Add(Formula.FormulaConstant.POSITION_CODE.ToString(), PositionCode); } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.CURRENTMONTH_INSALARY.ToString())) { int month = 0; month = currentMonth.Month; formula.Parameters.Add(Formula.FormulaConstant.CURRENTMONTH_INSALARY.ToString(), month); } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.IS_PROBATION.ToString())) { int flag = 0; if ((dateHire != null && dateHire >= dtStart && dateHire <= dtEnd) || (dateEndProbation != null && dateEndProbation >= dtStart && dateEndProbation <= dtEnd) || (dateHire != null && dateHire <= dtEnd && dateEndProbation != null && dateEndProbation >= dtStart)) { flag = 1; } formula.Parameters.Add(Formula.FormulaConstant.IS_PROBATION.ToString(), flag); } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.YEAR_OF_DATEHIRE.ToString())) { int year = 0; if (dateHire != null && dateHire >= dtStart && dateHire <= dtEnd) { year = dateHire.Value.Year; } formula.Parameters.Add(Formula.FormulaConstant.YEAR_OF_DATEHIRE.ToString(), year); } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.MONTH_OF_DATEHIRE.ToString())) { int month = 0; if (dateHire != null && dateHire >= dtStart && dateHire <= dtEnd) { month = dateHire.Value.Month; } formula.Parameters.Add(Formula.FormulaConstant.MONTH_OF_DATEHIRE.ToString(), month); } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.YEAR_OF_DATEENDPROBATION.ToString())) { int year = 0; if (dateEndProbation != null && dateEndProbation >= dtStart && dateEndProbation <= dtEnd) { year = dateEndProbation.Value.Year; } formula.Parameters.Add(Formula.FormulaConstant.YEAR_OF_DATEENDPROBATION.ToString(), year); } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.MONTH_OF_DATEENDPROBATION.ToString())) { int month = 0; if (dateEndProbation != null && dateEndProbation >= dtStart && dateEndProbation <= dtEnd) { month = dateEndProbation.Value.Month; } formula.Parameters.Add(Formula.FormulaConstant.MONTH_OF_DATEENDPROBATION.ToString(), month); } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.DAYOFDATEHIRE.ToString())) { int Day = 0; if (dateHire != null) Day = dateHire.Value.Day; formula.Parameters.Add(Formula.FormulaConstant.DAYOFDATEHIRE.ToString(), Day); } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.DAYOFDATEQUIT.ToString())) { int Day = 0; if (dateQuit != null) Day = dateQuit.Value.Day; formula.Parameters.Add(Formula.FormulaConstant.DAYOFDATEQUIT.ToString(), Day); } if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.JOBTITLE_ANNUAL.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.JOBTITLE_ANNUAL.ToString(), AnnualDays); } //Lấy tháng của DateHire, lấy kỳ lương theo tháng đó (tháng của DateHire), sau đó xuất ra Năm của kỳ lương đó. //vd: DateHire là 26/08/2014 ==>kỳ lương T8 là 25/07/2014-24/08/2014, ktra DateHire có thuộc kỳ T8 ko, nếu ko thì ktra trong kỳ lương T9. if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.YEAR_OF_SALARY_IF_DATEHIRE_BELONG.ToString())) { int year = 0; DateTime dateStart, dateEnd; if (dateHire != null) { DateTime dtmonthCheck = new DateTime(dateHire.Value.Year, dateHire.Value.Month, 1); //Lấy khoảng thời gian của kỳ lương Att_AttendanceServices.GetSalaryDateRange(gradeCfg, null, null, dtmonthCheck, out dateStart, out dateEnd); if (dateHire >= dateStart && dateHire <= dateEnd) { year = dateEnd.Year; } else { DateTime dateStartAdd = dateStart.AddMonths(1); DateTime dateEndAdd = dateEnd.AddMonths(1); if (dateHire >= dateStartAdd && dateHire <= dateEndAdd) { year = dateEndAdd.Year; } } } formula.Parameters.Add(Formula.FormulaConstant.YEAR_OF_SALARY_IF_DATEHIRE_BELONG.ToString(), year); } //Lấy tháng của DateHire, lấy kỳ lương theo tháng đó (tháng của DateHire), sau đó xuất ra Tháng của kỳ lương đó. if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.MONTH_OF_SALARY_IF_DATEHIRE_BELONG.ToString())) { int month = 0; DateTime dateStart, dateEnd; if (dateHire != null) { DateTime dtmonthCheck = new DateTime(dateHire.Value.Year, dateHire.Value.Month, 1); //Lấy khoảng thời gian của kỳ lương Att_AttendanceServices.GetSalaryDateRange(gradeCfg, null, null, dtmonthCheck, out dateStart, out dateEnd); if (dateHire >= dateStart && dateHire <= dateEnd) { month = dateEnd.Month; } else { DateTime dateStartAdd = dateStart.AddMonths(1); DateTime dateEndAdd = dateEnd.AddMonths(1); if (dateHire >= dateStartAdd && dateHire <= dateEndAdd) { month = dateEndAdd.Month; } } } formula.Parameters.Add(Formula.FormulaConstant.MONTH_OF_SALARY_IF_DATEHIRE_BELONG.ToString(), month); } //XuChi..Phần tử lấy số ngày thâm niên (theo đk của Danieli) if (gradeCfg.FormulaAnnualLeave.Contains(Formula.FormulaConstant.THAMNIEN_DANIELI.ToString())) { int thamnien = 0; DateTime dayRule = new DateTime(2014, 10, 4); //Ngày quy định fixed của Danieli DateTime currentDay = DateTime.Now.Date; //Ngày hiện tại lúc kiểm tra if (dateHire != null) { DateTime dayHire = dateHire.Value.Date; //Nếu ngày vào làm vào sau ngày quy định (logic: thâm niên 5 năm thì cộng 1) if (dayHire >= dayRule) { while (dayHire.AddYears(5) <= currentDay) { dayHire = dayHire.AddYears(5); thamnien++; } } else //Nếu ngày vào làm trước ngày quy định { //logic 1: thâm niêm 3 năm thì cộng 1 while (dayHire.AddYears(3) <= dayRule) { dayHire = dayHire.AddYears(3); thamnien++; } //logic 2: sau logic 1, sẽ có ngày dayHire gần với ngày dayRule nhất, //khi đó dayHire sẽ đc so sánh với currentDay, sau đó tính thâm niên 5 năm thì cộng 1 while (dayHire.AddYears(5) <= currentDay) { dayHire = dayHire.AddYears(5); thamnien++; } } } formula.Parameters.Add(Formula.FormulaConstant.THAMNIEN_DANIELI.ToString(), thamnien); } result = Convert.ToDouble(formula.Evaluate()); if ((result - (int)result) > 0) { double dental = result - (int)result; result = dental >= 0.5 ? (int)result + 1 : (int)result; } return result; return result; }
/// <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; } }